etcd备份

所有master节点上先复制出容器里的etcdctl

  1. docker cp `docker ps -a | awk '/k8s_etcd/{print $1}'|head -n1`:/usr/local/bin/etcdctl /usr/local/bin/etcdctl

编写一个简单别名,记得替换对应的ip

  1. cat >/etc/profile.d/etcd.sh<<'EOF'
  2. ETCD_CERET_DIR=/etc/kubernetes/pki/etcd/
  3. ETCD_CA_FILE=ca.crt
  4. ETCD_KEY_FILE=healthcheck-client.key
  5. ETCD_CERT_FILE=healthcheck-client.crt
  6. ETCD_EP=https://192.168.33.101:2379,https://192.168.33.102:2379,https://192.168.33.103:2379
  7. alias etcd_v3="ETCDCTL_API=3 \
  8. etcdctl \
  9. --cert ${ETCD_CERET_DIR}/${ETCD_CERT_FILE} \
  10. --key ${ETCD_CERET_DIR}/${ETCD_KEY_FILE} \
  11. --cacert ${ETCD_CERET_DIR}/${ETCD_CA_FILE} \
  12. --endpoints $ETCD_EP"
  13. EOF
  1. source /etc/profile.d/etcd.sh
  1. etcd_v3 endpoint status --write-out=table
  2. +-----------------------------+------------------+---------+---------+-----------+-----------+------------+
  3. | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
  4. +-----------------------------+------------------+---------+---------+-----------+-----------+------------+
  5. | https://192.168.33.101:2379 | c724c500884441af | 3.3.17 | 1.6 MB | true | 7 | 1865 |
  6. | https://192.168.33.102:2379 | 3dcceec24ad5c5d4 | 3.3.17 | 1.6 MB | false | 7 | 1865 |
  7. | https://192.168.33.103:2379 | bc21062efb4a5d4c | 3.3.17 | 1.5 MB | false | 7 | 1865 |
  8. +-----------------------------+------------------+---------+---------+-----------+-----------+------------+
  1. etcd_v3 endpoint health --write-out=table
  2. +-----------------------------+--------+-------------+-------+
  3. | ENDPOINT | HEALTH | TOOK | ERROR |
  4. +-----------------------------+--------+-------------+-------+
  5. | https://192.168.33.103:2379 | true | 19.288026ms | |
  6. | https://192.168.33.102:2379 | true | 19.2603ms | |
  7. | https://192.168.33.101:2379 | true | 22.490443ms | |
  8. +-----------------------------+--------+-------------+-------+

配置etcd备份脚本
记得替换对应的ip

  1. mkdir -p /opt/etcd
  2. cat>/opt/etcd/etcd_cron.sh<<'EOF'
  3. #!/bin/bash
  4. set -e
  5. source /etc/profile
  6. export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  7. master=`ETCDCTL_API=3 etcdctl --endpoints="https://192.168.33.101:2379,https://192.168.33.102:2379,https://192.168.33.103:2379" --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt endpoint status | grep true|awk -F"," '{print $1}'`
  8. : ${bak_dir:=/root/} #缺省备份目录,可以修改成存在的目录
  9. : ${cert_dir:=/etc/kubernetes/pki/etcd/}
  10. : ${endpoints:=$master}
  11. bak_prefix='etcd-'
  12. cmd_suffix='date +%Y-%m-%d-%H-%M'
  13. bak_suffix='.db'
  14. #将规范化后的命令行参数分配至位置参数($1,$2,...)
  15. temp=`getopt -n $0 -o c:d: -u -- "$@"`
  16. [ $? != 0 ] && {
  17. echo '
  18. Examples:
  19. # just save once
  20. bash $0 /tmp/etcd.db
  21. # save in contab and keep 5
  22. bash $0 -c 5
  23. '
  24. exit 1
  25. }
  26. set -- $temp
  27. # -c 备份保留副本数量
  28. # -d 指定备份存放目录
  29. while true;do
  30. case "$1" in
  31. -c)
  32. [ -z "$bak_count" ] && bak_count=$2
  33. printf -v null %d "$bak_count" &>/dev/null || \
  34. { echo 'the value of the -c must be number';exit 1; }
  35. shift 2
  36. ;;
  37. -d)
  38. [ ! -d "$2" ] && mkdir -p $2
  39. bak_dir=$2
  40. shift 2
  41. ;;
  42. *)
  43. [[ -z "$1" || "$1" == '--' ]] && { shift;break; }
  44. echo "Internal error!"
  45. exit 1
  46. ;;
  47. esac
  48. done
  49. etcd::cron::save(){
  50. cd $bak_dir/
  51. ETCDCTL_API=3 etcdctl --endpoints=$endpoints --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt snapshot save $bak_prefix$($cmd_suffix)$bak_suffix
  52. rm_files=`ls -t $bak_prefix*$bak_suffix | tail -n +$[bak_count+1]`
  53. if [ -n "$rm_files" ];then
  54. rm -f $rm_files
  55. fi
  56. }
  57. main(){
  58. [ -n "$bak_count" ] && etcd::cron::save || etcd_v3 snapshot save $@
  59. }
  60. main $@
  61. EOF

image.png
备份

bash /opt/etcd/etcd_cron.sh  -c 4 -d /opt/etcd/

image.png
定时备份
crontab -e添加下面内容自动保留四个备份副本

0 * * * * bash /opt/etcd/etcd_cron.sh  -c 4 -d /opt/etcd/ &>/dev/null

etcd还原

举个例子,先查看default下资源,发现一个pod 一个deployemnt 一个svc

 kubectl get all

image.png
先备份一下当前的信息

bash /opt/etcd/etcd_cron.sh  -c 4 -d /tmp

image.png
将备份信息发给其他2个master节点
image.png
删掉pod deployment svc
image.png

还原备份记录到新的存储目录

在3个etcd节点都执行一遍还原操作
master01

ETCDCTL_API=3 etcdctl \
     --cacert=/etc/kubernetes/pki/etcd/ca.crt \
     --name=master01 \
     --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key \
     --data-dir /var/lib/etcd-from-backup \
     --initial-cluster=master01=https://192.168.33.101:2380,master02=https://192.168.33.102:2380,master03=https://192.168.33.103:2380 \
     --initial-cluster-token=etcd-cluster-1 \
     --initial-advertise-peer-urls=https://192.168.33.101:2380 \
     snapshot restore /tmp/etcd-2020-06-10-07-21.db

master02

ETCDCTL_API=3 etcdctl \
     --cacert=/etc/kubernetes/pki/etcd/ca.crt \
     --name=master02 \
     --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key \
     --data-dir /var/lib/etcd-from-backup \
     --initial-cluster=master01=https://192.168.33.101:2380,master02=https://192.168.33.102:2380,master03=https://192.168.33.103:2380 \
     --initial-cluster-token=etcd-cluster-1 \
     --initial-advertise-peer-urls=https://192.168.33.102:2380 \
     snapshot restore /tmp/etcd-2020-06-10-07-21.db

master03

ETCDCTL_API=3 etcdctl \
     --cacert=/etc/kubernetes/pki/etcd/ca.crt \
     --name=master03 \
     --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key \
     --data-dir /var/lib/etcd-from-backup \
     --initial-cluster=master01=https://192.168.33.101:2380,master02=https://192.168.33.102:2380,master03=https://192.168.33.103:2380 \
     --initial-cluster-token=etcd-cluster-1 \
     --initial-advertise-peer-urls=https://192.168.33.103:2380 \
     snapshot restore /tmp/etcd-2020-06-10-07-21.db

统计修改3个节点上的/etc/kubernetes/manifests/etcd.yaml
更新—data-dir

--data-dir=/var/lib/etcd-from-backup

添加 initial-cluster-token

--initial-cluster-token=etcd-cluster-1

更新—initial-cluste

--initial-cluster=master01=https://192.168.33.101:2380,master02=https://192.168.33.102:2380,master03=https://192.168.33.103:2380

更新- —initial-cluster-state

- --initial-cluster-state=new

image.png
更新目录

   volumeMounts:
    - mountPath: /var/lib/etcd-from-backup
      name: etcd-data
    - mountPath: /etc/kubernetes/pki/etcd
      name: etcd-certs
  hostNetwork: true
  priorityClassName: system-cluster-critical
  volumes:
  - hostPath:
      path: /var/lib/etcd-from-backup
      type: DirectoryOrCreate
    name: etcd-data
  - hostPath:
      path: /etc/kubernetes/pki/etcd
      type: DirectoryOrCreate
    name: etcd-certs

image.png
然后保存退出即可
之后发现已还原
image.png
如果遇到3个etcd 一直处于pending时,重启主机即可。