10 KiB
01-07-双控制节点HA(安装与准备)
TL;DR
- 自动化验收(基线):
./ansible/bin/verify.sh run 01-07(只做集群可达性基线;HA 加入/切换需按本文手工演练) - 你需要准备:第二个 server、外部 datastore、面向
6443的负载均衡(双主控硬前提);**仅两台主控、不想单独跑 HAProxy/nginx 时,优先 kube-vip(L2/ARP VIP,见下节))、维护窗口与备份 - 成功判据:能按本文完成外部 datastore 与 LB 的准备清单;并在
03-08中完成加入/切换演练 - 失败排障:见本文「排障」小节(datastore/LB/tls-san/6443)
本文只讲双控制节点 HA 的安装前准备与基础环境搭建。 具体集群参数切换、server 加入与迁移步骤见
03-08-k3s-ha-集群配置与切换.md。
前置条件
- 已完成
01-01-k3s-控制节点含traefik.md - 已完成
01-02-k3s-工作节点.md - 当前集群运行稳定,可执行维护窗口
目标与边界
- 目标:控制平面单点故障时仍可管理集群
- 边界:家庭网关(如 OpenWrt)可能仍是整体单点
双主控与负载均衡
双主控 = 要对 Kubernetes API 做负载均衡。 至少一个 稳定对外的入口地址(或域名),其背后把 6443 流量落到多个 k3s server 上(多活分摊或主备切换均可),这样 kubelet、kubectl、K3S_URL 与证书 --tls-san 才能始终指向同一逻辑端点,控制面才算 HA。
HAProxy 不是唯一选项,但「LB 这一层」不能省。 常见实现:
| 做法 | 说明 |
|---|---|
| HAProxy / nginx stream 等 | 典型 四层 LB:TCP 轮询/最少连接等到各 server 的 6443 |
| 云厂商 / 硬件 LB | 托管型四层 LB,同上 |
| kube-vip、Keepalived + VIP | 常做成 apiserver VIP(对外仍是一个 IP,背后与多 master 协同;语义上仍是「单入口 + 高可用后端」) |
与 01-06-openwrt-haproxy.md 的区别:01-06 的 HAProxy 面向 HTTP/HTTPS(80/443)→ Traefik 应用入口;01-07 / 03-08 要解决的是 API Server(6443)的负载均衡。可在同一台 OpenWrt 上同时部署,但须 两套监听与后端,不要与 01-06 的 18080/18443 配置混用。
推荐:只有两台主控、不用独立 HAProxy / nginx
目标:不增加专门跑 HAProxy、nginx stream 的第四台机器,只在 两个 k3s server 节点上解决「对外一个稳定 6443 地址」。
首选 kube-vip(Layer 2 / ARP 模式,Control Plane VIP)
| 项 | 说明 |
|---|---|
| 做什么 | 在每个主控节点上跑 kube-vip(常见为 static pod 或与 k3s 集成的部署方式),在同网段申请一个 VIP(如 192.168.2.60);VIP 随节点存活 漂移,客户端始终访问 https://<VIP>:6443。 |
| 为何适合双主控 | 不依赖外部 HAProxy/nginx VM;组件只落在主控上,与「仅两台 server」拓扑一致。 |
| 网络前提 | 两主控与 VIP 须在 同一二层广播域(家庭局域网通常满足);VIP 需在网段内 未被占用。 |
| 与「多活轮询」 | 常见是 主备式 VIP(同一时刻由一台承接 6443),故障后漂到另一台;对双主控 HA 足够。若要 多活同时分摊 API 连接,才更偏向独立四层 LB。 |
| k3s 侧 | --tls-san / 证书须包含 该 VIP(及若使用则包含域名);K3S_URL、kubeconfig 的 server 地址指向 VIP:6443。具体安装与清单以官方与 03-08 演练为准。 |
备选(仍无 HAProxy/nginx):两节点 Keepalived + VIP,自行维护 vrrp 与脚本,语义与 kube-vip 类似,集成度略低。
云上:若无 L2 条件,可改用 托管四层 LB 指到各主控 6443(仍属负载均衡,只是不在你自己机器上跑进程)。
安装准备清单
- 新增第二个 server 节点(示例
192.168.2.63) - 准备外部数据存储(MySQL/PostgreSQL/etcd)
- 准备
6443负载均衡:仅双主控、无独立 LB 机器时优先 kube-vip(L2 VIP);否则可选 HAProxy、nginx stream、云 LB 等 - 备份现有 token 与关键配置
免费 PostgreSQL(实验室推荐)
k3s 的外部 datastore 只需 兼容的 PostgreSQL;PostgreSQL 本体开源(PostgreSQL License),无商业版授权问题,下列均为 $0 落地方式:
| 方式 | 适合场景 | 说明 |
|---|---|---|
| 发行版软件包 | 有一台 独立于 k3s 控制面 的 Linux(如工作机、ARM 小主机、虚拟机) | Fedora/RHEL:dnf install postgresql-server 后 postgresql-setup --initdb、systemctl enable --now postgresql;Debian/Ubuntu:apt install postgresql。建库 k3s、用户与密码,在 pg_hba.conf 放行 k3s server 网段。 |
| 官方容器镜像 postgres | 想快速起实例、少动系统包 | docker / podman 一行起库,例如:podman run -d --name k3s-pg -e POSTGRES_USER=k3s -e POSTGRES_PASSWORD=strong-password -e POSTGRES_DB=k3s -p 5432:5432 docker.io/library/postgres:16(版本号可按需调整)。数据卷请挂到持久目录。 |
| 托管免费档(容量/用量有限制) | 不想自建、可接受 公网 与厂商条款 | 常见:Neon(Serverless Postgres,免费档对 存储、分支、计算时长 等有限额,适合轻量/实验);Supabase(免费档含托管 Postgres,数据库容量、API 调用、带宽 等受限)。另有各云「试用/免费层」Postgres,均以 官网当期配额 为准。k3s 连接串一般需 sslmode=require(或厂商文档要求);家庭实验室须保证各 k3s server 能访问云库主机(出口、防火墙、TLS)。仅免费档不宜当生产唯一 datastore(易触顶、休眠策略、合规以厂商为准)。 |
注意:datastore 建议与 两个 k3s server 网络互通、且 不要 只跑在「即将整体下线的那一台」唯一节点上,否则 datastore 单点与迁移成本更高。
双控 + datastore 还能不能「数据库集群」?
可以。 双主控解决的是 Kubernetes API(6443) 高可用;外部 PostgreSQL 这一层同样可以做成 高可用/集群,与双控 不冲突。
- k3s 侧:
--datastore-endpoint里填的仍是 一个 连接目标(host多为 VIP、LB 虚拟地址、托管库提供的单一 endpoint、或始终解析到当前主的 DNS)。k3s 只按 PostgreSQL 协议访问,不关心背后是单进程还是多节点。 - 数据库侧:常见做法包括 云托管多可用区 Postgres(RDS、Cloud SQL、Aurora 兼容端等)、Patroni + etcd/Consul、repmgr 等;由它们负责 主备、故障转移;对 k3s 必须保证故障转移后 仍连到可写主库(不要把 endpoint 指到 只读副本)。
- 取舍:PG 集群能消掉 datastore 单点,但 运维复杂度明显高于「单实例 Postgres」;家庭实验室可先单库跑通双控,再按需上 PG HA。
外部 datastore 与 k3s server 最小示例
以下只给出一个“最小可参考”的 PostgreSQL + k3s server 参数示意,具体地址/账号请按你自己的环境调整:
- 若采用 01-01 的数据盘方案:在 server 参数中增加
--data-dir=/storage,与首节点一致(第二个 server 安装时同样需要)。
# 假设外部 PostgreSQL 已创建数据库与账号:
# host=192.168.2.50 dbname=k3s user=k3s password=strong-password
# 在首个 server(例如 192.168.2.61)上,默认数据目录:
sudo k3s server \
--datastore-endpoint="postgres://k3s:strong-password@192.168.2.50:5432/k3s?sslmode=disable" \
--tls-san 192.168.2.61 \
--tls-san 192.168.2.62 \
--tls-san 192.168.2.63 \
--tls-san 192.168.2.60 # 这里示例为 LB IP
# 若使用数据盘方案,增加 --data-dir=/storage,例如:
# sudo k3s server --data-dir=/storage \
# --datastore-endpoint="postgres://..." --tls-san ...
说明:上面的命令仅作为参数示意,实际部署时建议改用 systemd unit 或官方安装脚本的额外参数(
INSTALL_K3S_EXEC=...),并结合03-08-k3s-ha-集群配置与切换.md中的步骤执行。
从现有 worker 升级为第二控制节点(推荐路径)
在家庭实验室环境中,第二个控制节点通常可以直接复用一台已有的 worker 节点。整体思路是:
- 确认 worker 节点健康:
- 已按
01-02-k3s-工作节点.md正常加入集群; - 无关键 Pod 仅运行在该节点(可先用
kubectl drain或手动迁移工作负载)。
- 已按
- 在
01-07阶段完成外部 datastore 与 LB 准备:- 不要立即改动现有 server/worker 的 systemd 配置,只确保 datastore/LB 均已就绪。
- 在
03-08中按步骤将该 worker 替换为 server:- 停止该节点上的
k3s-agent服务(或执行官方卸载脚本); - 使用与首个 server 相同的 token/datastore/LB 地址重新以
server角色安装 k3s; - 最终形成“2 个 server + 若干 worker”的目标拓扑。
- 停止该节点上的
具体切换命令与顺序详见:
03-08-k3s-ha-集群配置与切换.md中的操作步骤。
基础验证
kubectl get nodes -o wide
kubectl get pods -A
风险提示
- 这是高级改造,建议在业务稳定后执行
- 执行前务必做完整备份
下一步
03-08-k3s-ha-集群配置与切换.md:加入第二个 server、切换与演练
排障
- LB 6443 不通:先在客户端
curl -k https://<lb_ip>:6443/ping;再在各 server 检查监听与防火墙放行。 - 加入第二个 server 后 kubeconfig 指向错误地址:确认
--tls-san包含 LB IP/域名与各 server IP,并更新 kubeconfig server 地址。 - 外部 datastore 连接失败:检查连接串、网络 ACL、防火墙、账号权限;在 server 上用
psql/mysql先手工连通再跑 k3s 参数。