LabHub
배우기 러닝패스 코스

Kubernetes運用実務

etcdのスナップショットを取り検証する

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

살아 있는 etcd 의 상태를 확인하고, 스냅샷을 뜨고, 그 스냅샷이 실제로 쓸 수 있는 물건인지 기계적으로 검증하는 절차를 손에 익힙니다.

왜 중요한가

백업은 만드는 것보다 믿을 수 있게 만드는 것이 어렵습니다. 매일 도는 CronJob 이 매일 0바이트 파일을 남기고 있어도 아무 알람이 울리지 않는 시스템이 현실에는 아주 많습니다. 그래서 이 실습은 파일을 만드는 단계와 그 파일을 판정하는 단계를 나눕니다. snapshot status 가 돌려주는 revision, totalKey, hash 세 값은 각각 "언제 시점인가", "얼마나 담겼는가", "깨지지 않았는가"에 대한 답입니다. 이 셋을 스크립트가 읽어 OK 를 내도록 만들면, 백업의 성공 여부가 사람의 눈이 아니라 종료 코드로 표현됩니다. 또 하나, 쿼럼은 장애를 막아 주지만 오삭제를 막아 주지 못한다는 점을 멤버 수 계산과 함께 새겨 두세요. 멤버가 셋이든 다섯이든, 잘못된 삭제는 성실하게 전 멤버에 복제됩니다.

단계

  1. etcdctl --endpoints=127.0.0.1:2379 endpoint health 의 출력을 /root/etcd/backup/out/health.txt 에 저장하세요. 파일 안에 healthy 와 엔드포인트 포트 2379 가 보여야 하고 unhealthy 라는 단어는 없어야 합니다.
  2. etcdctl member list 출력을 /root/etcd/backup/out/members.txt 에 저장하세요(16진수 멤버 ID 와 2379/2380 주소가 포함돼야 합니다). 이어서 /root/etcd/backup/out/quorum.txtmembers=<멤버 수>quorum=<과반 수> 두 줄을 적으세요. 이 랩의 etcd 는 단일 멤버이므로 members=1, quorum=1 이 됩니다.
  3. 스냅샷을 /root/etcd/backup/snap-01.db 로 저장하세요. 파일 크기가 20000 바이트 이상이어야 합니다.
  4. snapshot status 를 JSON 형식으로 실행해 결과를 /root/etcd/backup/out/snap-01.json 에 저장하세요. revision 이 0보다 크고 totalKey 가 20보다 크며 hash 가 0이 아니어야 합니다.
  5. /registry 접두어 아래 키 개수를 세어 숫자만 /root/etcd/backup/out/key-count.txt 에 넣으세요(20 이상이어야 합니다). 그리고 리소스 종류별 키 개수 상위 목록을 /root/etcd/backup/out/top-prefixes.txt 에 저장하세요. 이 파일에는 pods, configmaps, secrets, leases, events, namespaces 중 하나 이상의 이름이 들어 있어야 합니다.
  6. 네임스페이스 etcd-lab 을 만들고 그 안에 ConfigMap etcd-lab-markerdata.owner=platform 으로 만드세요. 그다음 두 번째 스냅샷을 /root/etcd/backup/snap-02.db 로 뜨고 검증 결과를 /root/etcd/backup/out/snap-02.json 에 저장하세요. 두 번째 JSON 의 revision 이 첫 번째보다 커야 합니다.
  7. /root/etcd/backup/cronjob.yaml 에 정기 백업 명세를 작성하세요. kind: CronJob, metadata.namespace: kube-system, spec.schedule: "0 */6 * * *" 입니다. 컨테이너의 command 는 리스트 형태이며 그 안에 snapshot save--endpoints, --cacert, --cert, --key 네 플래그, 그리고 find-mtime +7 을 쓴 삭제 명령이 모두 들어가야 합니다. 파드 명세에는 hostPath/etc/kubernetes/pki/etcd 인 볼륨, 키에 control-plane 이 들어가는 nodeSelector, 그리고 tolerations 가 있어야 합니다. 볼륨은 모두 hostPath 형식으로 쓰세요.
  8. /root/etcd/backup/verify.sh 를 실행 권한이 있는 스크립트로 만드세요. 인자로 받은 스냅샷이 정상이면 첫 줄에 OK <revision> <keys> 형식(공백 구분, 숫자 두 개)을 출력하고, 아니면 OK 로 시작하지 않는 줄을 출력해야 합니다. 이 스크립트로 snap-01.db 결과를 /root/etcd/backup/out/verify-01.txt 에, snap-02.db 결과를 /root/etcd/backup/out/verify-02.txt 에 저장하세요. 마지막으로 일부러 망가뜨린 파일을 하나 만들어 검증한 결과를 /root/etcd/backup/out/verify-bad.txt 에 남기세요.

참고

백업 전에 etcd 건강 상태 확인하기

etcdctl --endpoints=127.0.0.1:2379 endpoint health 의 출력을 /root/etcd/backup/out/health.txt 에 저장하세요. 파일 안에 healthy 와 엔드포인트 포트 2379 가 보여야 하고 unhealthy 라는 단어는 없어야 합니다.

아픈 etcd 를 백업하면 아픈 스냅샷이 나옵니다. etcdctl 의 endpoint 계열 하위 명령 중 건강을 보는 것을 쓰고, 출력을 파일로 남기세요. 이 랩은 클라이언트 TLS 가 없어 인증서 플래그가 필요 없습니다.

멤버 목록과 쿼럼 계산하기

etcdctl member list 출력을 /root/etcd/backup/out/members.txt 에 저장하세요(16진수 멤버 ID 와 2379/2380 주소가 포함돼야 합니다). 이어서 /root/etcd/backup/out/quorum.txtmembers=<멤버 수>quorum=<과반 수> 두 줄을 적으세요. 이 랩의 etcd 는 단일 멤버이므로 members=1, quorum=1 이 됩니다.

member list 로 실제 멤버를 보고, 쿼럼은 과반입니다. 멤버 N 개의 과반은 N 을 2로 나눈 몫에 1을 더한 값이라는 점을 기억하세요.

첫 스냅샷 뜨기

스냅샷을 /root/etcd/backup/snap-01.db 로 저장하세요. 파일 크기가 20000 바이트 이상이어야 합니다.

snapshot save 뒤에 저장할 파일 경로를 붙입니다. 결과 파일 크기가 수십 KB 이상 나오는지 확인하세요 — 0바이트 백업은 흔한 사고입니다.

스냅샷을 JSON 으로 검증하기

snapshot status 를 JSON 형식으로 실행해 결과를 /root/etcd/backup/out/snap-01.json 에 저장하세요. revision 이 0보다 크고 totalKey 가 20보다 크며 hash 가 0이 아니어야 합니다.

뜬 것과 쓸 수 있는 것은 다릅니다. snapshot status-w json 을 주면 hash, revision, totalKey 가 JSON 한 줄로 나옵니다. 경고 메시지는 표준 오류로 나가니 리다이렉션에 섞이지 않습니다.

etcd 안에 무엇이 얼마나 있는지 세기

/registry 접두어 아래 키 개수를 세어 숫자만 /root/etcd/backup/out/key-count.txt 에 넣으세요(20 이상이어야 합니다). 그리고 리소스 종류별 키 개수 상위 목록을 /root/etcd/backup/out/top-prefixes.txt 에 저장하세요. 이 파일에는 pods, configmaps, secrets, leases, events, namespaces 중 하나 이상의 이름이 들어 있어야 합니다.

쿠버네티스 오브젝트는 모두 /registry 접두어 아래 있습니다. get 에 접두어 조회 옵션과 키만 출력하는 옵션을 주고, 리소스 종류는 키 경로의 세 번째 조각입니다.

변경을 만들고 두 번째 스냅샷 뜨기

네임스페이스 etcd-lab 을 만들고 그 안에 ConfigMap etcd-lab-markerdata.owner=platform 으로 만드세요. 그다음 두 번째 스냅샷을 /root/etcd/backup/snap-02.db 로 뜨고 검증 결과를 /root/etcd/backup/out/snap-02.json 에 저장하세요. 두 번째 JSON 의 revision 이 첫 번째보다 커야 합니다.

오브젝트를 하나 만들면 revision 이 올라갑니다. 두 스냅샷의 revision 을 비교하면 백업 시점의 의미가 손에 잡힙니다. 만든 다음에 떠야 한다는 순서가 핵심입니다.

정기 백업 CronJob 명세 쓰기

/root/etcd/backup/cronjob.yaml 에 정기 백업 명세를 작성하세요. kind: CronJob, metadata.namespace: kube-system, spec.schedule: "0 */6 * * *" 입니다. 컨테이너의 command 는 리스트 형태이며 그 안에 snapshot save--endpoints, --cacert, --cert, --key 네 플래그, 그리고 find-mtime +7 을 쓴 삭제 명령이 모두 들어가야 합니다. 파드 명세에는 hostPath/etc/kubernetes/pki/etcd 인 볼륨, 키에 control-plane 이 들어가는 nodeSelector, 그리고 tolerations 가 있어야 합니다. 볼륨은 모두 hostPath 형식으로 쓰세요.

etcd 는 컨트롤 플레인에만 있고 거기엔 테인트가 걸려 있습니다. 인증서는 호스트 경로에서 마운트하고, 오래된 파일을 지우는 보관 정책도 명령에 넣으세요.

스냅샷 검증 스크립트 만들기

/root/etcd/backup/verify.sh 를 실행 권한이 있는 스크립트로 만드세요. 인자로 받은 스냅샷이 정상이면 첫 줄에 OK <revision> <keys> 형식(공백 구분, 숫자 두 개)을 출력하고, 아니면 OK 로 시작하지 않는 줄을 출력해야 합니다. 이 스크립트로 snap-01.db 결과를 /root/etcd/backup/out/verify-01.txt 에, snap-02.db 결과를 /root/etcd/backup/out/verify-02.txt 에 저장하세요. 마지막으로 일부러 망가뜨린 파일을 하나 만들어 검증한 결과를 /root/etcd/backup/out/verify-bad.txt 에 남기세요.

정상 파일에는 정해진 형식으로 OK 를 내고, 망가진 파일에는 OK 를 내면 안 됩니다. 검증기가 항상 통과한다면 아무것도 검증하지 않는 것입니다.