Files
Deploy-Laboratory/docs/01-07-双控制节点ha.md
2026-03-29 09:08:01 +08:00

10 KiB
Raw Permalink Blame History

01-07-双控制节点HA安装与准备

TL;DR

  • 自动化验收(基线)./ansible/bin/verify.sh run 01-07只做集群可达性基线HA 加入/切换需按本文手工演练)
  • 你需要准备:第二个 server、外部 datastore、面向 6443 的负载均衡(双主控硬前提);**仅两台主控、不想单独跑 HAProxy/nginx 时,优先 kube-vipL2/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 典型 四层 LBTCP 轮询/最少连接等到各 server 的 6443
云厂商 / 硬件 LB 托管型四层 LB同上
kube-vip、Keepalived + VIP 常做成 apiserver VIP(对外仍是一个 IP背后与多 master 协同;语义上仍是「单入口 + 高可用后端」)

01-06-openwrt-haproxy.md 的区别:01-06 的 HAProxy 面向 HTTP/HTTPS80/443→ Traefik 应用入口01-07 / 03-08 要解决的是 API Server6443的负载均衡。可在同一台 OpenWrt 上同时部署,但须 两套监听与后端,不要与 01-06 的 18080/18443 配置混用。

推荐:只有两台主控、不用独立 HAProxy / nginx

目标:不增加专门跑 HAProxy、nginx stream 的第四台机器,只在 两个 k3s server 节点上解决「对外一个稳定 6443 地址」。

首选 kube-vipLayer 2 / ARP 模式Control Plane VIP

说明
做什么 每个主控节点上跑 kube-vip常见为 static pod 或与 k3s 集成的部署方式),在同网段申请一个 VIP(如 192.168.2.60VIP 随节点存活 漂移,客户端始终访问 https://<VIP>:6443
为何适合双主控 不依赖外部 HAProxy/nginx VM组件只落在主控上与「仅两台 server」拓扑一致。
网络前提 两主控与 VIP 须在 同一二层广播域家庭局域网通常满足VIP 需在网段内 未被占用
与「多活轮询」 常见是 主备式 VIP(同一时刻由一台承接 6443),故障后漂到另一台;对双主控 HA 足够。若要 多活同时分摊 API 连接,才更偏向独立四层 LB。
k3s 侧 --tls-san / 证书须包含 该 VIP(及若使用则包含域名);K3S_URLkubeconfig 的 server 地址指向 VIP:6443。具体安装与清单以官方与 03-08 演练为准。

备选(仍无 HAProxy/nginx:两节点 Keepalived + VIP,自行维护 vrrp 与脚本,语义与 kube-vip 类似,集成度略低。

云上:若无 L2 条件,可改用 托管四层 LB 指到各主控 6443(仍属负载均衡,只是不在你自己机器上跑进程)。

安装准备清单

  1. 新增第二个 server 节点(示例 192.168.2.63
  2. 准备外部数据存储MySQL/PostgreSQL/etcd
  3. 准备 6443 负载均衡仅双主控、无独立 LB 机器时优先 kube-vipL2 VIP;否则可选 HAProxy、nginx stream、云 LB 等
  4. 备份现有 token 与关键配置

免费 PostgreSQL实验室推荐

k3s 的外部 datastore 只需 兼容的 PostgreSQLPostgreSQL 本体开源PostgreSQL License),无商业版授权问题,下列均为 $0 落地方式:

方式 适合场景 说明
发行版软件包 有一台 独立于 k3s 控制面 的 Linux如工作机、ARM 小主机、虚拟机) Fedora/RHELdnf install postgresql-serverpostgresql-setup --initdbsystemctl enable --now postgresqlDebian/Ubuntuapt 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(版本号可按需调整)。数据卷请挂到持久目录。
托管免费档(容量/用量有限制) 不想自建、可接受 公网 与厂商条款 常见:NeonServerless Postgres免费档对 存储、分支、计算时长 等有限额,适合轻量/实验);Supabase(免费档含托管 Postgres数据库容量、API 调用、带宽 等受限)。另有各云「试用/免费层」Postgres均以 官网当期配额 为准。k3s 连接串一般需 sslmode=require(或厂商文档要求);家庭实验室须保证各 k3s server 能访问云库主机出口、防火墙、TLS仅免费档不宜当生产唯一 datastore(易触顶、休眠策略、合规以厂商为准)。

注意datastore 建议与 两个 k3s server 网络互通、且 不要 只跑在「即将整体下线的那一台」唯一节点上,否则 datastore 单点与迁移成本更高。

双控 + datastore 还能不能「数据库集群」?

可以。 双主控解决的是 Kubernetes API6443 高可用;外部 PostgreSQL 这一层同样可以做成 高可用/集群,与双控 不冲突

  • k3s 侧--datastore-endpoint 里填的仍是 一个 连接目标(host 多为 VIP、LB 虚拟地址、托管库提供的单一 endpoint、或始终解析到当前主的 DNS。k3s 只按 PostgreSQL 协议访问,不关心背后是单进程还是多节点。
  • 数据库侧:常见做法包括 云托管多可用区 PostgresRDS、Cloud SQL、Aurora 兼容端等)、Patroni + etcd/Consulrepmgr 等;由它们负责 主备、故障转移;对 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 节点。整体思路是:

  1. 确认 worker 节点健康
    • 已按 01-02-k3s-工作节点.md 正常加入集群;
    • 无关键 Pod 仅运行在该节点(可先用 kubectl drain 或手动迁移工作负载)。
  2. 01-07 阶段完成外部 datastore 与 LB 准备
    • 不要立即改动现有 server/worker 的 systemd 配置,只确保 datastore/LB 均已就绪。
  3. 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 参数。