- 基于 etcd 快照还原 Kubernetes 集群
- 配置用于灾难恢复
配置用于灾难恢复
etcd
快照,并在另一个(辅助)Kubernetes 集群或源集群本身中恢复快照。在下载和使用脚本配置快照之前,规划配置并了解要求非常重要。
注意:
此解决方案假设 Kubernetes 集群(包括控制层和 worker 节点)都已存在。计划配置
注意:
此解决方案假设 Kubernetes 集群(包括控制层和 worker 节点)都已存在。本手册中提供的建议和实用程序不会检查资源、控制层或 worker 节点容量和配置。恢复可以应用于“镜像”主节点(相同数量的控制平面节点、相同数量的 worker 节点)的集群。这些过程假定存在使用 kubeadm
创建的主 Kubernetes 集群。辅助系统中的主机名配置为模仿主主机名,如下一段所述。然后,也会使用 kubeadm
创建辅助群集(仅处理所需的主机名解析之后)。
规划配置时,请完成 Restore
的以下要求:
- 确认主节点中的所需 worker 节点和资源在辅助节点中可用。 这包括共享存储装载、负载平衡器以及将在要还原的名称空间中使用的 pod 和系统使用的数据库。
- 配置主机名解析,以便控制层和 Worker 平面使用的主机名在辅助层中有效。
例如,如果主站点解析类似于以下内容的群集:
[opc@olk8-m1 ~]$ kubectl get nodes -A NAME STATUS ROLES AGE VERSION olk8-m1 Ready control-plane 552d v1.25.12 olk8-m2 Ready control-plane 552d v1.25.12 olk8-m3 Ready control-plane 2y213d v1.25.12 olk8-w1 Ready <none> 2y213d v1.25.12 olk8-w2 Ready <none> 2y213d v1.25.12 olk8-w3 Ready <none> 2y213d v1.25.12 [opc@olk8-m1 ~]$ nslookup olk8-m1 Server: 169.254.169.254 Address: 169.254.169.254#53 Non-authoritative answer: Name: olk8-m1.k8dbfrasubnet.k8dbvcn.oraclevcn.com Address: 10.11.0.16
然后,辅助站点必须使用相同的节点名称。在控制层中的上一个示例节点中,区域 2 中的主机名将与映射到其他 IP 的主机名相同。[opc@k8dramsnewbastion ~]$ nslookup olk8-m1 Server: 169.254.169.254 Address: 169.254.169.254#53 Non-authoritative answer: Name: olk8-m1.sub01261629121.k8drvcnams.oraclevcn.com Address: 10.5.176.144 [opc@k8dramsnewbastion ~]$
生成的辅助配置(使用kubeadm
创建群集并添加 worker 节点后)将使用完全相同的节点名称,即使内部 IP 和其他值延迟也是如此。[opc@k8dramsnewbastion ~]$ kubectl get nodes -A NAME STATUS ROLES AGE VERSION olk8-m1 Ready control-plane 552d v1.25.11 olk8-m2 Ready control-plane 552d v1.25.11 olk8-m3 Ready control-plane 2y213d v1.25.11 olk8-w1 Ready <none> 2y213d v1.25.11 olk8-w2 Ready <none> 2y213d v1.25.11 olk8-w3 Ready <none> 2y213d v1.25.11
- 对
kube-api
前端地址使用类似的“主机名别名”。注意:
主 Kubernetes 集群不应将 IP 地址用于前端
kube-api
。必须使用主机名,以便可以在辅助系统中将此前端设为别名。有关如何将主机名别名添加到现有主kube-api
系统的示例,请参见 maak8s-kube-api-alias.sh 脚本。例如,如果主服务器的kube-api
地址解析如下所示:[opc@olk8-m1 ~]$ grep server .kube/config server: https://k8lbr.paasmaaoracle.com:6443 [opc@olk8-m1 ~]$ grep k8lbr.paasmaaoracle.com /etc/hosts 132.145.247.187 k8lbr.paasmaaoracle.com k8lbr
然后,辅助服务器的kube-api
应使用相同的主机名(您可以将其映射到其他 IP):[opc@k8dramsnewbastion ~]$ grep server .kube/config server: https://k8lbr.paasmaaoracle.com:6443 [opc@k8dramsnewbastion ~]$ grep k8lbr.paasmaaoracle.com /etc/hosts 144.21.37.81 k8lbr.paasmaaoracle.com k8lbr
您可以通过使用虚拟主机、本地/etc/hosts
解析或每个位置的不同 DNS 服务器来实现此目的。要确定由特定主机使用的主机名解析方法,请在主机上的/etc/nsswitch.conf
文件中搜索 hosts 参数的值。-
如果要解析主机上的本地主机名,则使文件条目成为
hosts
参数的第一个条目。当files
是 hosts 参数的第一个条目时,将首先使用主机/etc/hosts
文件中的条目解析主机名。指定在
/etc/nsswitch.conf
文件中使用本地主机名解析:hosts: files dns nis
-
如果要通过在主机上使用 DNS 解析主机名,请使
dns
条目成为 hosts 参数的第一个条目。当dns
是hosts
参数的第一个条目时,首先使用 DNS 服务器条目解析主机名。指定使用 DNS 主机名解析
/etc/nsswitch.conf
文件:hosts: dns files nis
为了简化和保持一致性,Oracle 建议站点(生产站点或备用站点)中的所有主机使用相同的主机名解析方法(在本地解析主机名或使用单独的 DNS 服务器或全局 DNS 服务器解析主机名)。
“主机名别名”技术已经在中间件系统的灾难保护中使用多年。您可以在 Oracle 文档中找到详细信息和示例,包括 Oracle Fusion Middleware Disaster Recovery Guide 和与 Oracle Cloud Disaster Protection 相关的其他文档,例如 Oracle WebLogic Server for Oracle Cloud Infrastructure Disaster Recovery 和 SOA Suite on Oracle Cloud Infrastructure Marketplace Disaster Recovery 。
-
- 使用与主服务器中相同的前端
kube-api
负载平衡器主机名创建辅助集群。在主机名解析准备就绪后执行此步骤。请参阅 Kuberneteskubeadm
工具文档。使用与主版本相同的kubeadm
和 Kubernetes 版本。容器运行时可能会延迟,但您应该在两个区域使用相同版本的 Kubernetes 基础设施。例如,如果主群集是使用以下项创建的:kubeadm init --control-plane-endpoint $LBR_HN:$LBR_PORT --pod-network-cidr=10.244.0.0/16 --node-name $mnode1 --upload-certs --v=9
然后,在辅助值中使用与主值完全相同的
$LBR_HN:$LBR_PORT
和 CIDR 值。如果使用其他群集创建工具(例如 kOps 和 kubesparay),则同样适用。 - 添加其他控制层或 worker 节点时,请确保在主节点和辅助节点中使用相同的节点名称。
kubeadm join $LBR_HN:$LBR_PORT --token $token --node-name $host --discovery-token-ca-cert-hash $token_ca --control-plane --certificate-key $cp_ca
- 配置辅助群集后,从 kubernetes 检索节点信息时应显示相同的主机名。
每个控制层和 worker 节点的辅助节点中使用的 $host 变量必须与主节点中使用的变量相同。
主集群
在主服务器上运行以下命令以确认控制层和 worker 节点状态、角色、生存期、版本、内部 IP、外部 IP、OS 映像、内核版本和容器运行时:下面是输出示例。[opc@olk8-m1 ~]$ kubectl get nodes -o wide
[opc@olk8-m1 ~]$ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME olk8-m1 Ready control-plane 578d v1.25.12 10.11.0.16 <none> Oracle Linux Server 7.9 4.14.35-1902.302.2.el7uek.x86_64 cri-o://1.26.1 olk8-m2 Ready control-plane 578d v1.25.12 10.11.210.212 <none> Oracle Linux Server 7.9 5.4.17-2136.301.1.3.el7uek.x86_64 cri-o://1.26.1 olk8-m3 Ready control-plane 2y238d v1.25.12 10.11.0.18 <none> Oracle Linux Server 7.9 4.14.35-2047.527.2.el7uek.x86_64 cri-o://1.26.1 olk8-w1 Ready <none> 2y238d v1.25.12 10.11.0.20 <none> Oracle Linux Server 7.9 4.14.35-1902.302.2.el7uek.x86_64 cri-o://1.26.1 olk8-w2 Ready <none> 2y238d v1.25.12 10.11.0.21 <none> Oracle Linux Server 7.9 4.14.35-1902.302.2.el7uek.x86_64 cri-o://1.26.1 olk8-w3 Ready <none> 2y238d v1.25.12 10.11.0.22 <none> Oracle Linux Server 7.9 4.14.35-1902.302.2.el7uek.x86_64 cri-o://1.26.1 [opc@olk8-m1 ~]$
在主服务器上运行以下命令以确定 Kubernetes 控制层和核心 DNS 的运行位置。[opc@olk8-m1 ~]$ kubectl cluster-info
辅助群集
在辅助节点上运行以下命令以确认控制层和 worker 节点状态、角色、年龄、版本、内部 IP、外部 IP、OS 映像、内核版本和容器运行时:[opc@k8dramsnewbastion ~]$ kubectl get node -o wide
下面是输出示例。[opc@k8dramsnewbastion ~]$ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME olk8-m1 Ready control-plane 579d v1.25.11 10.5.176.144 <none> Oracle Linux Server 8.7 5.15.0-101.103.2.1.el8uek.x86_64 containerd://1.6.21 olk8-m2 Ready control-plane 579d v1.25.11 10.5.176.167 <none> Oracle Linux Server 8.7 5.15.0-101.103.2.1.el8uek.x86_64 containerd://1.6.21 olk8-m3 Ready control-plane 2y239d v1.25.11 10.5.176.154 <none> Oracle Linux Server 8.7 5.15.0-101.103.2.1.el8uek.x86_64 containerd://1.6.21 olk8-w1 Ready <none> 2y239d v1.25.11 10.5.176.205 <none> Oracle Linux Server 8.7 5.15.0-101.103.2.1.el8uek.x86_64 containerd://1.6.22 olk8-w2 Ready <none> 2y239d v1.25.11 10.5.176.247 <none> Oracle Linux Server 8.7 5.15.0-101.103.2.1.el8uek.x86_64 containerd://1.6.22 olk8-w3 Ready <none> 2y239d v1.25.11 10.5.176.132 <none> Oracle Linux Server 8.7 5.15.0-101.103.2.1.el8uek.x86_64 containerd://1.6.22 [opc@k8dramsnewbastion ~]$ kubectl cluster-info Kubernetes control plane is running at https://k8lbr.paasmaaoracle.com:6443 CoreDNS is running at https://k8lbr.paasmaaoracle.com:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. [opc@k8dramsnewbastion ~]$
在辅助服务器上运行以下命令以确定 Kubernetes 控制层和核心 DNS 的运行位置。[opc@k8dramsnewbastion ~]$ kubectl cluster-info
使用
kubeadm
群集创建中的默认设置,etcd
将在主端口和辅助端口中使用相同的端口。如果辅助集群需要使用不同的端口,则必须修改脚本来处理它。可以对etcds
数据库在主数据库和辅助数据库中使用不同的存储位置。脚本将负责在辅助群集用于etcd
的相应位置进行恢复。 - 在主位置和辅助位置(执行备份和恢复脚本的节点)中安装
etcdctl
。用于备份和恢复的脚本将使用etcdctl
从群集获取信息,以及创建和应用etcd
快照。要安装etcdctl
,请参见 https://github.com/etcd-io/etcd/releases 文档。 - 确保设置了适当的防火墙和安全规则,以便为此类访问启用执行备份和恢复操作的节点。这些脚本还需要使用
kubectl
访问集群,并通过 SSH 和 HTTP(对于 shell 命令和etcdctl
操作)访问不同的节点。
配置
配置用于灾难恢复。
恢复的步骤包括以下步骤:
- 在主位置执行
etcd
备份。 - 将备份发送到辅助位置。
- 在辅助群集中恢复该
etcd
备份。
此时,请执行以下步骤:
- 在主 Kubernetes 集群中创建
etcd
备份。- 从本文档的“下载代码”部分下载
etcd
快照 DR 的所有脚本。注意:
所有脚本必须位于同一路径中,因为主脚本使用其他辅助脚本。 - 从控制层节点
etcd
配置中获取 advert_port 。[opc@olk8-m1 ~]$ sudo grep etcd.advertise-client-urls /etc/kubernetes/manifests/etcd.yaml | awk -F ":" '{print $NF}' 2379
与init_port
相同:[opc@olk8-m1 ~]$ sudo grep initial-advertise-peer-urls /etc/kubernetes/manifests/etcd.yaml | awk -F ":" '{print $NF}' 2380
这些端口是默认端口,由控制层的所有
etcd
云池使用。在极少数情况下,如果将etcd
定制为在每个节点中使用不同的init
和advertise
端口,则必须定制脚本以考虑这些端口。如果使用其他网络插件,或者必须在恢复后重新启动其他相关的云池或部署,则还可以定制infra_pod_list
的值。但是,一般情况下,它可以默认为文件中提供的值。 - 编辑
maak8s.env
脚本并根据您的环境更新变量。以下是maak8s.env
文件示例:[opc@olk8-m1 ~]$ cat maak8s.env #sudo ready user to ssh into the control plane nodes export user=opc #ssh key for the ssh export ssh_key=/home/opc/KeyMAA.ppk #etcdctl executable's location export etcdctlhome=/scratch/etcdctl/ #etcd advertise port export advert_port=2379 #etcd init cluster port export init_port=2380 #infrastructure pods that will be restarted on restore export infra_pod_list="flannel proxy controller scheduler"
- 运行
maak8-etcd-backup.sh
脚本并按以下顺序提供以下字段作为参数:- 存储备份的目录
- 描述备份的“标签/文本”
- 运行
kubectl
操作的群集配置的位置
例如:[opc@olk8-m1 ~]$ ./maak8-etcd-backup.sh /backup-volumes/ "ETCD Snapshot after first configuration " /home/opc/.kubenew/config
该脚本执行以下任务:
- 从
etcd
主节点创建etcd
快照 - 创建每个控制层节点的当前配置的副本(每个控制层节点的清单和证书),包括集群的签名密钥
- 记录节点、云池、服务和群集配置的列表
- 将上述所有信息存储在带有日期标签的目录中。如果命令行参数中指定的目录为
/backup-volume
,则备份存储在备份的/backup-volume/etcd_snapshot_date
下。例如,/backup-volume/etcd_snapshot_2022-08-29_15-56-59
。
- 从本文档的“下载代码”部分下载
- 将整个目录 (
/backup-volume/etcd_snapshot_date
) 复制到辅助群集。- 使用
sftp
工具或使用该目录创建一个 tar 并将其发送到辅助位置。 - 解压缩或解压缩文件,使其在辅助系统中可用,就像在主系统中一样。
- 记下备份中的日期标签(在上面的示例中为 2022-08-29_15-56-59)。
例如:[opc@olk8-m1 ~]$ scp -i KeyMAA.ppk -qr /backup-volume/etcd_snapshot_2022-08-29_15-56-59 154.21.39.171:/restore-volume [opc@olk8-m1 ~]$ ssh -i KeyMAA.ppk 154.21.39.171 "ls -lart /restore-volume" total 4 drwxrwxrwt. 6 root root 252 Aug 30 15:11 .. drwxrwxr-x. 3 opc opc 47 Aug 30 15:12 . drwxrwxr-x. 5 opc opc 4096 Aug 30 15:12 etcd_snapshot_2022-08-29_15-56-59
- 使用
- 备份在辅助位置可用后,请按照以下步骤进行还原:
- 将
etcd
快照 DR 的所有脚本从“下载代码”部分下载到将运行恢复的辅助区域节点。请记住,此节点还必须安装etcdctl
并对辅助群集具有kubectl
访问权限。注意:
由于主脚本使用其他辅助脚本,因此在执行不同步骤时,所有脚本必须位于同一路径中。 - 编辑
maak8s.env
脚本并根据您的环境更新变量。您可以根据辅助节点更改用户、SSH 密钥和etcdctl
位置,但advert
和init
端口应与主节点中使用的端口相同。以下是maak8s.env
文件示例:[opc@olk8-m1 ~]$ cat maak8s.env #sudo ready user to ssh into the control plane nodes export user=opc #ssh key for the ssh export ssh_key=/home/opc/KeyMAA.ppk #etcdctl executable's location export etcdctlhome=/scratch/etcdctl/ #etcd advertise port export advert_port=2379 #etcd init cluster port export init_port=2380 #infrastructure pods that will be restarted on restore export infra_pod_list="flannel proxy controller scheduler"
- 使用
maak8-etcd-restore.sh
脚本运行恢复。作为参数提供备份从主数据库复制到备用数据库的根目录、备份的时间戳以及集群的kubectl
配置的位置。例如:[opc@k8dramsnewbastion ~]$ ./maak8-etcd-restore.sh /restore-volume 2022-08-29_15-56-59 /home/opc/.kube/config
该脚本在
/restore-volume
目录中查找名为etcd_snapshot_date
的子目录。使用该示例时,将使用/restore-volume/etcd_snapshot_2022-08-29_15-56-59
。恢复执行以下任务:- 强制在二级停止控制平面(如果正在运行)
- 在所有控制层节点中恢复
etcd
快照 - 替换所有控制层节点中的集群签名密钥
- 启动控制层
- 回收集群中的所有基础设施云池(代理、调度程序、控制器)和部署(使其处于一致状态)
恢复结束时,将显示 pod 和
etcd
子系统的状态。例如:NAMESPACE NAME READY STATUS RESTARTS AGE default dnsutils 1/1 Running 0 27d default nginx-deployment-566ff9bd67-6rl7f 1/1 Running 0 19s default nginx-deployment-566ff9bd67-hnx69 1/1 Running 0 17s default nginx-deployment-566ff9bd67-hvrwq 1/1 Running 0 15s default test-pd 1/1 Running 0 26d kube-flannel kube-flannel-ds-4f2fz 1/1 Running 3 (22d ago) 35d kube-flannel kube-flannel-ds-cvqzh 1/1 Running 3 (22d ago) 35d kube-flannel kube-flannel-ds-dmbhp 1/1 Running 3 (22d ago) 35d kube-flannel kube-flannel-ds-skhz2 1/1 Running 3 (22d ago) 35d kube-flannel kube-flannel-ds-zgkkp 1/1 Running 4 (22d ago) 35d kube-flannel kube-flannel-ds-zpbn7 1/1 Running 3 (22d ago) 35d kube-system coredns-8f994fbf8-6ghs4 0/1 ContainerCreating 0 15s kube-system coredns-8f994fbf8-d79h8 1/1 Running 0 19s kube-system coredns-8f994fbf8-wcknd 1/1 Running 0 12s kube-system coredns-8f994fbf8-zh8w4 1/1 Running 0 19s kube-system etcd-olk8-m1 1/1 Running 22 (89s ago) 44s kube-system etcd-olk8-m2 1/1 Running 59 (88s ago) 44s kube-system etcd-olk8-m3 1/1 Running 18 (88s ago) 26s kube-system kube-apiserver-olk8-m1 1/1 Running 26 (89s ago) 44s kube-system kube-apiserver-olk8-m2 1/1 Running 60 (88s ago) 42s kube-system kube-apiserver-olk8-m3 1/1 Running 18 (88s ago) 27s kube-system kube-controller-manager-olk8-m1 1/1 Running 19 (89s ago) 10s kube-system kube-controller-manager-olk8-m2 1/1 Running 18 (88s ago) 10s kube-system kube-controller-manager-olk8-m3 1/1 Running 18 (88s ago) 10s kube-system kube-flannel-ds-62dcq 1/1 Running 0 19s kube-system kube-flannel-ds-bh5w7 1/1 Running 0 19s kube-system kube-flannel-ds-cc2rk 1/1 Running 0 19s kube-system kube-flannel-ds-p8kdk 1/1 Running 0 19s kube-system kube-flannel-ds-vj8r8 1/1 Running 0 18s kube-system kube-flannel-ds-wz2kv 1/1 Running 0 18s kube-system kube-proxy-28d98 1/1 Running 0 14s kube-system kube-proxy-2gb99 1/1 Running 0 15s kube-system kube-proxy-4dfjd 1/1 Running 0 14s kube-system kube-proxy-72l5q 1/1 Running 0 14s kube-system kube-proxy-s8zbs 1/1 Running 0 14s kube-system kube-proxy-tmqnm 1/1 Running 0 14s kube-system kube-scheduler-olk8-m1 0/1 Pending 0 5s kube-system kube-scheduler-olk8-m2 1/1 Running 18 (88s ago) 5s kube-system kube-scheduler-olk8-m3 1/1 Running 18 (88s ago) 5s newopns weblogic-operator-5d74f56886-mtjp6 0/1 Terminating 0 26d newopns weblogic-operator-webhook-768d9f6f79-tdt8b 0/1 Terminating 0 26d soans soaedgdomain-adminserver 0/1 Running 0 22d soans soaedgdomain-soa-server1 0/1 Running 0 22d soans soaedgdomain-soa-server2 0/1 Running 0 22d +--------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | +--------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | olk8-m1:2379 | 63c63522f0be24a6 | 3.5.6 | 146 MB | true | false | 2 | 1195 | 1195 | | | olk8-m2:2379 | 697d3746d6f10842 | 3.5.6 | 146 MB | false | false | 2 | 1195 | 1195 | | | olk8-m3:2379 | 7a23c67093a3029 | 3.5.6 | 146 MB | false | false | 2 | 1195 | 1195 | | +--------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ +------------------+---------+---------+----------------------+---------------------------+------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER | +------------------+---------+---------+----------------------+---------------------------+------------+ | 7a23c67093a3029 | started | olk8-m3 | https://olk8-m3:2380 | https://10.5.176.154:2379 | false | | 63c63522f0be24a6 | started | olk8-m1 | https://olk8-m1:2380 | https://10.5.176.144:2379 | false | | 697d3746d6f10842 | started | olk8-m2 | https://olk8-m2:2380 | https://10.5.176.167:2379 | false | +------------------+---------+---------+----------------------+---------------------------+------------+ Restore completed at 2023-08-30_15-18-22 [opc@k8dramsnewbastion ~]$
- 将
验证
maak8DR-apply.sh
脚本后,验证主集群中存在的所有对象是否已复制到辅助集群。查看辅助集群并验证辅助站点中的云池是否正在运行且没有错误。
- 检查辅助云池的状态,直到所需的云池与主云池中的状态匹配。 默认情况下,云池和部署在辅助区域中启动。恢复结束时,将显示辅助群集的状态。某些云池可能需要额外的时间才能达到“正在运行”状态。
- 检查辅助服务器中的
restore
日志以了解可能的错误。日志位置在恢复开始时报告。默认情况下,日志是在备份本身所在的目录(位于/backup_dir/etcd_snapshot_backup-date/restore_attempted_restore-date/restore.log
)下创建的。专门为etcd
快照恢复操作/backup_dir/etcd_snapshot_backup-date/restore_attempted_restore-date/etcd_op.log
创建了另一个日志。 - (可选)恢复。
除了恢复日志之外,还为
/backup_dir/etcd_snapshot_backup-date/restore_attempted_restore-date/current_etc_kubernetes
目录下的每个控制层节点创建一个先前/etc/kubernetes
配置的备份。同样,在恢复之前每个节点中的etcd
数据库将复制到/backup_dir/etcd_snapshot_backup-date/restore_attempted_restore-date/node_name
。您可以使用这些命令恢复到执行恢复之前存在的群集配置。