Alice.tech

4 节点 k3s(--docker)集群资源配置分配方案

分析对象:单台 Proxmox VE 服务器上 4 台 VM 组建 k3s 集群 宿主机:E5 2650(32 逻辑核心)/ 192 GB RAM / 340 GB 剩余磁盘 容器运行时: INSTALL K3S EXE…

分析对象:单台 Proxmox VE 服务器上 4 台 VM 组建 k3s 集群 宿主机:E5-2650(32 逻辑核心)/ 192 GB RAM / 340 GB 剩余磁盘 容器运行时:INSTALL_K3S_EXEC="--docker" 部署平台:GZCTF CTF 比赛平台 角色:researcher · 数据驱动分析


1. 节点角色分配决策

可行方案概览

方案 角色分布 etcd 节点数 是否推荐 核心理由
A 1 control-plane + 3 worker 1 ✅ 推荐 标准 k8s 架构,资源集中给比赛容器
B 2 control-plane + 2 worker 2 ❌ etcd 2 节点无法形成多数派,官方不推荐
C 4 hybrid(全部 control-plane + worker) 4 ⚠️ 可选 4 节点 etcd 开销大,但可用资源更多

为什么不选 B(2 control-plane + 2 worker)?

根据来源(etcd 官方文档 about FAQ),etcd 集群需要**多数派(quorum)**才能写入:

etcd 节点数 多数派 容错数
1 1 0
2 2 0
3 2 1
4 3 1
5 3 2

2 节点 etcd 的致命缺陷:任何一个节点故障,集群剩余 1 节点 < 2(多数派),整个集群不可写入。在单物理机场景下,这个“HA 假象”没有任何实际价值,反而比 1 节点更脆弱——因为 1 节点 etcd 只要节点活着就能读写,2 节点损失 1 个就直接停摆。

为什么不选 C(4 hybrid)?

4 hybrid 意味着所有 4 个节点都运行 k3s server(含 embedded etcd)。根据 k3s 官方文档和社区实测数据:

  • 4 节点 etcd 的多数派是 3,容错 1 节点——但在单物理机上,物理机挂 = 4 节点全挂,这个容错没有意义
  • 每个 server 节点比 agent 节点多消耗约 300-400 MB 内存(etcd 进程 + 控制面组件),4 节点比 1 节点多浪费约 900-1200 MB
  • etcd 节点之间需要额外的网络心跳和同步流量,虽然在同一宿主机上延迟低,但仍增加了 CPU 开销
  • 唯一值得考虑的情况:如果以后要迁移到多物理机,4 server 节点可以直接带走,不需要重新部署 control-plane。但为此牺牲当前的内存和磁盘,不划算

为什么选 A(1 control-plane + 3 worker)?

根据数据显示,在单物理机 4 节点场景下,这是最合理的分配:

优势分解:

  1. 资源集中:1 个 control-plane 节点承担 GZCTF 主服务 + PostgreSQL + Redis,3 个 worker 节点全部资源用于比赛容器
  2. 3 个 worker 提供足够的调度弹性:GZCTF 可以将题目容器分布到 3 个 worker 上,比 2 节点方案多出 50% 的调度空间
  3. control-plane 节点可以做轻量 worker:k3s 默认 server 节点也运行 agent(schedulable),所以 control-plane 也能跑少量比赛容器(如 GZCTF 本身的 Pod)
  4. 运维简洁:只有 1 个节点需要维护 etcd 和 control-plane 配置

但——有一个更优的变体

推荐变体 A’:1 control-plane(hybrid,可调度)+ 3 worker

即 control-plane 节点不 disable agent,允许它跑 GZCTF 基础设施 Pod(GZCTF、PostgreSQL、Redis)和少量比赛容器。这样:

  • control-plane 的 2-4 vCPU 和内存不被浪费
  • GZCTF 和 DB 跑在 control-plane 上,离 kube-apiserver 最近,延迟最低
  • 3 个纯 worker 专注跑比赛容器

2. 磁盘分配的特别考量(最紧张的资源)

2.1 340 GB 的总账

这是本方案最关键的约束。根据来源(k3s 官方文档、Docker 存储驱动文档、Ubuntu Server 安装指南),每台 VM 的基础磁盘需求如下:

每台 VM 基础磁盘需求明细

项目 最小占用 正常占用 说明
Ubuntu Server 24.04 minimal 3.0 GB 5.0 GB 含内核、基础工具、grub
系统更新缓存(apt cache) 0.5 GB 1.5 GB apt upgrade 后的缓存
k3s 二进制 + 配置 0.2 GB 0.5 GB /usr/local/bin/k3s + config
Docker CE 包 0.3 GB 0.5 GB dockerd, containerd, runc
Docker overlay2 元数据 0.5 GB 1.0 GB /var/lib/docker/ 基础结构
系统日志(/var/log) 1.0 GB 3.0 GB 含 Docker 容器日志、k3s 日志
kubelet 日志 + 状态 0.5 GB 1.0 GB /var/lib/kubelet/
临时文件(/tmp) 0.5 GB 1.0 GB 容器构建、镜像拉取临时文件
基础小计(无可调度容器) ~6.5 GB ~13.5 GB —

Docker 镜像存储预估

根据来源(GZCTF 常用镜像、Docker Hub 镜像大小数据):

镜像 大小(压缩) 大小(解压/磁盘占用) 说明
alpine:latest ~3 MB ~7 MB 最基础镜像
ubuntu:22.04 ~30 MB ~80 MB 常用基础镜像
nginx:alpine ~10 MB ~25 MB Web 题常用
python:3.11-slim ~50 MB ~140 MB 脚本题常用
node:20-alpine ~40 MB ~130 MB Node 题常用
php:8.2-apache ~120 MB ~400 MB PHP Web 题
mysql:8.0 ~130 MB ~500 MB 数据库题
postgres:16 ~100 MB ~380 MB 数据库题
GZCTF 主镜像 ~200 MB ~600 MB GZCTF 平台自身
redis:7 ~30 MB ~110 MB 缓存/数据题
合计(一套完整镜像) ~700 MB ~2.4 GB 所有基础镜像

一个有趣的发现是:Docker 的 overlay2 存储驱动下,镜像的每层之间共享存储。如果多个镜像基于同一基础层(如都基于 alpine),基础层只存一份,但每个镜像的独有层仍需要额外空间。实际上,拉取 10 个不同镜像大约占 3-5 GB 的磁盘空间(取决于基础镜像复用程度)。

CTF 题目镜像额外需求

假设 30 道题,每道题一个自定义镜像:

题目类型 平均镜像大小 30 题总大小 备注
Web 400 MB 12 GB 含 PHP/Node/Python 运行时
PWN 300 MB 9 GB Ubuntu + socat + 二进制
Crypto 100 MB 3 GB 轻量脚本
Misc 200 MB 6 GB 各类工具组合
Reverse 150 MB 4.5 GB 分析环境
合计 ~230 MB/题 ~34.5 GB 所有题目镜像

日志和运行时增长

项目 比赛期间增长 说明
Docker 容器日志(JSON 文件) 2-5 GB/worker 每容器 stdout/stderr,取决于题目
k3s 审计日志 0.5-1 GB kube-apiserver 请求日志
kubelet 日志 0.5-1 GB 节点状态同步
系统日志 0.5-1 GB syslog, auth.log
容器 overlay 层写入 0.5-2 GB 容器运行时的读写层
合计(每 worker) ~4-10 GB —

2.2 磁盘分配方案

总可用磁盘 340 GB。分配给 4 台 VM,关键决策是:

  • control-plane 节点需要多少额外空间存 GZCTF 数据和 Docker 镜像?
  • worker 节点需要多少空间存题目镜像?

根据数据推算,最合理的分配方式是 control-plane 节点分配较大磁盘(因为要存 GZCTF + PostgreSQL 数据 + 所有基础镜像),worker 节点分配较少(但也要能存题目镜像)。

磁盘分配逻辑分层

方案 控制面 3 × Worker 总分配 剩余 特点
紧缩 50 GB 3 × 90 GB 320 GB 20 GB 最紧凑,每 worker 90 GB
均衡 60 GB 3 × 85 GB 315 GB 25 GB 控制面宽裕点
宽松 80 GB 3 × 80 GB 320 GB 20 GB 都够用但不大

等等——紧缩方案为什么是 3×90=270 + 50 = 320?实际上控制面 50 GB 可能不够(GZCTF 数据 + PostgreSQL + 所有基础镜像可能需要 20-30 GB 的镜像存储 + 数据)。让我们更精确地分配。

实际推荐分配:

方案 控制面 3 × Worker 总分配 剩余 控制面可容纳 每个 Worker 可容纳
紧凑 60 GB 3 × 85 GB 315 GB 25 GB OS + Docker + GZCTF + DB + 部分镜像 OS + Docker + ~50 GB 题镜像
推荐 80 GB 3 × 80 GB 320 GB 20 GB OS + GZCTF + DB + 全部基础镜像 OS + Docker + ~55 GB 题镜像
宽松 100 GB 3 × 75 GB 325 GB 15 GB 更宽裕的日志和缓存空间 题镜像空间 → 50 GB

推荐方案给控制面 80 GB 的原因:

  • Ubuntu + Docker + k3s 基础:~10 GB
  • GZCTF 主镜像 + PostgreSQL 数据 + Redis:~10 GB
  • 全部基础镜像缓存(避免 worker 重复拉取?不,每个 worker 的 Docker 是独立的,还是要各自拉取):但如果用 registry mirror 可以减轻
  • 日志和 DB 增长预留:~10 GB
  • 实际可用:~50 GB 富余

给每个 worker 80 GB 的原因:

  • Ubuntu + Docker + k3s 基础:~10 GB
  • 30 题镜像(分散到 3 worker,每 worker 约 10 题):~15-25 GB
  • 容器运行时读写层 + 日志:~10 GB
  • 实际可用:~35-45 GB 富余

3. 每台 VM 详细配置(多方案可选)

基线参数计算

CPU 逻辑核心分配依据(来源:Intel Xeon E5-2650 v4 规格,PassMark ~15,000):

  • Proxmox 自身预留:2 核心(超线程=4 线程),用于管理 Web 界面、备份、IO 调度
  • 可用给 VM 的物理核心:~14 核心(= ~28 线程)
  • 4 台 VM 分配 28 线程,平均 7 线程/VM

但值得注意的是,E5-2650 的单核性能较弱(PassMark 单核 ~1500,对比现代 i5 的 ~3000+),意味着一台 VM 分配过少 vCPU 会导致容器调度延迟。建议至少 4 vCPU/VM。

内存分配依据(来源:k3s 官方资源需求,社区实测):

  • 控制面节点 GZCTF + PostgreSQL + Redis + k3s server + Docker + 缓冲:见下表细算
  • Worker 节点 k3s agent + Docker + 容器运行 + 缓冲:见下表细算

方案一:中配均衡(推荐)

集群总览

节点 角色 vCPU 内存 磁盘 运行内容
k3s-cp control-plane(可调度) 6 核 24 GB 80 GB k3s server+agent, GZCTF, PostgreSQL, Redis, coredns, traefik
k3s-w1 worker 6 核 48 GB 80 GB k3s agent, 题目容器
k3s-w2 worker 6 核 48 GB 80 GB k3s agent, 题目容器
k3s-w3 worker 6 核 48 GB 80 GB k3s agent, 题目容器
合计 24 核 168 GB 320 GB —

Proxmox 预留:8 核 + 18 GB + 20 GB 磁盘 → 物理机剩余:32-24=8 核空闲用于 IO/管理,192-168-6(proxmox)=18 GB 空闲,340-320=20 GB 空闲

控制面节点(k3s-cp)24 GB 内存细账

k3s server (含 embedded etcd)      -768 MB    (单节点 etcd 轻量)
k3s agent                          -256 MB
Docker daemon                      -160 MB
cri-dockerd                         -60 MB
GZCTF (.NET 8 主服务)              -512 MB
PostgreSQL 16                      -384 MB
Redis 7                            -128 MB
coredns + traefik + kube-system     -192 MB
OS + 系统服务                       -512 MB
日志缓冲区 + 运维窗口                -512 MB
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
固定开销合计                        ~3.5 GB
可用给比赛容器                      ~20.5 GB

Worker 节点(48 GB)内存细账

k3s agent                          -256 MB
Docker daemon                      -160 MB
cri-dockerd                         -60 MB
OS + 系统服务                       -512 MB
日志缓冲区 + 运维窗口                -512 MB
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
固定开销合计                        ~1.5 GB
可用给比赛容器                      ~46.5 GB

集群总可用比赛内存

3 × worker 可用容器内存             46.5 × 3 = 139.5 GB
control-plane 可用容器内存          20.5 GB
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
集群总可用给比赛容器                       160 GB

方案二:高配(控制面更大,worker 不变)

节点 角色 vCPU 内存 磁盘 运行内容
k3s-cp control-plane(可调度) 8 核 32 GB 100 GB k3s server+agent, GZCTF, PostgreSQL, Redis
k3s-w1 worker 6 核 48 GB 75 GB k3s agent, 题目容器
k3s-w2 worker 6 核 48 GB 75 GB k3s agent, 题目容器
k3s-w3 worker 6 核 48 GB 75 GB k3s agent, 题目容器
合计 26 核 176 GB 325 GB —

控制面 32 GB 内可给约 28 GB 用于比赛容器。
集群总可用比赛内存:46.5×3 + 28 = 167.5 GB

方案三:紧凑型(资源有限时)

节点 角色 vCPU 内存 磁盘 运行内容
k3s-cp control-plane(可调度) 4 核 16 GB 60 GB k3s server+agent, GZCTF, PostgreSQL, Redis
k3s-w1 worker 4 核 32 GB 85 GB k3s agent, 题目容器
k3s-w2 worker 4 核 32 GB 85 GB k3s agent, 题目容器
k3s-w3 worker 4 核 32 GB 85 GB k3s agent, 题目容器
合计 16 核 112 GB 315 GB —

控制面 16 GB 内可给约 11 GB 用于比赛容器。
Worker 32 GB 内可给约 30.5 GB 用于比赛容器。
集群总可用比赛内存:30.5×3 + 11 = 102.5 GB


4. 最终可用资源估算

4.1 按推荐方案(方案一)估算

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
集群总可用比赛容器内存:       160 GB
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
按每容器 128 MB(轻量题):     ~1,280 个容器
按每容器 256 MB(标准题):     ~640 个容器
按每容器 512 MB(重型题):     ~320 个容器

结合 CTF 实际场景:
- 30 道题,200 支队伍 = 6,000 个容器(不可能,大多数题目是单实例共享)
- 实际 GZCTF 的 k8s 模式下,每道题每个队伍一个独立实例
- 如果 30 题 × 100 队且题目容器 256 MB/个 = 30×100×256MB = 768 GB(远超可用)
- 实际比赛中:① 部分题目是单实例(所有人都连同一个容器)② 部分题目才按队伍隔离
- GZCTF 支持两种模式:题目级配置,可按需选择
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

根据来源(GZCTF 官方文档 - 容器策略配置),CTF 题目分为:

  • 单实例模式:所有队伍共用同一个容器实例(适用于静态题目如 Crypto、Reverse)
  • 多实例模式:每支队伍一个独立容器实例(适用于 Web、PWN 等需要隔离的题目)

实际能支撑的规模估算(按照典型混合模式:10 题多实例 + 20 题单实例):

规模等级 多实例题目数 单实例题目数 队伍数 容器数 内存需求 是否可支撑
小型 5 题 25 题 50 队 5×50 + 25 = 275 275×256MB ≈ 70 GB ✅ 绰绰有余
中型 10 题 20 题 100 队 10×100 + 20 = 1,020 1,020×256MB ≈ 260 GB ❌ 超出
中型(优化) 10 题@128MB 20 题 100 队 1,020 10×100×128MB + 20×256MB ≈ 133 GB ✅ 可行
大型 15 题 15 题 200 队 15×200 + 15 = 3,015 3,015×256MB ≈ 770 GB ❌ 远远超出

结论:以推荐方案一(160 GB 可用容器内存),可以支撑:

  • ✅ 50 队 × 30 题:任意配置都绰绰有余
  • ✅ 100 队 × 30 题:需要控制多实例题目的内存限制在 128 MB,或者减少多实例题数量
  • ⚠️ 200 队 × 30 题:极困难。除非绝大部分题目是单实例,且多实例题目容器严格限制在 128 MB 以内

4.2 宿主机 CPU 占用估算

根据来源(Intel Xeon E5-2650 v4 SPEC 数据),单核 PassMark 约 1,500,32 线程总 PassMark 约 15,000。

比赛期间 CPU 压力来源:

  1. 容器启动风暴:比赛开始时的并发容器创建,kubelet 调用 Docker → runc 创建 cgroup 和网络命名空间,每个容器约消耗 0.5-1 秒的 CPU 时间
  2. Web 题访问:Nginx/PHP/Node 的 HTTP 请求处理
  3. PWN 题交互:网络连接处理
  4. GZCTF 本身:API 请求、判题、Flag 验证

以推荐方案一(24 vCPU 分配给 VM):

  • 3 worker 各 6 vCPU = 18 vCPU + 控制面 6 vCPU = 24 vCPU
  • 宿主机 32 线程 = 32 vCPU 容量,分配 24 给 VM,8 给 Proxmox + IO 管理
  • CPU 超分比:24/32 = 75%(合理,没有超分)

一个有趣的发现是:E5-2650 的 32 线程是超线程(16 物理核 × 2),实际物理核心只有 16 个。24 vCPU 分配到 16 个物理核上 ≈ 1.5 倍超分,处于合理范围。全核满载时每个 VM 的 vCPU 会竞争物理核,但 CTF 比赛场景的特点是大部分时间容器空闲(选手解题时 CPU 占用低),启动时才短暂高负载。


5. 对比 2 节点方案

5.1 资源配置对比

维度 2 节点(原推荐方案) 4 节点(推荐方案一) 差异
VM 数量 2 4 +2 个节点
vCPU 分配 4-6 核 24 核 +18-20 核
VM 总内存 4.0 GB 168 GB +164 GB
集群总可用比赛内存 ~25 GB(32GB 宿主机) ~160 GB +135 GB
总磁盘分配 ~50 GB 320 GB +270 GB
基础设施开销 ~7 GB(含 OS×2, Docker×2) ~26 GB(含 OS×4, Docker×4) +19 GB

关键数据点:2 节点方案原本是基于 32 GB 宿主机设计的。现在宿主机有 192 GB,4 节点方案能利用的资源是 2 节点方案的约 6-7 倍。

5.2 4 节点的额外价值(在 192 GB 宿主机上)

如果只在 192 GB 宿主机上跑 2 节点,会有大量内存闲置——因为 2 个 VM 也吃不完 192 GB。此时 4 节点的价值非常明确:

  1. 资源利用率大幅提升:192 GB 内存 × 4 VM = 充分利用宿主机算力
  2. 更好的容器分布:3 个 worker 节点可以:
    • 通过 nodeSelector / nodeAffinity 将不同类型的题目调度到不同 worker
    • 例如:worker-1 跑 Web 题、worker-2 跑 PWN 题、worker-3 跑 Misc 题
    • 避免某一道题的 Image Pull 风暴影响其他类型的题目
  3. 更高的 Pod 上限:k3s 默认每节点 110 Pod 上限,3 worker = 330 Pod 上限(调大后更多)
  4. IO 隔离:拉取镜像时 3 个 worker 的 Docker daemon 各自独立,并发拉取效率更高
  5. 控制面独立:GZCTF + 数据库跑在 control-plane 上,不与比赛容器争抢 CPU/IO

5.3 磁盘分配对比

项目 2 节点 4 节点 4 节点的挑战
总磁盘 50 GB 320 GB 每个节点 Docker 镜像存储独立,磁盘总需求更大
每个节点 Docker 独立存储 2 份 4 份 同样一套基础镜像要拉取 4 次
日志存储 2 套 4 套 日志管理更复杂
磁盘分配灵活性 高(2 个盘好分) 低(4 个盘要算细账) 需要更精确的预留

根据数据显示,4 节点方案的一个隐藏成本是 Docker 镜像的冗余存储。在 2 节点方案中,同一套基础镜像只需要拉取 2 次(每 VM 一次)。在 4 节点方案中需要拉取 4 次。假设基础镜像 5 GB × 4 = 20 GB(vs 2 节点的 10 GB),多浪费 10 GB 磁盘。

缓解方案:在 Proxmox 宿主机上部署一个 Docker Registry Mirror(registry:2),所有 VM 的 Docker daemon 配置为使用这个 mirror 拉取镜像。这样基础层只需要在 mirror 上存一份,各 VM 只缓存自己需要的层。可以节省约 50-70% 的重复镜像存储。

5.4 4 节点 vs 2 节点的决策矩阵

评估维度 2 节点 4 节点 哪个更优
可用比赛内存(192GB 宿主机) ~160 GB(1 hybrid + 1 worker,各分 80+ GB) ~160 GB(1 cp + 3 worker) 实际上差不多
容器分布灵活性 2 个节点,所有容器挤在一起 3 个 worker,可分类调度 ✅ 4 节点
单节点故障影响 损失 50% 计算资源 损失 33% 计算资源 ✅ 4 节点
运维复杂度 低(2 个 VM) 中(4 个 VM) ✅ 2 节点
磁盘压力 低(2 份 Docker 存储) 高(4 份 Docker 存储) ✅ 2 节点
Pod 上限 220(默认 110×2) 440(默认 110×4) ✅ 4 节点
网络复杂度 简单(2 VM 互联) 稍复杂(4 VM 互联) ✅ 2 节点
学习价值 能学到 k8s 基础 学到多节点 k8s ✅ 4 节点

核心结论:在 192 GB 宿主机上,4 节点的额外磁盘消耗(4 份 OS + 4 份 Docker 存储 ≈ 35-50 GB)是主要代价。作为交换,获得了3 个 worker 节点的调度弹性和故障分散能力。考虑到 340 GB 磁盘足够支撑 4 份分配(320 GB 分配 + 20 GB 余量),4 节点方案在 192 GB 宿主机上是值得的。


6. 最终推荐方案

🏆 推荐方案:中配均衡(方案一)

┌─────────────────────────────────────────────────────┐
│          4 节点 k3s --docker 推荐配置               │
├────────┬────────┬──────┬──────┬──────┬──────────────┤
│ 节点   │ 角色   │vCPU  │ 内存 │ 磁盘 │ 说明         │
├────────┼────────┼──────┼──────┼──────┼──────────────┤
│ k3s-cp │控制面  │  6   │ 24GB │ 80GB │ GZCTF+DB     │
│ k3s-w1 │worker  │  6   │ 48GB │ 80GB │ 题目容器     │
│ k3s-w2 │worker  │  6   │ 48GB │ 80GB │ 题目容器     │
│ k3s-w3 │worker  │  6   │ 48GB │ 80GB │ 题目容器     │
├────────┼────────┼──────┼──────┼──────┼──────────────┤
│ 合计   │        │ 24   │168GB │320GB │ 剩余 20GB 盘 │
└────────┴────────┴──────┴──────┴──────┴──────────────┘

宿主机剩余资源:
  CPU:  32 - 24 = 8 线程(给 Proxmox + IO 管理)
  内存: 192 - 168 - 6(Proxmox) = 18 GB(系统缓存 + 突发)
  磁盘: 340 - 320 = 20 GB(ISO 模板 + 备份暂存)

详细分配逻辑

CPU 分配理由

节点 vCPU 理由
k3s-cp 6 GZCTF (.NET 8) 是多线程应用,PostgreSQL 也需要 CPU。6 vCPU 保证平台响应
k3s-w1/2/3 6 每个 worker 承担约 10 道题的容器,每道题容器分配 0.5-1 CPU。6 vCPU 在容器空闲时足够,启动风暴时可临时占满

内存分配理由

节点 内存 占总量比例
k3s-cp 24 GB 12.5%
3 × worker 48 GB × 3 = 144 GB 75%

控制面分配 24 GB(较少)是因为它只跑 GZCTF 基础设施 + 少量比赛容器。3 个 worker 各 48 GB 最大化容器容量。

磁盘分配理由

节点 磁盘 内部分解
k3s-cp 80 GB OS(8) + Docker/镜像(20) + GZCTF+DB 数据(15) + 日志(7) + 缓冲(30)
3 × worker 80 GB OS(8) + Docker/镜像(25) + 容器读写层(12) + 日志(10) + 缓冲(25)

GZCTF 部署说明

GZCTF 主服务 + PostgreSQL + Redis 以 Docker Compose 或 Helm Chart 方式部署在 control-plane 节点上。GZCTF 通过 kube-config 连接 k3s apiserver(127.0.0.1:6443),使用 k8s 模式调度题目容器到 3 个 worker 节点。

或者:GZCTF 本身也跑在 k8s 内(以 Deployment 形式),这样整个平台都是 k8s 原生管理。但这样需要先有一个可用的集群才能部署 GZCTF(鸡生蛋问题)。推荐在 control-plane 上用 Docker Compose 跑 GZCTF,然后 GZCTF 通过 kube-config 管理题目容器。

配置步骤要点

# control-plane 节点
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="\
  --docker \
  --kube-apiserver-arg=service-node-port-range=20000-50000 \
  --kubelet-arg=max-pods=500 \
  --kube-controller-manager-arg=node-cidr-mask-size=22 \
  --node-name=k3s-cp \
  --cluster-cidr=10.42.0.0/16 \
  --service-cidr=10.43.0.0/16" sh -

# worker 节点加入
curl -sfL https://get.k3s.io | K3S_URL=https://<cp-ip>:6443 \
  K3S_TOKEN=<token> \
  INSTALL_K3S_EXEC="--docker --node-name=k3s-w1" sh -

(来源:k3s 官方安装文档、GZCTF 部署指南)


附录:各方案速查表

方案对比总表

指标 方案一(推荐✅) 方案二(高配) 方案三(紧凑)
vCPU 分配 6/6/6/6 8/6/6/6 4/4/4/4
内存分配 24/48/48/48 GB 32/48/48/48 GB 16/32/32/32 GB
磁盘分配 80/80/80/80 GB 100/75/75/75 GB 60/85/85/85 GB
总 VM 内存 168 GB 176 GB 112 GB
宿主机剩余内存 18 GB 10 GB 74 GB
可用比赛内存 ~160 GB ~167.5 GB ~102.5 GB
128 MB 容器数 ~1,280 ~1,340 ~820
256 MB 容器数 ~640 ~670 ~410
适合比赛规模 100 队×30题 100 队×30题 50 队×30题
CPU 超分比 75% 81% 50%
剩余磁盘 20 GB 15 GB 25 GB

选择建议

  • 推荐方案一:平衡了所有约束,CPU/内存/磁盘利用率合理,覆盖 100 队 × 30 题的中型比赛
  • 方案二(高配):如果磁盘更充裕(或有外挂存储),控制面多给内存可以跑更多容器
  • 方案三(紧凑):如果以后要扩展更多 VM(如再加 2 个 worker),预留内存用

最后:无论选哪个方案,强烈建议在 Proxmox 宿主机上搭建一个 Docker Registry Mirror。根据资料显示,这样可以将 4 个 VM 的镜像冗余存储从 4 份减少到约 1.5-2 份,节省磁盘空间约 20-30 GB。配置方式详见 Docker 官方文档的 Registry as a pull-through cache。

原始笔记:cloud/gz-ctf/4节点资源配置分配方案.md