146 lines
10 KiB
Markdown
146 lines
10 KiB
Markdown
# 01-07-双控制节点HA(安装与准备)
|
||
|
||
## TL;DR
|
||
|
||
- **自动化验收(基线)**:`./ansible/bin/verify.sh run 01-07`(只做集群可达性基线;HA 加入/切换需按本文手工演练)
|
||
- **你需要准备**:第二个 server、外部 datastore、**面向 `6443` 的负载均衡**(双主控硬前提);**仅两台主控、不想单独跑 HAProxy/nginx 时,优先 [kube-vip](https://kube-vip.io/)(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](https://kube-vip.io/)(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`(仍属负载均衡,只是不在你自己机器上跑进程)。
|
||
|
||
## 安装准备清单
|
||
|
||
1. 新增第二个 server 节点(示例 `192.168.2.63`)
|
||
2. 准备外部数据存储(MySQL/PostgreSQL/etcd)
|
||
3. 准备 **`6443` 负载均衡**:**仅双主控、无独立 LB 机器时优先 kube-vip(L2 VIP)**;否则可选 HAProxy、nginx stream、云 LB 等
|
||
4. 备份现有 token 与关键配置
|
||
|
||
### 免费 PostgreSQL(实验室推荐)
|
||
|
||
k3s 的外部 datastore 只需 **兼容的 PostgreSQL**;**PostgreSQL 本体开源**([PostgreSQL License](https://www.postgresql.org/about/licence/)),无商业版授权问题,下列均为 **$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](https://hub.docker.com/_/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](https://neon.tech/)**(Serverless Postgres,免费档对 **存储、分支、计算时长** 等有限额,适合轻量/实验);**[Supabase](https://supabase.com/pricing)**(免费档含托管 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 安装时同样需要)。
|
||
|
||
```bash
|
||
# 假设外部 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` 中的操作步骤。
|
||
|
||
## 基础验证
|
||
|
||
```bash
|
||
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 参数。
|
||
|