Lab 40 - etcd snapshot and restore
Lab 40 - etcd snapshot and restore
Goal: save the complete cluster state, make a “fatal mistake”, and roll the whole cluster back to the snapshot. Chapter: Backup and disaster recovery
This lab rewinds the entire cluster. Everything created after the snapshot disappears. Trainer: take a VM snapshot of control01 before the lab.
Tools on control01
# 1 - which etcd version runs? (on support01)
kubectl get pod -n kube-system etcd-control01 -o jsonpath='{.spec.containers[0].image}{"\n"}'
# 2 - matching etcdctl / etcdutl on control01
ssh student@control01
ETCD_VER=v3.6.5 # <- the version from step 1, with "v", without "-0"
curl -fsSL https://github.com/etcd-io/etcd/releases/download/$ETCD_VER/etcd-$ETCD_VER-linux-amd64.tar.gz \
| tar xz -C /tmp
sudo mv /tmp/etcd-$ETCD_VER-linux-amd64/etcdctl /tmp/etcd-$ETCD_VER-linux-amd64/etcdutl /usr/local/bin/
etcdctl version
alias ectl='sudo etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key'
ectl endpoint health
ectl member list -w table
exit
State worth saving
# 3 - on support01
kubectl create ns precious
kubectl create deploy vault -n precious --image nginx:1.27 --replicas 2
kubectl create cm before-snapshot --from-literal=state=old
Snapshot
# 4 - on control01
ssh student@control01
alias ectl='sudo etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key'
ectl snapshot save /root/etcd-snap.db
sudo etcdutl snapshot status /root/etcd-snap.db -w table
sudo cp /root/etcd-snap.db /tmp/ && sudo chmod 644 /tmp/etcd-snap.db
exit
scp student@control01:/tmp/etcd-snap.db ~/etcd-snap-$(date +%F).db # off the node!
The file holds every object of the cluster, including all Secrets - store it like a password.
The fatal mistake
# 5 - on support01
kubectl delete ns precious
kubectl delete cm before-snapshot
kubectl create cm after-snapshot --from-literal=state=new
kubectl get ns precious # NotFound
Restore
# 6 - on control01: restore into a NEW data directory
ssh student@control01
sudo etcdutl snapshot restore /root/etcd-snap.db --data-dir /var/lib/etcd-restore
sudo ls /var/lib/etcd-restore # member
# 7 - point the etcd static Pod at it (back up the manifest first)
sudo cp /etc/kubernetes/manifests/etcd.yaml /root/etcd.yaml.bak
sudo sed -i 's#path: /var/lib/etcd$#path: /var/lib/etcd-restore#' /etc/kubernetes/manifests/etcd.yaml
sudo grep -n -A2 'hostPath' /etc/kubernetes/manifests/etcd.yaml | grep etcd
The kubelet restarts etcd on the restored data; the API server reconnects. Give it one to two minutes.
# 8 - wait, then back to support01
watch -n 5 'sudo crictl ps --name "etcd|kube-apiserver"' # both Running; Ctrl-C
exit
kubectl get ns precious # back
kubectl get deploy -n precious
kubectl get cm before-snapshot after-snapshot # before: yes, after: NotFound
The cluster is exactly where it was at step 4 - including things you did not want to lose after step 4.
Not coming back? On control01:
sudo cp /root/etcd.yaml.bak /etc/kubernetes/manifests/etcd.yaml returns to
the old data. sudo crictl logs $(sudo crictl ps -a --name etcd -q | head -1)
shows why etcd refused to start.
Discovery
InfodiscoverTask A. Make the snapshot a nightly job on control01 that keeps 7 days.
Task B. Which is the better tool to bring back the deleted namespace
precious alone, without rewinding everything else - and why?
Clean up
kubectl delete ns precious; kubectl delete cm before-snapshot