← 返回文章列表

K8s 高可用部署、版本升级与 etcd 备份恢复

9 分钟阅读
字号

K8s 高可用部署、版本升级与 etcd 备份恢复

本文涵盖 K8s 高可用集群部署方案、版本升级实践、etcd 备份与恢复等生产级运维核心知识点。


一、高可用集群部署方案

1. 高可用架构概述

核心思路: 负载均衡 + Keepalived 代理多个 Master 对外提供一个 VIP,所有 Worker Node 访问这个 VIP 即可。

                    VIP (192.168.71.100)

              ┌──────────┴──────────┐
              │      HAProxy       │
              │   (VIP 监听 8443)  │
              └──────────┬──────────┘

        ┌────────────────┼────────────────┐
   ┌────▼────┐      ┌────▼────┐      ┌────▼────┐
   │ Master1 │      │ Master2 │      │ Master3 │
   │API Server│     │API Server│     │API Server│

2. 两种 etcd 部署方案对比

方案一:堆叠 etcd(Stacked control plane nodes)

架构特点: etcd 服务运行在集群内部,与 Master 节点共用同一台主机,由 kubeadm 管理。

┌─────────────────────────────────────────┐
│           Master Node                    │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐│
│  │ kube-   │  │ kube-   │  │  etcd   ││
│  │ apiserver│  │scheduler│  │ (本地)  ││
│  └────┬────┘  └─────────┘  └────┬────┘│
│       │                         │     │
│       └───────────┬─────────────┘     │
│                   │                   │
│            kube-controller-manager      │
└─────────────────────────────────────────┘

工作原理:

  • kube-apiserver、kube-scheduler、kube-controller-manager 运行在同一节点
  • 本节点的 kube-controller-manager、kube-scheduler 只与本节点 kube-apiserver 通讯
  • 本节点 etcd 成员只与本节点 kube-apiserver 通讯
  • 由本节点 kube-apiserver 负责对外暴露

优点:

  1. 节省主机:etcd 成员与 Master 在相同节点,比外部 etcd 方案需要的主机数量少
  2. 部署简单:集群部署比较简单,复制易于管理

缺点:

  1. 鸡蛋都放在一个篮子里:如果某个主节点故障,其上的 kube-apiserver、kube-scheduler、kube-controller-manager 同时挂掉,该节点上的 etcd 也一起挂掉,所以需要多个主节点保证高可用

方案二:外部 etcd(External etcd cluster)

架构特点: etcd 服务运行在集群外部独立主机,与 Master 节点分离。

┌─────────────────────────────────────────┐
│           Master Node                    │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐│
│  │ kube-   │  │ kube-   │  │ kube-   ││
│  │ apiserver│  │scheduler│  │controller││
│  └────┬────┘  └─────────┘  └─────────┘│
└───────┼─────────────────────────────────┘
        │ 每个 etcd 与每个 Master 通讯

┌─────────────────────────────────────────┐
│           External etcd Cluster          │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐│
│  │  etcd1  │  │  etcd2  │  │  etcd3  ││
│  │(独立节点)│  │(独立节点)│  │(独立节点)││
│  └─────────┘  └─────────┘  └─────────┘│
└─────────────────────────────────────────┘

工作原理:

  • kube-apiserver 暴露为工作节点使用
  • etcd 运行在独立主机
  • 每个 etcd 服务与每个 Master 节点上的 kube-apiserver 通讯

优点:

  1. 鸡蛋没有放在一个篮子里:etcd 放在主节点外的节点上,因此主节点故障或 etcd 故障不会影响到集群冗余

缺点:

  1. 需要更多主机:至少三台主机运行 etcd 服务,至少三台主机运行 Master 节点

3. 服务器规划示例

7 台 CentOS 服务器:
- Master1: 192.168.71.101
- Master2: 192.168.71.102
- Master3: 192.168.71.103
- Node1:   192.168.71.104
- Node2:   192.168.71.105
- Node3:   192.168.71.106
- Node4:   192.168.71.107
 
VIP: 192.168.71.100 (Keepalived)

4. kubeadm join 命令

Master 节点加入集群:

kubeadm join api-server:8443 --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:e53ab548e5582cf86d3646cbfed824b28631906a0639265b123f285d66659e5d \
  --control-plane \
  --certificate-key 76efa192afc6bfb83aafddb4d2959aee2794e711567c0f4cb767a27f3df73eff

Worker 节点加入集群:

kubeadm join api-server:8443 --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:e53ab548e5582cf86d3646cbfed824b28631906a0639265b123f285d66659e5d

二、etcd 常用操作

1. etcdctl 基础命令

注意:etcd 数据存储使用的是 protocol buffer 序列化,不是 JSON 明文存储。

查看集群成员列表(多节点):

ETCDCTL_API=3 etcdctl \
  --endpoints=https://192.168.71.103:2379,https://192.168.71.101:2379,https://192.168.71.102:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member list

查看集群成员列表(单节点本地):

ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member list

查看所有 key(只显示 key 名):

ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  get / --prefix --keys-only

查看指定 key 值:

ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  get /registry/deployments/default/mynginx

2. etcdctl 下载地址

https://github.com/etcd-io/etcd/releases

三、K8s 版本升级实践

1. 升级原则

K8s 没有 LTS 长期稳定版本,需要定期升级。

原则说明
必须备份升级前备份所有组件及数据,重点是 etcd(/var/lib/etcd
不跨两个大版本如 1.19 → 1.21 必须走 1.20 中间站
测试环境演练升级前在测试环境充分演练,准备回滚脚本

2. 版本号规则

主版本号.次版本号.修订号
1.19.4 → 1.19.7  ✅ 通常不会有问题
1.19.4 → 1.20.4  ✅ 通常 OK
1.19.4 → 1.21.4  ⚠️ 慎重,不建议这么升级

正确升级路径示例:

# 错误:跨两个大版本
1.19.4 → 1.21.4  ❌
 
# 正确:分步升级
1.19.4 → 1.20.4 → 1.21.4  ✅

3. 升级前准备

etcd 数据备份

ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  snapshot save /var/backups/etcdbackupfile.db

etcd 数据恢复(如需回滚)

# 1. 停止服务
mv /etc/kubernetes/manifests /etc/kubernetes/manifests_bak
systemctl stop kubelet
 
# 2. 备份现有数据
mv /var/lib/etcd /var/lib/etcd_bak
mkdir /var/lib/etcd
 
# 3. 恢复数据
ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  snapshot restore /var/backups/etcdbackupfile.db --data-dir=/var/lib/etcd
 
# 4. 重启服务
mv /etc/kubernetes/manifests_bak /etc/kubernetes/manifests
systemctl restart kubelet

4. 三种升级方案

方案一:蓝绿方式

1. 仿照现有 K8s 集群,部署一套新环境
2. 在新环境里部署指定版本的 K8s
3. 把业务应用也部署到新环境
4. 然后将流量切换到新环境

特点: 回滚快,但需要双倍资源

方案二:滚动升级

1. 新增一台机器,例如在上面部署新版本的 Master 节点
2. 将新 Master join 进集群
3. 跑一段时间,停一台 Master
4. 重复直到全部完成

特点: 资源利用率高,但周期长

方案三:原地升级(前提:集群本身是高可用)

1. 先逐台更新 Master 上的 K8s 服务版本
2. 再逐个批量更新 Node 上的 K8s 服务版本

注意: 高版本 Master 通常可以管理更低版本的 Node,但版本差异过大也会有问题


四、etcd 备份与恢复

1. 备份

前提:备份应该周期性执行,建议写入脚本做成计划任务定期执行。

ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  snapshot save /var/backups/etcdbackupfile.db

2. 恢复步骤

第一步:停止相关服务

# 把使用该 etcd 实例的服务停掉
mv /etc/kubernetes/manifests /etc/kubernetes/manifests_bak
systemctl stop kubelet

第二步:清理数据

mv /var/lib/etcd /var/lib/etcd_bak
mkdir /var/lib/etcd

第三步:还原数据

ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  snapshot restore /var/backups/etcdbackupfile.db --data-dir=/var/lib/etcd

第四步:重启服务

mv /etc/kubernetes/manifests_bak /etc/kubernetes/manifests
systemctl restart kubelet

3. etcdctl 下载地址

https://github.com/etcd-io/etcd/releases

五、总结

┌─────────────────────────────────────────────────────────┐
│                   K8s 运维核心要点                       │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  高可用部署:                                             │
│  ├─ 堆叠 etcd:省钱简单,但故障影响大                     │
│  │   (一个节点故障 = apiserver + etcd 同时挂)           │
│  └─ 外部 etcd:更安全,但需要更多主机                     │
│      (故障隔离,etcd 挂了不影响 Master)                  │
│                                                          │
│  etcd 操作:                                             │
│  ├─ 数据是 protobuf 编码,不是 JSON                       │
│  ├─ etcdctl 需要设置 ETCDCTL_API=3                      │
│  └─ 必须指定证书文件(--cacert/--cert/--key)             │
│                                                          │
│  版本升级:                                               │
│  ├─ 不要跨两个大版本(如 1.19 → 1.21 必须走 1.20)       │
│  ├─ 先备份 etcd 数据                                      │
│  ├─ 测试环境演练 + 回滚脚本                               │
│  └─ 三种方案:蓝绿(双倍资源)/滚动(周期长)/原地升级   │
│                                                          │
│  etcd 备份恢复:                                          │
│  └─ 四步:停服务 → 清数据 → 还原 → 重启                   │
│                                                          │
└─────────────────────────────────────────────────────────┘
分享

// RELATED_POSTS

0%