Kubernetes上でdynmapを動かしてingnressによる外部公開をするまでのメモ。
構成
- マイクラ鯖:OCI無料枠(2Core, 12GB、PaperMC)
- tailscale(自宅との接続用)
- Kubernetesクラスタ(Calico, ingress-nginx, ArgoCD)
- MariaDB
実際はマイクラ鯖にアクセスするまでにVelocityを噛ませたりしてますが今回は特に必要ないので端折ります
マイクラ鯖を建てる
お好きな環境でマイクラ鯖を建ててください。私はちょうどOCIの無料枠が余っていたのでそこに建てました。
Dynmapも通常通り追加しておきます。(先にマイクラ鯖上でマップ生成されると困る場合は先にconfigurationを書いてもいいかもしれません)
dynmapの設定変更
データベースの変更
デフォルトだとpluginsフォルダにマップデータが保存されますがそのままだとdynmapを外部へ出したときに参照できなくなるので外部のデータベースへ保存するようにします。
今回はMySQLを使いますがPostgreSQLであったりS3ストレージなんかも使えるらしいのでお好きなものをご利用ください。
MySQLの場合はデータベースとアクセス用のユーザーを適当に作成してあげればOKです。データベースがKubernetesクラスタとマイクラサーバーの両方からアクセスできるようにしておいてください。
参考
storage:
# Filetree storage (standard tree of image files for maps)
#type: filetree
# SQLite db for map storage (uses dbfile as storage location)
#type: sqlite
#dbfile: dynmap.db
# MySQL DB for map storage (at 'hostname':'port' with flags "flags" in database 'database' using user 'userid' password 'password' and table prefix 'prefix')
type: mysql
hostname: DBサーバーのIP(マイクラ鯖側からアクセスできるもの)
port: 3306
database: dynmap_mc01
userid: minecraft
password: password
#prefix: ""
#flags: "?allowReconnect=true&autoReconnect=true"
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#override_endpoint: ""
内部Webサーバーの無効化
下の記事を参考にdynmapのconfiguration.txtを外部サーバー向けに書き換えます。
変更箇所(引用)
org.dynmap.InternalClientUpdateComponentの部分をすべてコメントアウトし、その下にあるorg.dynmap.JsonFileClientUpdateComponentのコメントアウトを外します。
- class: org.dynmap.InternalClientUpdateComponent
sendhealth: true
sendposition: true
allowwebchat: true
webchat-interval: 5
hidewebchatip: false
trustclientname: false
includehiddenplayers: false
# (optional) if true, color codes in player display names are used
use-name-colors: false
# (optional) if true, player login IDs will be used for web chat when their IPs match
use-player-login-ip: true
# (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored
require-player-login-ip: false
# (optional) block player login IDs that are banned from chatting
block-banned-player-chat: true
# Require login for web-to-server chat (requires login-enabled: true)
webchat-requires-login: false
# If set to true, users must have dynmap.webchat permission in order to chat
webchat-permissions: false
# Limit length of single chat messages
chatlengthlimit: 256
# # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky)
# hideifshadow: 4
# # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky)
# hideifundercover: 14
# # (Optional) if true, players that are crouching/sneaking will be hidden
hideifsneaking: false
# If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self)
protected-player-info: false
# If true, hide players with invisibility potion effects active
hide-if-invisiblity-potion: true
# If true, player names are not shown on map, chat, list
hidenames: false
#- class: org.dynmap.JsonFileClientUpdateComponent
# writeinterval: 1
# sendhealth: true
# sendposition: true
# allowwebchat: true
# webchat-interval: 5
# hidewebchatip: false
# includehiddenplayers: false
# use-name-colors: false
# use-player-login-ip: false
# require-player-login-ip: false
# block-banned-player-chat: true
# hideifshadow: 0
# hideifundercover: 0
# hideifsneaking: false
# # Require login for web-to-server chat (requires login-enabled: true)
# webchat-requires-login: false
# # If set to true, users must have dynmap.webchat permission in order to chat
# webchat-permissions: false
# # Limit length of single chat messages
# chatlengthlimit: 256
# hide-if-invisiblity-potion: true
# hidenames: false
#- class: org.dynmap.InternalClientUpdateComponent
# sendhealth: true
# sendposition: true
# allowwebchat: true
# webchat-interval: 5
# hidewebchatip: false
# trustclientname: false
# includehiddenplayers: false
# # (optional) if true, color codes in player display names are used
# use-name-colors: false
# # (optional) if true, player login IDs will be used for web chat when their IPs match
# use-player-login-ip: true
# # (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored
# require-player-login-ip: false
# # (optional) block player login IDs that are banned from chatting
# block-banned-player-chat: true
# # Require login for web-to-server chat (requires login-enabled: true)
# webchat-requires-login: false
# # If set to true, users must have dynmap.webchat permission in order to chat
# webchat-permissions: false
# # Limit length of single chat messages
# chatlengthlimit: 256
# # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky)
# hideifshadow: 4
# # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky)
# hideifundercover: 14
# # (Optional) if true, players that are crouching/sneaking will be hidden
# hideifsneaking: false
# # If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self)
# protected-player-info: false
# # If true, hide players with invisibility potion effects active
# hide-if-invisiblity-potion: true
# # If true, player names are not shown on map, chat, list
# hidenames: false
- class: org.dynmap.JsonFileClientUpdateComponent
writeinterval: 1
sendhealth: true
sendposition: true
allowwebchat: true
webchat-interval: 5
hidewebchatip: false
includehiddenplayers: false
use-name-colors: false
use-player-login-ip: false
require-player-login-ip: false
block-banned-player-chat: true
hideifshadow: 0
hideifundercover: 0
hideifsneaking: false
# # Require login for web-to-server chat (requires login-enabled: true)
webchat-requires-login: false
# # If set to true, users must have dynmap.webchat permission in order to chat
webchat-permissions: false
# # Limit length of single chat messages
chatlengthlimit: 256
hide-if-invisiblity-potion: true
hidenames: false
それからdisable-webserverもtrueにしておきましょう。
dynmap用のイメージの作成
次にKubernetes上でDynmapを動作させるためのイメージを作成します。
FROM php:7.4-apache
COPY web/ /var/www/html
RUN docker-php-ext-install mysqli pdo pdo_mysql
Dockerfileと同じ階層にマイクラ鯖のplugins/dynmap/内のwebをフォルダごとコピーしてください。
その後、必要に応じてwebフォルダ内のstandalone/MySQL_config.phpを書き換えてください。(主にKubernetesとマイクラ鯖が違うネットワークにいる場合)
<?php
$dbname = 'dynmap_mc01';
$dbhost = 'DBサーバーのIP(Kubernetes側からアクセスできるもの)';
$dbport = 3306;
$dbuserid = 'minecraft';
$dbpassword = 'password';
$dbprefix = '';
$loginenabled = true;
?>
K8sクラスタとマイクラ鯖が違うネットワークにあるなど、複雑な構成でなければ特に触らなくて大丈夫です
ビルド後は任意のコンテナリポジトリへアップロードし、Kubernetesクラスタからpullできるようにします。
デプロイ
あとは通常のWebサーバーと同様にデプロイします。
apiVersion: apps/v1
kind: Deployment
metadata:
name: dynmap-mc01
spec:
replicas: 1
selector:
matchLabels:
app: dynmap-mc01
template:
metadata:
labels:
app: dynmap-mc01
spec:
containers:
- name: dynmap-mc01
image: アップロードしたURL
imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: dynmap-mc01
spec:
type: ClusterIP
ports:
- name: "http-port"
protocol: "TCP"
port: 80
targetPort: 80
selector:
app: dynmap-mc01
enjoy!
以上でKubernetesクラスタへのdynmapの移行は以上となります。お疲れ様でした。
今回はマイクラサーバーがtailscaleネットワーク上にあるためIPアドレスの変更などの手順がありましたが、ローカルネットワークで完結or全ノードがtailnet上にあればもっと楽かと思います。
なにか分かりにくい点等あれば遠慮なく質問していただけると幸いです。