Openshift集群全环境恢复

敏捷自动化

阅读前说明

  • 按照官网提供的文档操作能够恢复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主机来恢复文件,然后重新启动受影响的服务。

恢复过程

  1. 恢复/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服务也起来了,再将它添加到负载均衡池中。

  2. 如果因为缺少一些二进制包,而导致无法启动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>
      
  3. 恢复系统信任的证书

    $ 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节点恢复过程类似。

恢复过程

  1. 恢复/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
    
    
  2. 如果因为缺少一些二进制包,而导致无法启动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>
      
  3. 恢复系统信任的证书

    $ 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数据恢复

      该恢复过程必须,在单独的一台主机上恢复数据,再通过扩容的方式加入剩下的主机

      1. 通过将pod的yaml文件移出来暂停etcd pod

        $ mkdir -p /etc/origin/node/pods-stopped
        $ mv /etc/origin/node/pods/* /etc/origin/node/pods-stopped/
        $ reboot
        
      2. 清除之前的数据

        • 对当前数据做备份

          $ mv /var/lib/etcd /var/lib/etcd.old
          $ mkdir /var/lib/etcd
          $ restorecon -Rv /var/lib/etcd/
          
          
        • 直接清除当前数据

          $ rm -rf /var/lib/etcd
          
          
      3. 在所有的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/
        
        
      4. 在每台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
        
        
      5. 检查错误日志

        $ master-logs etcd etcd
        
        
      6. 检查etcd集群的状态

        # etcdctl2 cluster-health
        member 5ee217d17301 is healthy: got healthy result from https://192.168.55.8:2379
        cluster is healthy
        
        
      7. 集群默认配置下启动etcd

        $ rm -f /etc/systemd/system/etcd.service.d/temp.conf
        $ systemctl daemon-reload
        $ master-restart etcd
        
        
      8. 检查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
        
        
      9. 第一个实例运行后,就可以还原其余的etcd服务器

      修复PEERURL参数问题

      在恢复数据后,新的etcd集群参数peerurl为localhost而不是ip地址,我们需要将它修改为ip地址

      1. 执行etcdctl member list获得member ID

        $ etcdctl member list
        
        
      2. 获得etcd通信的IP

        $ ss -l4n | grep 2380
        
        
      3. 更新对应member的peer地址

        $ etcdctl2 member update 5ee217d17301 https://192.168.55.8:2380
        Updated member with ID 5ee217d17301 in cluster
        
        
      4. 查看新的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

      该恢复过程必须,在单独的一台主机上恢复数据,再通过扩容的方式加入剩下的主机

      1. 通过将pod的yaml文件移出来暂停etcd pod

        $ mkdir -p /etc/origin/node/pods-stopped
        $ mv /etc/origin/node/pods/* /etc/origin/node/pods-stopped/
        $ reboot
        
      2. 清除之前的数据

        $ rm -rf /var/lib/etcd
        
      3. 使用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获取

      4. 给相关文件及目录设置相关的selinux权限

        $ restorecon -Rv /var/lib/etcd/
        
      5. 启动etcd服务

        $ systemctl start etcd
        
      6. 检查错误日志

        $ master-logs etcd etcd
        
    • 在静态etcd pod恢复etcd

      1. 通过将pod的yaml文件移出来暂停etcd pod

        $ mv /etc/origin/node/pods/etcd.yaml .
        
      2. 清除之前的数据

        $ rm -rf /var/lib/etcd
        
      3. 使用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 文件中获得相关的参数

      4. 给相关文件及目录设置相关的selinux权限

        $ restorecon -Rv /var/lib/etcd/
        
      5. 通过将etcd pod的yaml文件恢复到静态pod目录下来重启etcd数据

        $ mv etcd.yaml /etc/origin/node/pods/.
        

使用Ansible添加etcd节点

还原etcd数据后,可以使用ansible或者手动的方式对etcd进行扩容。

添加过程

  1. 在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 
    
  2. 执行ansible扩容ansible脚本

    $ cd /usr/share/ansible/openshift-ansible
    $ ansible-playbook  playbooks/openshift-etcd/scaleup.yml
    
  3. 将[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集群节点上的服务

恢复过程

  1. 在每一个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
    
  2. 在每一个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应用的备份数据恢复应用的例子。

恢复过程

  1. 检查备份数据

    $ 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
    
  2. 使用oc rsync恢复应用数据

    $ oc rsync /tmp/jenkins-backup/jenkins jenkins-1-37nux:/var/lib
    
  3. 重启应用

    $ 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,再恢复数据。

恢复过程

  1. 如果没有挂载PV执行创建新的挂载

    $ oc set volume dc/demo --add --name=persistent-volume \
         --type=persistentVolumeClaim --claim-name=filestore \ --mount-path=/opt/app-root/src/uploaded --overwrite
    
  2. 删除当前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
    
  3. 将之前备份的数据拷贝到对应的目录下

    $ oc rsync uploaded demo-2-fxx6d:/opt/app-root/src/
    
  4. 验证应用数据

    $ oc rsh demo-2-fxx6d
    sh-4.2$ *ls /opt/app-root/src/uploaded/*
    lost+found  ocp_sop.txt
    

实战演练步骤

  1. 部署安装3Master 1etcd及2个Node节点的Openshift集群
  2. 使用恢复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文件中删除。

  1. 按照使用Ansible添加etcd节点中的步骤将1个etcd节点扩容为3个etcd节点
  2. 清理恢复中的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

参考文章

Openshift官方文档之恢复集群

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343