kubernetes cluster에 배포되어 있는 pod, service, deployment 등등의 kubernetes resource들을 backup하여 저장하고 싶다면 어떻게해야할까??
이 경우 kube-apiserver
에 resource configuration을 요청하는 방식이 있다.
kubectl get all --all-namesapces -o yaml > all-deploy-services.yaml
위 방식은 kubectl get all
명령어를 통해서 cluster에 배포된 resource들의 yaml file을 가져와 all-deploy-services.yaml
에 저장하는 방식이다.
이러한 방식 말고도 더 좋은 방법이 있는데, etcd
를 backup하는 방식이다. 왜냐하면 kubernetes cluster의 resource들이 모두 etcd에 저장되어 있기 때문이다.
일반적으로 etcd
는 각 master node에 있고, 어딘가에 분산 data를 저장한다. 이 분산 data 저장 위치는 etcd.service
나 pod manifest의 volume을 통해 얻을 수 있다.
ExecStart=/usr/local/bin/etcd \\
--name ${ETCD_NAME} \\
...
--data-dir=/var/lib/etcd
--data-dir
에 표시된 곳이 바로 etcd가 데이터를 저장하는 곳이고, backup의 타겟이되는 위치인 것이다.
etcd pod가 있는 경우는 다음의 통해서 얻을 수 있다.
volumes:
...
- hostPath:
path: /var/lib/etcd
type: DirectoryOrCreate
name: etcd-data
/var/lib/etcd
가 바로 --data-dir
에 해당하는 부분인 것이다.
etcd
를 backup하는 가장 손쉬운 방법은 snapshot
을 사용하는 것이다.
ETCDCTL_API=3 etcdctl snapshot save snapshot.db
현재의 etcd data, 즉 /var/lib/etcd
에 있는 data를 snapshot.db
라는 스냅샷으로 찍는 것이다.
다음의 명령어의 결과는 아래와 같다.
ls
snapshot.db
snapshot.db
가 만들어진 것을 볼 수 있다.
snapshot.db
내부가 어떻게 생겼는 지를 알기위해서는 status
를 사용하면 된다.
ETCDCTL_API=3 etcdctl snapshot status snapshot.db
그럼 해당 snapshot
을 사용하여 data를 복구하려면 어떻게해야할까?? 먼저 kube-apiserver
를 잠시 종료시켜준다.
service kube-apiserver stop
왜 kube-apiserver
를 종료시켜주냐면, etcd cluster
를 재시작하는데 있어서 kube-apiserver
가 etcd cluster
에 의존하고 있어, 재시작 중 에러가 발생할 수 있기 때문이다.
이 다음 etcdctl
을 이용하여 data를 복구하도록 한다.
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db --data-dir /var/lib/etcd-from-backup
snapshot.db
의 내용을 /var/lib/etcd-from-backup
에 복구하도록 한 것이다. 왜 이전 data path가 아니라 새로운 data path를 지정했냐면, 기존의 남아있던 data path와 현재의 복구한 내용이 충돌을 발생시킬 수 있기 때문이다.
위와 같이 --data-dir
을 바꾸는 경우는 etcd
pod에서 volume에 대한 정의를 --data-dir
에서 지시한 곳으로 변경해야한다.
systemctl
에서의 etcd.service
를 수정하면 된다.
vi /etc/systemd/system/etcd.service
[Service]
User=etcd
Type=notify
ExecStart=/usr/local/bin/etcd \
--name etcd-server \
--data-dir=/var/lib/etcd-data \
/var/lib/etcd-data
을 /var/lib/etcd-from-backup
으로 바꾸면 된다.
[Service]
User=etcd
Type=notify
ExecStart=/usr/local/bin/etcd \
--name etcd-server \
--data-dir=/var/lib/etcd-data-new \
다음과 같이 바꾸고 저장하면 된다.
이제 service
daemon을 재시작하고 etcd
service를 재시작해주도록 하자.
systemctl daemon-reload
systemctl restart etcd
마지막으로 kube-apiserver
를 다시 실행시켜준다.
systemctl kube-apiserver start
이제 우리의 cluster가 정상 작동하면서, 이전의 data를 가지고 있게 된다.
참고로, 위의 방식은 etcd
가 외부 설치되었을 때 설정하는 방법이다. 만약 kubernetes master node에 etcd
가 설치되었다면, 바로 etcdctl
을 통해서 snapshot restore 후에 etcd pod의 volume을 --data-dir
로만 바꿔주면 된다. 즉 굳이 service
명령어를 쓸 필요가 없다.
단, mastert node와 etcd가 같이 설치된 경우에는 다음과 같이 pod의 yaml 명세를 바꾸어야 한다.
가령 아래는 etcd
pod yaml파일이다. 보통 /etc/kubernetes/manifests/etcd.yaml
에 있기 때문에, 이 파일을 직접 바꾸면 반영이 된다.
volumes:
...
- hostPath:
path: /var/lib/etcd
type: DirectoryOrCreate
name: etcd-data
/var/lib/etcd
이 부분을 --data-dir
이 명시하고 있는 /var/lib/etcd-from-backup
으로 바꾸어야 한다는 것이다.
volumes:
...
- hostPath:
path: /var/lib/etcd-from-backup
type: DirectoryOrCreate
name: etcd-data
이렇게 바꾸면 된다.
한 가지 명심할 것은 etcdctl
로 save
를 사용할 때는 etcd
에 접근해야하므로 다음과 같이 endpoint와 cert를 설정해주어야 한다.
ETCDCTL_API=3 etcdctl snapshot save snapshot.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/ca.crt \
--cert=/etc/etcd/etcd-server.crt \
--key=/etc/etcd/etcd-server.key
만약 위처럼 endpoint, cacert, cery, key를 안써주면 다음과 같은 error가 발생한다.
Error: rpc error: code = Unavailable desc = transport is closing
또한 backup과 restore 기능을 사용하기 위해서 etcdctl은 반드시 3이상의 version을 사용해야하기 때문에 ETCDCTL_API=3
을 써주는 것이다.
가령 kubectl describe
을 통해 etcd pod의 flag들을 가져와서 다음을 얻었다고 하자.
Command:
etcd
..
--cert-file=/etc/kubernetes/pki/etcd/server.crt
--client-cert-auth=true
--data-dir=/var/lib/etcd
...
--key-file=/etc/kubernetes/pki/etcd/server.key
--listen-client-urls=https://127.0.0.1:2379,https://192.30.39.9:2379
...
--trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
cert-file
, key-file
, trusted-ca-file
에 해당하는 값들을 etcdctl
의 flag에 써주면 된다.
ETCDCTL_API=3 etcdctl snapshot save /opt/snapshot-pre-boot.db \ --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
참고로 --endpoints
는 listen-client-urls
의 값으로 생각하면 된다.
마지막으로 etcdctl
을 통해서 etcd cluster의 구성을 볼 수 있는데, etcdctl member
를 사용하면 된다.
etcdctl member list
13:54:06 up 56 min, 1 user, load average: 11.46, 9.75, 9.31
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.28.177.9 13:50 6.00s 0.08s 0.00s w
1개의 member로만 이루어진 것을 알 수 있다.
정리하자면 master node에 etcd
가 있으면 해당 master node에서 etcdctl
을 통해 snapshot
을 save
하는 backup부분과 restore를 모두 할 수 있다. 이후 etcd pod manifest를 수정하여 data path를 변경해주면 자동으로 설정된다.
만약 master node에 etcd
가 없으면 외부etcd
와 연결된 것이기 때문에, master node에서 etcdctl
을 통해서 backup은 가능하지만, restore은 직접 etcd
가 있는 외부 서버에 접근하여 etcdctl
로 restore
를 해주어야 한다. 또한, restore
이후에는 systemctl
의 etcd.service
를 수정하여 data path를 변경해주고 재시작해주어야 한다.
kubernetes cluster는 하나의 host에 여러 개 있을 수 있다. 현재 cluster가 몇 개 있는 지는 다음의 명령어를 통해서 알 수 있다.
kubectl config get-clusters
NAME
cluster1
cluster2
현재 host에 두 개의 cluster가 있는 것을 알 수 있다.
참고로, context 변경을 통해서 kubectl
의 타겟이 되는 각 cluster를 변경할 수 있다.
cluster1으로 context를 변경하기 위해서는 다음의 명령어를 사용하면 된다.
kubectl config use-context cluster1
Switched to context "cluster1".