🐙

proxmoxによるk8sクラスタの構築でDiscord TTS Botとマイクラサーバーの建て方

に公開

ProxmoxによるKubernetesクラスター構築 - Discord TTS Bot & マイクラサーバー構築ガイド

目次

  1. 概要
  2. Proxmox環境構築
  3. Kubernetesクラスター構築
  4. Discord TTS Bot構築
  5. マイクラサーバー構築
  6. ネットワークセキュリティ設定
  7. 運用・保守
  8. トラブルシューティング

概要

アーキテクチャ概要

[Proxmox Hypervisor] ├── [Master Node] - Kubernetes Control Plane ├── [Worker Node 1] - GPU対応 (Discord TTS Bot + aivisspeech-engine) ├── [Worker Node 2] - ゲームサーバー専用 (Minecraft Server) └── [共有ストレージ] - NFS/Ceph (ワールドデータ永続化)

構築するサービス

  • Discord TTS Bot (6インスタンス) - 音声読み上げサービス
  • AivisSpeech-Engine - 高品質音声合成エンジン (GPU使用)
  • Minecraft Server - マルチプレイヤーゲームサーバー
  • ネットワークセキュリティ - Cilium + NetworkPolicy

Proxmox環境構築

システム要件(実際の運用例)

Hardware:
    CPU: AMD Ryzen 5 3600 (6コア12スレッド)
    RAM: 32GiB
    Storage: SSD 1TiB
    Network: 1Gbps Ethernet
    GPU: NVIDIA GTX 1660 Super

Software:
    Proxmox VE: 9.0.3
    OS: Oracle Linux 9.6

Proxmox初期セットアップ

1. ISO ダウンロードとインストール

# Proxmox VE 8.0 ISO をダウンロード
wget https://www.proxmox.com/en/downloads

# USBメディアに書き込み
dd if=proxmox-ve_8.0-2.iso of=/dev/sdX bs=1M status=progress

2. 基本設定

# Proxmox初期設定
hostnamectl set-hostname proxmox-k8s
echo "192.168.1.100 proxmox-k8s" >> /etc/hosts

# アップデート
apt update && apt upgrade -y

# 必要なパッケージインストール
apt install -y curl wget git vim

3. GPU パススルー設定 (NVIDIA GPU使用時)

# GRUB設定編集
vim /etc/default/grub
# GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

# GRUB更新
update-grub

# VFIO モジュール設定
echo 'vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd' >> /etc/modules

# 再起動
reboot

GPU OperatorとNVIDIAドライバー運用のポイント

KubernetesのGPU OperatorはNVIDIAドライバーの自動インストール機能を持っていますが、
物理ノード(ワーカーノード)にあらかじめNVIDIA公式ドライバーとNVIDIA Container Toolkit(nvidia-docker2相当)を手動でインストールしておくことで、
GPU Operatorのdriver DaemonSetを無効化し、安定してNVIDIA GPUをKubernetesで利用できます。

メリット

  • ドライバーのバージョン管理が容易
  • OSアップデートや特殊なカーネル環境でも柔軟に対応可能
  • Operatorのdriver自動インストールによるトラブルを回避

この構成は多くの実運用現場で推奨される方法です。
(必要に応じて、values.yamlやCRDでdriverコンポーネントを無効化してください)


Kubernetesクラスター構築

VM構成

Master Node (Control Plane)

VM設定:
    CPU: 4 cores
    RAM: 8GB
    Disk: 50GB
    OS: Ubuntu 22.04 LTS
    Network: Bridge (vmbr0)
    IP: 192.168.1.101

Worker Node 1 (GPU + TTS)

VM設定:
    CPU: 6 cores
    RAM: 16GB
    Disk: 100GB
    OS: Ubuntu 22.04 LTS
    GPU: NVIDIA RTX (パススルー)
    Network: Bridge (vmbr0)
    IP: 192.168.1.102

Worker Node 2 (Game Server)

VM設定:
    CPU: 8 cores
    RAM: 16GB
    Disk: 200GB
    OS: Ubuntu 22.04 LTS
    Network: Bridge (vmbr0)
    IP: 192.168.1.103

Proxmox VM作成スクリプト

#!/bin/bash
# VM作成スクリプト

# Master Node
qm create 101 --name k8s-master --memory 8192 --cores 4 --net0 virtio,bridge=vmbr0
qm importdisk 101 ubuntu-22.04-server-amd64.iso local-lvm
qm set 101 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-101-disk-0
qm set 101 --boot c --bootdisk scsi0
qm set 101 --ide2 local:iso/ubuntu-22.04-server-amd64.iso,media=cdrom
qm set 101 --serial0 socket --vga serial0

# Worker Node 1 (GPU)
qm create 102 --name k8s-worker01 --memory 16384 --cores 6 --net0 virtio,bridge=vmbr0
qm importdisk 102 ubuntu-22.04-server-amd64.iso local-lvm
qm set 102 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-102-disk-0
qm set 102 --boot c --bootdisk scsi0
qm set 102 --ide2 local:iso/ubuntu-22.04-server-amd64.iso,media=cdrom
qm set 102 --hostpci0 01:00,pcie=1  # GPU パススルー

# Worker Node 2 (Game)
qm create 103 --name k8s-worker02 --memory 16384 --cores 8 --net0 virtio,bridge=vmbr0
qm importdisk 103 ubuntu-22.04-server-amd64.iso local-lvm
qm set 103 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-103-disk-0
qm set 103 --boot c --bootdisk scsi0
qm set 103 --ide2 local:iso/ubuntu-22.04-server-amd64.iso,media=cdrom

Kubernetes基盤インストール

全ノード共通の初期設定

# ホスト名設定
hostnamectl set-hostname k8s-master  # または k8s-worker01, k8s-worker02

# カーネルモジュール有効化
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

# カーネルパラメータ設定
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

sysctl --system

# Swap無効化
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

Container Runtime (containerd) インストール

# Docker公式リポジトリ追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# containerd インストール
apt update
apt install -y containerd.io

# containerd 設定
mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# systemd cgroup ドライバー有効化
sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml

systemctl restart containerd
systemctl enable containerd

Kubernetes コンポーネントインストール

# Kubernetes公式リポジトリ追加
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /usr/share/keyrings/kubernetes-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# kubelet, kubeadm, kubectl インストール
apt update
apt install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl

systemctl enable --now kubelet

クラスター初期化

Master Node でクラスター初期化

# クラスター初期化
kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.1.101

# kubectlアクセス設定
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# join コマンドをメモ
kubeadm token create --print-join-command

Worker Node をクラスターに追加

# Worker Node 1, 2 で実行
kubeadm join 192.168.1.101:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

CNI (Cilium) インストール

# Cilium CLI インストール
curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-amd64.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz{,.sha256sum}

# Cilium インストール
cilium install

# インストール確認
cilium status --wait

Worker Node 1 (GPU) の前提条件セットアップ

# NVIDIA ドライバーインストール
ssh k8s-worker01

# NVIDIA公式リポジトリ追加
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

apt update

# NVIDIA ドライバーとContainer Toolkit インストール
apt install -y nvidia-driver-535 nvidia-container-toolkit

# containerd にNVIDIA Container Runtime 設定
nvidia-ctk runtime configure --runtime=containerd
systemctl restart containerd

# 再起動してドライバー有効化
reboot

GPU Operator インストール (ドライバー除外設定)

# NVIDIA GPU Operator (ドライバーインストール無効)
helm repo add nvidia https://nvidia.github.io/gpu-operator
helm repo update

# GPU Operator インストール (ドライバーインストールを無効化)
helm install --wait --generate-name \
    -n gpu-operator --create-namespace \
    nvidia/gpu-operator \
    --set driver.enabled=false \
    --set toolkit.enabled=false

# GPU リソース確認
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.allocatable.nvidia\.com/gpu}{"\n"}{end}'

Discord TTS Bot構築

前提条件の確認

# クラスター状態確認
kubectl get nodes
kubectl get pods -A

# GPU使用可能性確認
kubectl get nodes -o jsonpath='{.items[*].status.allocatable.nvidia\.com/gpu}'

AivisSpeech-Engine デプロイ

ストレージ準備

# ホスト上でモデル保存ディレクトリ作成
ssh k8s-worker01
sudo mkdir -p /home/alec/models /home/alec/aivisspeech-data
sudo chown 1000:1000 /home/alec/models /home/alec/aivisspeech-data

aivisspeech-engine.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: aivisspeech-engine
spec:
    replicas: 1
    strategy:
        type: Recreate
    selector:
        matchLabels:
            app: aivisspeech-engine
    template:
        metadata:
            labels:
                app: aivisspeech-engine
        spec:
            nodeSelector:
                nvidia.com/gpu.present: "true"
            initContainers:
                - name: copy-models
                    image: busybox:latest
                    command: ['/bin/sh', '-c']
                    args:
                        - |
                            mkdir -p /aivisspeech-data/Models /aivisspeech-data/Logs
                            cp -r /models/* /aivisspeech-data/Models/ 2>/dev/null || echo "No models to copy"
                            chown -R 1000:1000 /aivisspeech-data
                            ls -la /aivisspeech-data/Models/
                    volumeMounts:
                        - name: aivisspeech-data
                            mountPath: /aivisspeech-data
                        - name: models-data
                            mountPath: /models
            containers:
                - name: aivisspeech-engine
                    image: ghcr.io/aivis-project/aivisspeech-engine:nvidia-latest
                    ports:
                        - containerPort: 10101
                    volumeMounts:
                        - name: aivisspeech-data
                            mountPath: /home/user/.local/share/AivisSpeech-Engine-Dev
                        - name: models-data
                            mountPath: /models
                    resources:
                        requests:
                            nvidia.com/gpu: "1"
                            memory: "4Gi"
                            cpu: "2000m"
                        limits:
                            nvidia.com/gpu: "1"
                            memory: "8Gi"
                            cpu: "4000m"
                    env:
                        - name: NVIDIA_VISIBLE_DEVICES
                            value: "all"
                        - name: NVIDIA_DRIVER_CAPABILITIES
                            value: "compute,utility"
                        - name: CUDA_VISIBLE_DEVICES
                            value: "0"
                        - name: OMP_NUM_THREADS
                            value: "4"
                        - name: PYTORCH_CUDA_ALLOC_CONF
                            value: "max_split_size_mb:128"
                        - name: DEFAULT_PRE_SILENCE
                            value: "0.1"
                        - name: DEFAULT_POST_SILENCE
                            value: "0.1"
            volumes:
                - name: aivisspeech-data
                    hostPath:
                        path: /home/alec/aivisspeech-data
                        type: DirectoryOrCreate
                - name: models-data
                    hostPath:
                        path: /home/alec/models
                        type: Directory
            tolerations:
                - key: "nvidia.com/gpu"
                    operator: "Exists"
                    effect: "NoSchedule"

---
apiVersion: v1
kind: Service
metadata:
    name: aivisspeech-engine
spec:
    type: NodePort
    ports:
        - port: 10101
            targetPort: 10101
            nodePort: 30101
    selector:
        app: aivisspeech-engine

Discord Bot デプロイ

Dockerfile (各Bot共通)

# マルチステージビルド
FROM node:22 AS builder

# 依存関係インストール
RUN apt-get update && apt-get install -y \
        ffmpeg \
        python3 \
        make \
        g++ \
        --no-install-recommends && \
        rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run compile

# 本番イメージ
FROM node:22-slim

RUN apt-get update && apt-get install -y ffmpeg --no-install-recommends && \
        rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/node_modules ./node_modules
COPY --from=builder /usr/src/app/package*.json ./
COPY --from=builder /usr/src/app/build/js ./build/js

EXPOSE 3000
CMD ["node", "build/js/index.js"]

Bot デプロイメント例 (aivis-chan-bot-1st.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
    name: aivis-chan-bot-1st
spec:
    replicas: 1
    selector:
        matchLabels:
            app: aivis-chan-bot-1st
    template:
        metadata:
            labels:
                app: aivis-chan-bot-1st
        spec:
            containers:
            - name: bot
                image: alecjp02/aivis-chan-bot-1st:latest
                ports:
                - containerPort: 3000
                env:
                - name: TTS_SERVICE_URL
                    value: "http://aivisspeech-engine:10101"
                - name: SPEECH_ENGINE_URL
                    value: "http://aivisspeech-engine:10101"
                resources:
                    requests:
                        memory: "512Mi"
                        cpu: "250m"
                    limits:
                        memory: "1Gi"
                        cpu: "500m"
                volumeMounts:
                - name: config-volume
                    mountPath: /usr/src/app/data
            volumes:
            - name: config-volume
                configMap:
                    name: bot-config

---
apiVersion: v1
kind: Service
metadata:
    name: aivis-chan-bot-1st
spec:
    type: NodePort
    ports:
    - port: 3000
        targetPort: 3000
        nodePort: 31001
    selector:
        app: aivis-chan-bot-1st

デプロイ手順

# Docker イメージビルド
cd Aivis-chan-bot-1st
docker build -t alecjp02/aivis-chan-bot-1st:latest .
docker push alecjp02/aivis-chan-bot-1st:latest

# ConfigMap作成
kubectl create configmap bot-config --from-file=data/

# デプロイ
kubectl apply -f aivisspeech-engine.yaml
kubectl apply -f aivis-chan-bot-1st.yaml
# 他のBotも同様に適用

# 状態確認
kubectl get pods -l app=aivisspeech-engine
kubectl get pods -l app=aivis-chan-bot-1st

マイクラサーバー構築

マイクラサーバー用ストレージ準備

# 永続ボリューム用ディレクトリ作成
ssh k8s-worker02
sudo mkdir -p /home/minecraft/{world,config,plugins,mods}
sudo chown 1000:1000 /home/minecraft/{world,config,plugins,mods}

Minecraft Server デプロイメント

minecraft-server.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
    name: minecraft-world-pv
spec:
    capacity:
        storage: 50Gi
    accessModes:
        - ReadWriteOnce
    persistentVolumeReclaimPolicy: Retain
    hostPath:
        path: /home/minecraft/world

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: minecraft-world-pvc
spec:
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 50Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
    name: minecraft-server
spec:
    replicas: 1
    strategy:
        type: Recreate
    selector:
        matchLabels:
            app: minecraft-server
    template:
        metadata:
            labels:
                app: minecraft-server
        spec:
            nodeSelector:
                kubernetes.io/hostname: k8s-worker02
            containers:
            - name: minecraft
                image: itzg/minecraft-server:latest
                ports:
                - containerPort: 25565
                    protocol: TCP
                - containerPort: 25575
                    protocol: TCP  # RCON
                env:
                - name: EULA
                    value: "TRUE"
                - name: TYPE
                    value: "PAPER"  # または VANILLA, FORGE, FABRIC
                - name: VERSION
                    value: "1.20.1"
                - name: MEMORY
                    value: "8G"
                - name: MAX_PLAYERS
                    value: "20"
                - name: DIFFICULTY
                    value: "normal"
                - name: MODE
                    value: "survival"
                - name: MOTD
                    value: "Kubernetes Minecraft Server"
                - name: ENABLE_RCON
                    value: "true"
                - name: RCON_PASSWORD
                    value: "minecraft_rcon_password"
                - name: SERVER_NAME
                    value: "k8s-minecraft"
                - name: SPAWN_PROTECTION
                    value: "0"
                - name: VIEW_DISTANCE
                    value: "10"
                - name: SIMULATION_DISTANCE
                    value: "8"
                resources:
                    requests:
                        memory: "8Gi"
                        cpu: "2000m"
                    limits:
                        memory: "12Gi"
                        cpu: "4000m"
                volumeMounts:
                - name: minecraft-world
                    mountPath: /data
                livenessProbe:
                    exec:
                        command:
                        - mc-health
                    initialDelaySeconds: 120
                    periodSeconds: 60
                readinessProbe:
                    exec:
                        command:
                        - mc-health
                    initialDelaySeconds: 30
                    periodSeconds: 10
            volumes:
            - name: minecraft-world
                persistentVolumeClaim:
                    claimName: minecraft-world-pvc

---
apiVersion: v1
kind: Service
metadata:
    name: minecraft-server
spec:
    type: NodePort
    ports:
    - name: minecraft
        port: 25565
        targetPort: 25565
        nodePort: 30565
        protocol: TCP
    - name: rcon
        port: 25575
        targetPort: 25575
        nodePort: 30575
        protocol: TCP
    selector:
        app: minecraft-server

MOD対応サーバー設定

Forge サーバー用設定

env:
- name: TYPE
    value: "FORGE"
- name: FORGE_VERSION
    value: "47.2.0"  # 1.20.1対応
- name: MODS_FILE
    value: "/data/mods.txt"  # MOD一覧ファイル

プラグイン対応 (Paper/Spigot)

env:
- name: TYPE
    value: "PAPER"
- name: PLUGINS
    value: |
        https://github.com/EssentialsX/Essentials/releases/download/2.20.1/EssentialsX-2.20.1.jar
        https://github.com/WorldEdit/WorldEdit/releases/download/7.2.15/worldedit-bukkit-7.2.15.jar

Discord Bot デプロイ手順

# デプロイ
kubectl apply -f minecraft-server.yaml

# 状態確認
kubectl get pods -l app=minecraft-server
kubectl logs minecraft-server-xxxxx -f

# サーバー接続テスト
kubectl port-forward svc/minecraft-server 25565:25565
# Minecraft クライアントで localhost:25565 に接続

ネットワークセキュリティ設定

NetworkPolicy 設定

Discord Bot 用 NetworkPolicy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: discord-bot-policy
spec:
    podSelector:
        matchExpressions:
        - key: app
            operator: In
            values:
            - aivis-chan-bot-1st
            - aivis-chan-bot-2nd
            - aivis-chan-bot-3rd
            - aivis-chan-bot-4th
            - aivis-chan-bot-5th
            - aivis-chan-bot-6th
    policyTypes:
    - Ingress
    - Egress
    ingress:
    - from:
        - namespaceSelector:
                matchLabels:
                    name: kube-system
        ports:
        - protocol: TCP
            port: 3000
    egress:
    - to:
        - namespaceSelector:
                matchLabels:
                    name: kube-system
        ports:
        - protocol: UDP
            port: 53
        - protocol: TCP
            port: 53
    - to:
        - podSelector:
                matchLabels:
                    app: aivisspeech-engine
        ports:
        - protocol: TCP
            port: 10101
    - to: []
        ports:
        - protocol: TCP
            port: 443
        - protocol: TCP
            port: 80
    - to: []
        ports:
        - protocol: UDP

Minecraft Server 用 NetworkPolicy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: minecraft-server-policy
spec:
    podSelector:
        matchLabels:
            app: minecraft-server
    policyTypes:
    - Ingress
    - Egress
    ingress:
    # Minecraftクライアントからの接続を許可
    - from: []
        ports:
        - protocol: TCP
            port: 25565
    # RCON アクセスを管理者のみに制限
    - from:
        - ipBlock:
                cidr: 192.168.1.0/24  # 内部ネットワークのみ
        ports:
        - protocol: TCP
            port: 25575
    egress:
    # DNS解決を許可
    - to:
        - namespaceSelector:
                matchLabels:
                    name: kube-system
        ports:
        - protocol: UDP
            port: 53
        - protocol: TCP
            port: 53
    # Mojang API への接続を許可
    - to: []
        ports:
        - protocol: TCP
            port: 443
        - protocol: TCP
            port: 80

ファイアウォール適用

# NetworkPolicy 適用
kubectl apply -f network-policies/

# 適用確認
kubectl get networkpolicies -A

運用・保守

監視設定

Prometheus + Grafana デプロイ

# Helm で Prometheus Stack インストール
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install prometheus prometheus-community/kube-prometheus-stack \
    --namespace monitoring --create-namespace \
    --set grafana.adminPassword=admin123

カスタムダッシュボード

  • Minecraft Server メトリクス
  • Discord Bot パフォーマンス
  • GPU 使用率
  • ネットワークトラフィック

バックアップ設定

Minecraft World バックアップ

#!/bin/bash
# minecraft-backup.sh

BACKUP_DIR="/backup/minecraft"
WORLD_DIR="/home/minecraft/world"
DATE=$(date +%Y%m%d_%H%M%S)

# RCON でワールド保存
kubectl exec -it $(kubectl get pod -l app=minecraft-server -o jsonpath='{.items[0].metadata.name}') -- \
    rcon-cli --host localhost --port 25575 --password minecraft_rcon_password save-all

# バックアップ作成
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/world_backup_$DATE.tar.gz -C $WORLD_DIR .

# 古いバックアップ削除 (7日以上)
find $BACKUP_DIR -name "world_backup_*.tar.gz" -mtime +7 -delete

Discord Bot 設定バックアップ

#!/bin/bash
# bot-config-backup.sh

BACKUP_DIR="/backup/discord-bot"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# ConfigMap のバックアップ
kubectl get configmaps -o yaml > $BACKUP_DIR/configmaps_$DATE.yaml

# シークレットのバックアップ
kubectl get secrets -o yaml > $BACKUP_DIR/secrets_$DATE.yaml

自動復旧設定

Pod 自動再起動設定

apiVersion: v1
kind: Pod
metadata:
    name: minecraft-server
spec:
    restartPolicy: Always  # Always, OnFailure, Never
    containers:
    - name: minecraft
        image: itzg/minecraft-server:latest
        livenessProbe:
            exec:
                command:
                - mc-health
            initialDelaySeconds: 120
            periodSeconds: 60
            failureThreshold: 3
        readinessProbe:
            exec:
                command:
                - mc-health
            initialDelaySeconds: 30
            periodSeconds: 10

ログ管理

集約ログ設定 (ELK Stack)

# Elasticsearch, Logstash, Kibana デプロイ
helm repo add elastic https://helm.elastic.co
helm install elasticsearch elastic/elasticsearch --namespace logging --create-namespace
helm install kibana elastic/kibana --namespace logging

トラブルシューティング

よくある問題と解決方法

1. GPU が認識されない

# GPU ノードの確認
kubectl describe node k8s-worker01 | grep nvidia.com/gpu

# GPU Operator の状態確認
kubectl get pods -n gpu-operator

# ドライバーログ確認 (ホスト側にドライバーがある場合)
nvidia-smi

# containerd設定確認
nvidia-ctk runtime configure --runtime=containerd --dry-run

2. Minecraft サーバーが起動しない

# Pod ログ確認
kubectl logs minecraft-server-xxxxx

# リソース不足の確認
kubectl describe pod minecraft-server-xxxxx

# ストレージマウント確認
kubectl exec -it minecraft-server-xxxxx -- ls -la /data

3. Discord Bot が aivisspeech-engine に接続できない

# ネットワーク接続テスト
kubectl exec -it aivis-chan-bot-1st-xxxxx -- ping aivisspeech-engine

# NetworkPolicy 確認
kubectl describe networkpolicy discord-bot-policy

# DNS 解決確認
kubectl exec -it aivis-chan-bot-1st-xxxxx -- nslookup aivisspeech-engine

4. ストレージ容量不足

# ディスク使用量確認
df -h

# Pod のストレージ使用量確認
kubectl exec -it minecraft-server-xxxxx -- du -sh /data/*

# 不要ファイル削除
kubectl exec -it minecraft-server-xxxxx -- find /data/logs -name "*.log.gz" -mtime +30 -delete

パフォーマンスチューニング

Minecraft Server 最適化

env:
# JVM 最適化パラメータ
- name: JVM_OPTS
    value: "-Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1"

# Paper サーバー設定
- name: PAPER_SETTINGS
    value: |
        use-alternative-luck-formula: true
        fix-entity-position-desync: true
        
# スレッド設定
- name: USE_AIKAR_FLAGS
    value: "true"

Discord Bot メモリ最適化

// メモリ使用量監視とガベージコレクション制御
let lastMemoryCheck = 0;
const MEMORY_CHECK_INTERVAL = 30000; // 30秒間隔

export function monitorMemoryUsage() {
        const now = Date.now();
        if (now - lastMemoryCheck < MEMORY_CHECK_INTERVAL) return;
        
        lastMemoryCheck = now;
        const memUsage = process.memoryUsage();
        const heapUsedMB = Math.round(memUsage.heapUsed / 1024 / 1024);
        
        if (heapUsedMB > 512) { // 512MB超過時
                if (global.gc) {
                        global.gc();
                }
        }
}

関連リンク・参考資料

公式ドキュメント

コミュニティリソース

運用ツール


作成日: 2025年8月14日
作成者: システム管理者
対象環境: Proxmox VE 8.0 + Kubernetes 1.28
更新予定: 月次レビュー

Discussion