- 基于 etcd 快照恢复 Kubernetes 集群
- 配置以实现灾难恢复
配置以实现灾难恢复
注:
此解决方案假定 Kubernetes 集群(包括控制层和 worker 节点)都已存在。规划配置
注:
此解决方案假定 Kubernetes 集群(包括控制层和 worker 节点)都已存在。此手册中提供的建议和实用程序不检查资源、控制层或 worker 节点容量和配置。可在“镜像”主节点(同一控制层节点数,相同数量的 worker 节点)的集群中应用还原。这些过程假定存在使用 kubeadm
创建的主 Kubernetes 集群。辅助系统中的主机名配置为模仿主主机名,如下一段所述。然后,也使用 kubeadm
创建辅助群集(仅对所需的主机名解析进行处理之后)。
规划配置时,请完成 Restore
的以下要求:
- 确认主节点和资源在辅助节点上可用。 这包括共享存储挂载、负载平衡器以及将由要恢复的名称空间中使用的云池和系统使用的数据库。
- 配置主机名解析,以便控制层和工作人员层使用的主机名在辅助层有效。
例如,如果主站点解析群集的方式类似于以下内容:
[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 灾难保护相关的其他文档,例如 Oracle WebLogic Server for Oracle Cloud Infrastructure Disaster Recovery 和 Oracle Cloud Infrastructure Marketplace 灾难恢复上的 SOA Suite 。
-
- 使用与主集群中的前端
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 的所有脚本从“Download Code(下载代码)”部分下载到将运行恢复的辅助区域节点。请记住,此节点还必须安装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
配置的备份。同样,在将恢复复制到/backup_dir/etcd_snapshot_backup-date/restore_attempted_restore-date/node_name
之前,每个节点中的etcd
数据库。可以使用这些命令恢复到执行恢复之前存在的群集配置。