阅读前说明
- 按照官网提供的文档操作能够恢复etcd数据,但是由于证书的问题,恢复的集群并不能正常使用,需要单独对集群的token进行清理。
- 官方文档中没有明确恢复etcd集群的部署,经过多次验证,确认了恢复etcd集群需要以下三步:1. 部署1台节点的etcd;2. 在当前1台etcd节点上恢复数据;3. 使用ansible扩容的方式,将etcd节点扩展到3台。
- 可以更新/etc/etcd/etcd.conf文件更改etcd name,进而解决etcd客户端访问服务器端证书不匹配的问题。
- 文章最后附上了经过测试认证的根据备份一键恢复etcd集群的脚本。
Openshift集群平台能够使用备份完整恢复集群。Openshift集群全环境备份
在恢复集群之前,请确保对集群做过完成的备份,并重新安装Openshift集群。
恢复Master节点
创建Master主机文件的备份后,如果它们被损坏或意外删除,就可以通过这些文件复制回Master主机来恢复文件,然后重新启动受影响的服务。
恢复过程
-
恢复
/etc/origin/master/master-config.yaml
文件$ MYBACKUPDIR=*/backup/$(hostname)/$(date +%Y%m%d)* $ cp /etc/origin/master/master-config.yaml /etc/origin/master/master-config.yaml.old $ cp /backup/$(hostname)/$(date +%Y%m%d)/origin/master/master-config.yaml /etc/origin/master/master-config.yaml $ master-restart api $ master-restart controllers
重启master服务可能会导致停机,此时可以将该主机从负载均衡池中删除,再恢复主机,待恢复完成后,Master服务也起来了,再将它添加到负载均衡池中。
-
如果因为缺少一些二进制包,而导致无法启动Master服务,那么重新安装缺少的包
-
获得当前已有的包
$ rpm -qa | sort > /tmp/current_packages.txt
-
与之前备份的包列表作比较,得到缺少的包
$ diff /tmp/current_packages.txt ${MYBACKUPDIR}/packages.txt > ansible-2.4.0.0-5.el7.noarch
-
安装缺少的包
$ yum reinstall -y <packages>
-
-
恢复系统信任的证书
$ MYBACKUPDIR=*/backup/$(hostname)/$(date +%Y%m%d)* $ sudo cp ${MYBACKUPDIR}/external_certificates/my_company.crt /etc/pki/ca-trust/source/anchors/ $ sudo update-ca-trust
恢复计算节点
一般计算节点不需要做恢复,但是如果有特殊的重要节点需要恢复的话,与Master节点恢复过程类似。
恢复过程
-
恢复
/etc/origin/node/node-config.yaml
文件$ MYBACKUPDIR=/backup/$(hostname)/$(date +%Y%m%d) $ cp /etc/origin/node/node-config.yaml /etc/origin/node/node-config.yaml.old $ cp /backup/$(hostname)/$(date +%Y%m%d)/etc/origin/node/node-config.yaml /etc/origin/node/node-config.yaml $ reboot
-
如果因为缺少一些二进制包,而导致无法启动Master服务,那么重新安装缺少的包
-
获得当前已有的包
$ rpm -qa | sort > /tmp/current_packages.txt
-
与之前备份的包列表作比较,得到缺少的包
$ diff /tmp/current_packages.txt ${MYBACKUPDIR}/packages.txt > ansible-2.4.0.0-5.el7.noarch
-
安装缺少的包
$ yum reinstall -y <packages>
-
-
恢复系统信任的证书
$ MYBACKUPDIR=*/backup/$(hostname)/$(date +%Y%m%d)* $ sudo cp ${MYBACKUPDIR}/external_certificates/my_company.crt /etc/pki/ca-trust/source/anchors/ $ sudo update-ca-trust
恢复etcd数据
恢复过程
-
恢复etcd配置文件
用备份中的etcd配置文件替换掉当前集群的配置文件,然后重启服务或者静态Pod。
$ ssh master-0 $ cp /backup/yesterday/master-0-files/etcd.conf /etc/etcd/etcd.conf $ restorecon -Rv /etc/etcd/etcd.conf $ systemctl restart etcd.service
-
恢复etcd数据
-
根据etcd v2 和 v3数据恢复
该恢复过程必须,在单独的一台主机上恢复数据,再通过扩容的方式加入剩下的主机
-
通过将pod的yaml文件移出来暂停etcd pod
$ mkdir -p /etc/origin/node/pods-stopped $ mv /etc/origin/node/pods/* /etc/origin/node/pods-stopped/ $ reboot
-
清除之前的数据
-
对当前数据做备份
$ mv /var/lib/etcd /var/lib/etcd.old $ mkdir /var/lib/etcd $ restorecon -Rv /var/lib/etcd/
-
直接清除当前数据
$ rm -rf /var/lib/etcd
-
-
在所有的etcd节点做如下操作,恢复数据
$ cp -R /backup/etcd-xxx/* /var/lib/etcd/ $ mv /var/lib/etcd/db /var/lib/etcd/member/snap/db $ chcon -R --reference /backup/etcd-xxx/* /var/lib/etcd/
-
在每台etcd主机上执行以下操作,强制创建一个新的etcd集群
$ mkdir -p /etc/systemd/system/etcd.service.d/ $ echo "[Service]" > /etc/systemd/system/etcd.service.d/temp.conf $ echo "ExecStart=" >> /etc/systemd/system/etcd.service.d/temp.conf $ sed -n '/ExecStart/s/"$/ --force-new-cluster"/p' \ /usr/lib/systemd/system/etcd.service \ >> /etc/systemd/system/etcd.service.d/temp.conf $ systemctl daemon-reload $ master-restart etcd
-
检查错误日志
$ master-logs etcd etcd
-
检查etcd集群的状态
# etcdctl2 cluster-health member 5ee217d17301 is healthy: got healthy result from https://192.168.55.8:2379 cluster is healthy
-
集群默认配置下启动etcd
$ rm -f /etc/systemd/system/etcd.service.d/temp.conf $ systemctl daemon-reload $ master-restart etcd
-
检查etcd状态,查看member list
$ etcdctl2 cluster-health member 5ee217d17301 is healthy: got healthy result from https://192.168.55.8:2379 cluster is healthy $ etcdctl2 member list 5ee217d17301: name=master-0.example.com peerURLs=http://localhost:2380 clientURLs=https://192.168.55.8:2379 isLeader=true
第一个实例运行后,就可以还原其余的etcd服务器
修复PEERURL参数问题
在恢复数据后,新的etcd集群参数peerurl为localhost而不是ip地址,我们需要将它修改为ip地址
-
执行etcdctl member list获得member ID
$ etcdctl member list
-
获得etcd通信的IP
$ ss -l4n | grep 2380
-
更新对应member的peer地址
$ etcdctl2 member update 5ee217d17301 https://192.168.55.8:2380 Updated member with ID 5ee217d17301 in cluster
-
查看新的peer地址进行校验
$ etcdctl2 member list 5ee217d17301: name=master-0.example.com peerURLs=https://*192.168.55.8*:2380 clientURLs=https://192.168.55.8:2379 isLeader=true
-
-
根据v3的快照snapshot恢复
如果是使用etcdctl snapshot save的方式备份的snapshot,etcdctl snapshot restore恢复数据时会去校验数据的hash,但是如果直接从数据目录中拷贝出来的就无法校验hash,这时恢复数据时需要加上--skip-hash-check
该恢复过程必须,在单独的一台主机上恢复数据,再通过扩容的方式加入剩下的主机
-
通过将pod的yaml文件移出来暂停etcd pod
$ mkdir -p /etc/origin/node/pods-stopped $ mv /etc/origin/node/pods/* /etc/origin/node/pods-stopped/ $ reboot
-
清除之前的数据
$ rm -rf /var/lib/etcd
-
使用snapshot restore命令来恢复数据
# etcdctl3 snapshot restore /backup/etcd-xxxxxx/backup.db \ --data-dir /var/lib/etcd \ --name master-0.example.com \ --initial-cluster "master-0.example.com=https://192.168.55.8:2380" \ --initial-cluster-token "etcd-cluster-1" \ --initial-advertise-peer-urls https://192.168.55.8:2380 \ --skip-hash-check=true 2017-10-03 08:55:32.440779 I | mvcc: restore compact to 1041269 2017-10-03 08:55:32.468244 I | etcdserver/membership: added member 40bef1f6c79b3163 [https://192.168.55.8:2380] to cluster 26841ebcf610583c
相关配置从/etc/etcd/etcd.conf获取
-
给相关文件及目录设置相关的selinux权限
$ restorecon -Rv /var/lib/etcd/
-
启动etcd服务
$ systemctl start etcd
-
检查错误日志
$ master-logs etcd etcd
-
-
在静态etcd pod恢复etcd
-
通过将pod的yaml文件移出来暂停etcd pod
$ mv /etc/origin/node/pods/etcd.yaml .
-
清除之前的数据
$ rm -rf /var/lib/etcd
-
使用snapshot恢复集群数据
$ export ETCDCTL_API=3 $ etcdctl snapshot restore /etc/etcd/backup/etcd/snapshot.db --data-dir /var/lib/etcd/ --name ip-172-18-3-48.ec2.internal --initial-cluster "ip-172-18-3-48.ec2.internal=https://172.18.3.48:2380" --initial-cluster-token "etcd-cluster-1" --initial-advertise-peer-urls https://172.18.3.48:2380 --skip-hash-check=true
从$/backup_files/etcd.conf 文件中获得相关的参数
-
给相关文件及目录设置相关的selinux权限
$ restorecon -Rv /var/lib/etcd/
-
通过将etcd pod的yaml文件恢复到静态pod目录下来重启etcd数据
$ mv etcd.yaml /etc/origin/node/pods/.
-
-
使用Ansible添加etcd节点
还原etcd数据后,可以使用ansible或者手动的方式对etcd进行扩容。
添加过程
-
在inventory的hosts中添加[new_etcd]服务器组
[OSEv3:children] masters nodes etcd new_etcd ... [OUTPUT ABBREVIATED] ... [etcd] master-0.example.com master-1.example.com master-2.example.com [new_etcd] etcd0.example.com
-
执行ansible扩容ansible脚本
$ cd /usr/share/ansible/openshift-ansible $ ansible-playbook playbooks/openshift-etcd/scaleup.yml
-
将[new_etcd]服务器组的主机移到[etcd]组
[OSEv3:children] masters nodes etcd new_etcd ... [OUTPUT ABBREVIATED] ... [etcd] master-0.example.com master-1.example.com master-2.example.com etcd0.example.com
恢复Openshift集群节点上的服务
恢复过程
-
在每一个Master节点恢复配置文件及重启相关服务
$ cp ${MYBACKUPDIR}/etc/origin/node/pods/* /etc/origin/node/pods/ $ cp ${MYBACKUPDIR}/etc/origin/master/master.env /etc/origin/master/master.env $ cp ${MYBACKUPDIR}/etc/origin/master/master-config.yaml.<timestamp> /etc/origin/master/master-config.yaml $ cp ${MYBACKUPDIR}/etc/origin/node/node-config.yaml.<timestamp> /etc/origin/node/node-config.yaml $ cp ${MYBACKUPDIR}/etc/origin/master/scheduler.json.<timestamp> /etc/origin/master/scheduler.json $ master-restart api $ master-restart controllers
-
在每一个Node节点,恢复配置文件,并重启origin-node服务
$ cp /etc/origin/node/node-config.yaml.<timestamp> /etc/origin/node/node-config.yaml $ systemctl enable atomic-openshift-node $ systemctl start atomic-openshift-node
恢复项目Project
恢复项目前,先创建项目,再通过oc create -f
命令将项目中的对象恢复。恢复项目时要注意对象的依赖关系,比如说pod依赖configmap资源,就需要先创建configmap。
恢复过程
$ oc new-project <projectname>
$ oc create -f project.yaml
$ oc create -f secret.yaml
$ oc create -f serviceaccount.yaml
$ oc create -f pvc.yaml
$ oc create -f rolebindings.yaml
恢复应用数据
与备份应用数据类似,可以使用oc rsync
命令来恢复应用数据。
以下是一个利用jenkins应用的备份数据恢复应用的例子。
恢复过程
-
检查备份数据
$ ls -la /tmp/jenkins-backup/ total 8 drwxrwxr-x. 3 user user 20 Sep 6 11:14 . drwxrwxrwt. 17 root root 4096 Sep 6 11:16 .. drwxrwsrwx. 12 user user 4096 Sep 6 11:14 jenkins
-
使用
oc rsync
恢复应用数据$ oc rsync /tmp/jenkins-backup/jenkins jenkins-1-37nux:/var/lib
-
重启应用
$ oc delete pod jenkins-1-37nux
或者使用
oc scale
命令将pod数调整为0,再调整为1,实现应用的重启$ oc scale --replicas=0 dc/jenkins $ oc scale --replicas=1 dc/jenkins
恢复持久化卷数据
如果应用已挂载了新的PV,那就将该PV原来的数据删除,之后将备份的数据拷贝到对应的目录;如果应用没有挂载PV,那就先挂载一个PV,再恢复数据。
恢复过程
-
如果没有挂载PV执行创建新的挂载
$ oc set volume dc/demo --add --name=persistent-volume \ --type=persistentVolumeClaim --claim-name=filestore \ --mount-path=/opt/app-root/src/uploaded --overwrite
-
删除当前PV挂载目录下的数据
$ oc rsh demo-2-fxx6d sh-4.2$ ls */opt/app-root/src/uploaded/* lost+found ocp_sop.txt sh-4.2$ *rm -rf /opt/app-root/src/uploaded/ocp_sop.txt* sh-4.2$ *ls /opt/app-root/src/uploaded/* lost+found
-
将之前备份的数据拷贝到对应的目录下
$ oc rsync uploaded demo-2-fxx6d:/opt/app-root/src/
-
验证应用数据
$ oc rsh demo-2-fxx6d sh-4.2$ *ls /opt/app-root/src/uploaded/* lost+found ocp_sop.txt
实战演练步骤
- 部署安装3Master 1etcd及2个Node节点的Openshift集群
- 使用
恢复etcd数据
中的根据v3的快照snapshot恢复
恢复etcd数据
如果此时pod无法正常启动,可以执行以下命令
$ echo "ETCD_FORCE_NEW_CLUSTER=true" >> /etc/etcd/etcd.conf
再重启Pod,待etcd正常运行后,将刚才添加的ETCD_FORCE_NEW_CLUSTER=true
从/etc/etcd/etcd.conf文件中删除。
- 按照
使用Ansible添加etcd节点
中的步骤将1个etcd节点扩容为3个etcd节点 - 清理恢复中的Openshift集群中的token,并重启相关pod,实现Openshift集群的完整恢复。
一键恢复与解决证书问题的脚本
一键恢复etcd
[root@master01 ~]# cat restore_etcd.sh
#!/bin/bash
snapshot_file_dir=$1
if [ $# -lt 1 ]
then
echo "Please input snapshot file path"
exit 2
fi
export ETCD_POD_MANIFEST="/etc/origin/node/pods/etcd.yaml"
mv ${ETCD_POD_MANIFEST} .
rm -rf /var/lib/etcd
## 获取etcd相关初始化配置项
ETCD_CONFIG_FILE="/etc/etcd/etcd.conf"
etcd_data_dir=$(grep ^ETCD_DATA_DIR= $ETCD_CONFIG_FILE|cut -d= -f2)
etcd_name=$(grep ^ETCD_NAME= $ETCD_CONFIG_FILE|cut -d= -f2)
etcd_initial_cluster=$(grep ^ETCD_INITIAL_CLUSTER= $ETCD_CONFIG_FILE|awk -F'ETCD_INITIAL_CLUSTER=' '{print $2}')
etcd_initial_cluster_token=$(grep ^ETCD_INITIAL_CLUSTER_TOKEN= $ETCD_CONFIG_FILE|cut -d= -f2)
etcd_initial_advertise_peer_urls=$(grep ^ETCD_INITIAL_ADVERTISE_PEER_URLS= $ETCD_CONFIG_FILE|cut -d= -f2)
## 恢复etcd数据
export ETCDCTL_API=3
etcdctl snapshot restore $snapshot_file_dir --data-dir $etcd_data_dir --name $etcd_name --initial-cluster "$etcd_initial_cluster" --initial-cluster-token "$etcd_initial_cluster_token" --initial-advertise-peer-urls $etcd_initial_advertise_peer_urls --skip-hash-check=true
restorecon -Rv /var/lib/etcd
mv etcd.yaml $ETCD_POD_MANIFEST
一键整理etcd数据,解决证书问题
[root@master01 ~]# cat reset.sh
#!/bin/bash
oc login -u system:admin
projects=$(oc get projects | awk '{print $1}' | grep -v kube-system|grep -v NAME)
for project in $(echo $projects)
do
oc delete secret $(oc get secret -n $project | grep token | awk '{print $1}') -n $project
oc delete pod $(oc get pod -n $project | grep -v NAME | awk '{print $1}') -n $project --force --grace-period=0
done