Docker + K3s 分离部署

实际上也可以单台服务器部署所有环境,但最好的就是K3s与GZCTF分离成两个服务器进行部署

本文章参考官方文档:https://docs.ctf.gzti.me/zh/quick-start

准备环境

接下来的教程均以 Ubuntu 22.04.3 (其他的发行版也可以)进行演示

VPS-1:GZCTF平台+Kuboard - 192.168.3.12

VPS-2:K3s集群环境 - 192.168.3.13

开始搭建

VPS-1 - 192.168.3.12

docker

安装 sudo apt install docker.io

测试 docker -v

出现以下版本号信息即为安装成功

VPS-2 - 192.168.3.13

K3s

k3s 是一个轻量级的 k8s 发行版,可以在单机和多机上快速部署 k8s 集群

官网文档地址:https://docs.k3s.io/zh

安装命令

1
2
3
curl -sfL https://get.k3s.io | sh -
# 检查就绪节点,大约需要30秒
sudo k3s kubectl get node

中国用户,可以使用以下方法加速安装:

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

多机安装和集群组建请参考 官方文档

测试 k3s -v

出现如下版本信息即为安装成功

docker-compose

下载最新版的docker-compose文件

1
sudo curl -L https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

如果出现以下错误则安装curl后再运行一次上面的代码

sudo apt-get install curl

添加可执行权限

sudo chmod +x /usr/local/bin/docker-compose

测试 docker-compose --version

出现如下版本信息即为安装成功

Kuboard可视化面板

此面板只是方便管理K3s集群,可以选择不装,不装请直接跳转到下面的配置文件步骤

在下面的配置中,第四行的端口示例3271要与第六行IP地址后的端口一致

1
2
3
4
5
6
7
8
9
10
docker run -d \
--restart=unless-stopped \
--name=kuboard \
-p 3271:80/tcp \
-p 10081:10081/tcp \
-e KUBOARD_ENDPOINT="http://192.168.3.13:3271" \
-e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
-v /root/kuboard-data:/data \
swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard:v3

docker创建完后,访问http://192.168.3.12:3271即可看到管理面板

默认账号:admin

默认密码:Kuboard123

如果是生产环境,登录后请及时更改密码

绑定集群

使用第二种方法

kubeconfig获取方法是在安装好K3s的机器上执行

cat /etc/rancher/k3s/k3s.yaml

然后把内容全部复制到图片上的kubeconfig

然后把ApiServer 地址改为192.168.3.13即可

填写配置文件

运行以下命令创建配置文件(配置文件的位置可以随意更改)

1
2
3
4
5
6
mkdir /GZCTF
cd /GZCTF
touch appsettings.json
touch docker-compose.yml
touch kube-config.yaml

appsettings.json

注:保存该配置文件前请把注释全部删除

更多配置请看官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
"AllowedHosts": "*",
"ConnectionStrings": {
// GZ数据库连接信息,通常情况下无需改动
"Database": "Host=db:5432;Database=gzctf;Username=postgres;Password=MCndCf26Ki4kp5eR"
},
"EmailConfig": {
"SendMailAddress": "", // 发件人邮箱地址(必填)
"UserName": "", // 服务器用户名(必填)
"Password": "", // 服务器密码(必填)
"Smtp": {
"Host": "", // 服务器地址(必填)
"Port": // 服务器端口(必填)
}
},
"XorKey": "", // 此处配置加密密钥,用于加密数据库中比赛的私钥信息,可为任意长度的任意字符串(必填)

// 此处配置容器后端,为比赛动态创建容器的必填项。
"ContainerProvider": {
"Type": "Kubernetes", // 容器后端类型,选Kubernetes
"PortMappingType": "Default", // 端口映射类型,可选 Default 或 PlatformProxy
"EnableTrafficCapture": false, // 是否开启流量捕获
"PublicEntry": "192.168.3.13", // 容器后端的公网地址,填写K3s的IP地址或域名(必填)
"DockerConfig": {
"SwarmMode": false,
"Uri": "unix:///var/run/docker.sock"
}
},
"RequestLogging": false, // 此处配置 Docker Registry 的用户名和密码,用于比赛动态创建容器时拉取镜像的验证,可选项
"DisableRateLimit": true, // 此处配置是否开启请求频率限制,若开启,将会根据预设规则限制每个 IP 和 API 的请求频率

// 此处配置 Docker Registry 的用户名和密码,用于比赛动态创建容器时拉取镜像的验证,可选项
"RegistryConfig": {
"UserName": "",
"Password": "",
"ServerAddress": ""
},
}

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
version: "3.0"
services:
gzctf:
https://api.xieweiling.top/blog/2024/9/26/image: gztime/gzctf:latest
restart: always
environment:
- "GZCTF_ADMIN_PASSWORD=Admin@5.2L9Q3" # Admin管理员密码(必填)
- "LC_ALL=zh_CN.UTF-8"
ports:
- "80:8080" # 对外端口号,前为GZ的外部端口(必填)
volumes:
- "./data/files:/app/files"
- "./appsettings.json:/app/appsettings.json:ro"
- "./kube-config.yaml:/app/kube-config.yaml:ro" # 这是k8s部署所必需的
# - "/var/run/docker.sock:/var/run/docker.sock" # 这是docker部署所必需的
depends_on:
- db

db:
https://api.xieweiling.top/blog/2024/9/26/image: postgres:alpine
restart: always
environment:
- "POSTGRES_PASSWORD=MCndCf26Ki4kp5eR"
volumes:
- "./data/db:/var/lib/postgresql/data"

kube-config.yaml

k3s 的连接配置文件位于 /etc/rancher/k3s/k3s.yaml,可以使用以下命令导出:

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

使用如下命令获取 k3s control-panel 所在机器的 IP:

sudo k3s kubectl cluster-info

若显示127.0.0.1则说明 k3s control-panel 就是当前的机器,请使用 ip a 查看当前机器的 IP

将上述输出的内容保存为 kube-config.yaml,并更改 server 字段为 k3s control-panel 所在机器的 IP,例如

1
2
3
4
5
6
7
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: # ...
server: https://192.168.3.13:6443 # 将IP更改为您的k3s控制面板的IP或域
name: default
# ...

最后一步

配置完成后输入在配置文件的目录下运行

docker-compose up -d

等程序创建好容器后

访问192.168.3.12即可

其他设置

更改 K3s 的容器数量限制

k3s 默认的容器数量限制为 110,这可能不适用于比赛中的大量小容器

因此可以根据需要更改 k3s 的容器数量限制

在 k3s control-panel 所在的机器上执行以下命令:

sudo nano /etc/rancher/k3s/kubelet.config

编辑如下设置中的 maxPods

1
2
3
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
maxPods: 500

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

编辑如下设置中的 ExecStart,指定kubelet-arg

1
2
3
ExecStart=/usr/local/bin/k3s \
server \
--kubelet-arg=config=/etc/rancher/k3s/kubelet.config

重启K3s即可

sudo systemctl daemon-reload

sudo systemctl restart k3s

添加容器镜像仓库

直接使用外部的容器镜像仓库无法直接在 k3s 中使用,需要在 k3s 中添加镜像仓库。

k3s control-panel 所在的机器上执行以下命令:

sudo vim /etc/rancher/k3s/registries.yaml

编辑如下设置中的 mirrors,指定你所需要的镜像仓库地址

1
2
3
4
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

重启K3s

sudo systemctl restart k3s

解决在docker中系统防火墙无法进行限制访问的问题

https://blog.csdn.net/qq_43580193/article/details/120222339

1
2
3
4
5
6
7
8
9
10
11
# 添加规则
vim /etc/docker/daemon.json

{
"experimental" : true,
"iptables": false
}

# 重启 docker
systemctl daemon-reload
systemctl restart docker

K3s卸载

运行以下命令即可一键删除K3s

sh /usr/local/bin/k3s-uninstall.sh

其他问题

如果K3s拉取镜像时出现以下问题

Failed to pull image "docker.io/kubernetesui/metrics-scraper:v1.0.8": failed to pull and unpack image "docker.io/kubernetesui/metrics-scraper:v1.0.8": failed to copy: httpReadSeeker: failed open: failed to do request: Get "https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/11/115053965e86b2df4d78af78d7951b8644839d20a03820c6df59a261103315f7/data?verify=1720885401-FQ2ec10z9ayDBBbvteS7LWUoZFY%3D": tls: failed to verify certificate: x509: certificate is valid for *.facebook.com, *.facebook.net, *.fbcdn.net, *.fbsbx.com, *.m.facebook.com, *.messenger.com, *.xx.fbcdn.net, *.xy.fbcdn.net, *.xz.fbcdn.net, facebook.com, messenger.com, not production.cloudflare.docker.com

很简单重启K3s就行了

重启命令:systemctl restart containerd

如果出现容器一开始启动成功,但是几秒后又出现容器未就绪的情况时

在GZ平台适当调整一下CPU限制、内存限制、存储限制即可

如果重启了GZ面板的服务后出现面版无法访问的问题

容器日志显示一直无法连接数据库

解决方法:

打开docker配置文件

把配置复制删除并保存,然后重启Docker服务,重启后GZ就能访问了

接着再把配置粘贴进去重启Docker服务,就能解决该问题