> For AI agents: the complete documentation index is available at /ja/llms.txt, the full documentation bundle is available at /ja/llms-full.txt.

# Docker + K8s 分離デプロイ

この記事では、軽量デプロイのK3sを例に、すでにK8sクラスタをデプロイしている場合、この記事の後半の設定を参考に同様の設定を行うことができます。

:::danger

**このチュートリアルは、操作を行う前に必ず全文を読むようにしてください。そうしないと、デプロイ結果が期待通りにならない可能性があります。**

:::

## Dockerのインストール

[Docker公式サイト](https://docs.docker.com/engine/install/)で関連するインストール手順を見つけることができます。そして、[クイックスタート](/ja/guide/start/quick-start.md)の基本設定を使用してGZCTFを起動します。

## k3sのインストール

k3sは軽量なk8sディストリビューションで、シングルマシンやマルチマシン上でk8sクラスタを迅速にデプロイすることができます。公式ドキュメントのURL：[https://docs.k3s.io](https://docs.k3s.io)

:::warning サーバーが1台だけの場合？

もしサーバーが1台だけの場合、他の方法でデプロイすることを強くお勧めします：

- **200チーム以下、30問程度の非公開ネットワーク内**のゲームについては、k8sを使用せず、Dockerで直接デプロイできます。
- **公開または大規模のゲーム**については、k3sを一体化してデプロイすることを強くお勧めします。**Dockerの使用は避けてください**。

***

最後に、どうしてもDockerを使用してk3sを実行したい場合、インストール時に以下のパラメータを追加してDockerバックエンドを指定できますが、**強くお勧めしません**。さまざまな互換性の問題を修正する必要があるかもしれず、多くの困難が生じる可能性があります。

```bash
INSTALL_K3S_EXEC="--docker"
```

:::

:::info

もし一台のk3sインスタンスで255個を超えるチャレンジコンテナを実行したい場合は、**k3sのインストール時に**`INSTALL_K3S_EXEC`を指定し、`node-cidr-mask-size`を必要なサブネットサイズに変更する必要があります。

```bash
INSTALL_K3S_EXEC="--kube-controller-manager-arg=node-cidr-mask-size=22"
```

**上記の設定はインストール後に容易には変更できません。** 推奨は `/22`（各ノード約 1024 Pod）で、必要に応じて `/20`（各ノード約 4096 Pod）を使用してください。さらに大きくしても（例: `/16`）単一ノードに過大なアドレス空間を確保するだけで、worker を増やしてスケールさせる能力を損ないます。

上記の設定は、ノードのPodが使用するIPアドレス範囲を変更するだけであり、ノードのPod数制限を変更する場合は、以下を参照してください。

:::

そして、以下の形式でk3sをインストールします。詳細は[k3sのインストール設定](https://docs.k3s.io/installation/configuration)を参照してください：

```bash
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="..." sh -
```

:::info

中国のユーザーは、以下の方法でインストールを高速化することができます：

```bash
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
```

:::

マルチマシンのインストールとクラスタの構築については、[公式ドキュメント](https://docs.k3s.io/quick-start)を参照してください。

## GZCTFの設定

k3sの接続設定ファイルは`/etc/rancher/k3s/k3s.yaml`にあり、以下のコマンドでエクスポートできます：

```bash
sudo cat /etc/rancher/k3s/k3s.yaml
```

以下のコマンドを使用して、k3s control-panelが存在するマシンのIPを取得します：

```bash
sudo k3s kubectl cluster-info
```

:::info

もし`127.0.0.1`が表示された場合、それはk3s control-panelが現在のマシンであることを意味します。`ip a`を使用して現在のマシンのIPを確認してください。

IPアドレスを直接使用することも、ドメイン名を使用することもできますが、ドメイン名がk3s control-panelのあるマシンに解決され、GZCTFのマシンがその6443ポートにアクセスできることを確認する必要があります。

:::

上記の出力内容を`kube-config.yaml`として保存し、`server`フィールドをk3s control-panelのあるマシンのIPに変更します。例えば、

```yaml
apiVersion: v1
clusters:
  - cluster:
      certificate-authority-data: # ...
      server: https://127.0.0.1:6443 # change this to your k3s control-panel's IP or domain
    name: default
# ...
```

これをGZCTFをデプロイするマシンに保存し、`compose.yml`と同じフォルダに置きます。例えば`kube-config.yaml`とします。
次に`compose.yml`のマウント情報を変更します：

```yaml
gzctf:
  image: gztime/gzctf:latest
  restart: always
  ports:
    - "80:8080"
  networks:
    default:
  volumes:
    - "./data/files:/app/files"
    - "./appsettings.json:/app/appsettings.json:ro"
    - "./kube-config.yaml:/app/kube-config.yaml:ro" # this is required for k8s deployment
    # - "/var/run/docker.sock:/var/run/docker.sock" # this is required for docker deployment
  depends_on:
    - db
```

同時に`appsettings.json`を変更し、`ContainerProvider`フィールドを設定します：

```json
{
  "Type": "Kubernetes",
  "PublicEntry": "ctf.example.com" // change this to your k3s control-panel's IP or domain
}
```

GZCTFを再起動すると、k3sをコンテナバックエンドとして使用できるようになります。すでにk8sを使用した経験があるユーザーは、上記の設定プロセスを参考にして、GZCTFを既存のk8sクラスタに接続することができます。

## NodePort ポート範囲の変更

k3sのデフォルトのNodePortポート範囲は30000-32767ですが、これは要件と一致しない場合があります。そのため、必要に応じてk3sのNodePortポート範囲を変更することができます。

k3s control-panelが存在するマシンで以下のコマンドを実行します：

- `sudo nano /etc/systemd/system/k3s.service`

- `ExecStart`の設定を編集し、`service-node-port-range`を指定します。

  ```bash
  ExecStart=/usr/local/bin/k3s \
      server \
      --kube-apiserver-arg=service-node-port-range=20000-50000
  ```

- `sudo systemctl daemon-reload`

- `sudo systemctl restart k3s`

## K3sのコンテナ数制限の変更

k3sのデフォルトのコンテナ数制限は110ですが、これは大量の小さなコンテナを含むゲームには適していないかもしれません。そのため、必要に応じてk3sのコンテナ数制限を変更することができます。

:::info

参考：[How do you increase maximum pods per node in K3S?](https://stackoverflow.com/questions/65894616/how-do-you-increase-maximum-pods-per-node-in-k3s)

:::

k3s control-panelが存在するマシンで、内蔵の設定ファイル `/etc/rancher/k3s/config.yaml` を使用して調整します：

- `sudo nano /etc/rancher/k3s/config.yaml`

- 以下を追加・編集します（例：各ノードの上限を 800 に設定）：

  ```yaml
  kubelet-arg:
    - max-pods=800
  ```

- 保存後、サービスを再起動して反映します：

  ```bash
  sudo systemctl restart k3s
  ```

- オプション：各ノードにより大きな Pod サブネットを確保したい場合は、同じファイルで `kube-controller-manager-arg` を設定します。推奨は `/22`（各ノード約 1024 Pod）、必要に応じて `/20`：

  ```yaml
  kube-controller-manager-arg:
    - node-cidr-mask-size=22
  ```

- 注意：`node-cidr-mask-size` を小さくしすぎる（例：`/16`）と、単一ノードに過大なアドレスブロックが割り当てられ、worker を追加して水平スケールする柔軟性が低下します。

## コンテナイメージリポジトリの追加

k3sはデフォルトで公開イメージリポジトリからイメージを取得できます。**プライベートな**コンテナイメージリポジトリを使用する必要がある場合は、k3sの`registries.yaml`設定ファイルでイメージリポジトリを追加してください。

k3s control-panelが存在するマシンで以下のコマンドを実行します：

- `sudo nano /etc/rancher/k3s/registries.yaml`

- `mirrors`の設定を編集し、必要なイメージリポジトリのアドレスを指定します。

  ```yaml
  mirrors:
    "container.ctf.example.com": # change this to your registry's domain
      endpoint:
        - "https://container.ctf.example.com" # change this to your registry's domain
  ```

- `sudo systemctl restart k3s`
