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

# 使用 Docker 和 K8s

本文中以轻量化部署的 K3s 为例，若您已经部署了 K8s 集群，可以参考本文后续配置进行类似的设置。

:::danger

**本篇教程请务必全部阅读后再进行操作，否则可能导致部署结果达不到预期。**

:::

## 安装 Docker

你可以在 [Docker 官网](https://docs.docker.com/engine/install/) 找到相关的安装说明，并使用 [快速上手](/zh/guide/start/quick-start.md) 中的基本配置将 GZCTF 运行起来。

## 安装 k3s

k3s 是一个轻量级的 k8s 发行版，可以在单机和多机上快速部署 k8s 集群。官网文档地址：[https://docs.k3s.io/zh](https://docs.k3s.io/zh)

:::warning 如果你只有一台机器？

如果你只有一台机器，我们强烈建议你使用其他的方式进行部署：

- 对于**小于 200 支队伍、30 道题目的私有内网**比赛，可以直接使用 Docker 部署，无需使用 k8s。
- 对于**公开或规模更大的比赛**，强烈建议使用 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"
```

**上述配置项在安装后无法轻易更改。** 推荐将 `node-cidr-mask-size` 设置为 `/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/zh/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`）会为单节点分配过大的地址块，降低集群横向扩展工作节点的能力。

## 添加容器镜像仓库

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`
