Skip to main content

Etcd 백업 및 복구

ETCD

  • Coreos가 만든 분산 key:value 형태의 데이터 스토리지
  • 쿠버네티스 클러스터의 정보를 저장해서 사용
  • 모든 etcd 데이터는 etcd 데이터베이스 파일에 보관: /var/lib/etcd
  • etcd 관리 명령어: etcdctl
  • etcd --version
  • etcdctl version

Kubernetes는 기반 스토리지(backing storage)로 etcd를 사용하고 있고, 모든 데이터가 etcd에 보관됩니다. 예를 들어, 클러스터에 어떤 노드가 몇 개나 있고 어떤 파드가 어떤 노드에서 동작하고 있는지가 etcd에 기록됩니다. 만약 동작 중인 클러스터의 etcd 데이터베이스가 유실된다면 컨테이너뿐만 아니라 클러스터가 사용하는 모든 리소스가 미아가 되어 버립니다. 따라서 이러한 etcd를 홀수개로 3대 또는 5대, 7대 등으로 운영하여 etcd 공간을 동기화 및 분산, 고가용성을 확보합니다.

Etcd는 Replicated state machine(이하 RSM)입니다. 분산 컴퓨팅 환경에서 서버가 몇 개 다운되어도 잘 동작하는 시스템을 만들고자 할 때 선택하는 방법의 하나로, State Machine Replication이 있습니다. 이는 똑같은 데이터를 여러 서버에 계속하여 복제하는 것이며, 이 방법으로 사용하는 머신을 RSM이라고 합니다.

RSM은 command가 들어있는 log 단위로 데이터를 처리합니다. 데이터의 write를 log append라 부르며, 머신은 받은 log를 순서대로 처리하는 특징을 갖습니다. 하지만, 똑같은 데이터를 여러 서버에 복제해놨다고 해서 모든 게 해결되지는 않습니다. 오히려 더 어려운 문제가 생기기도 합니다. Robust한 RSM을 만들기 위해서는 데이터 복제 과정에 발생할 수 있는 여러 가지 문제를 해결하기 위해 컨센서스(Consensus)를 확보하는 것이 핵심입니다. Consensus를 확보한다는 것은 RSM이 아래 4가지 속성을 만족한다는 것과 의미가 같으며, etcd는 이를 위해 Raft 알고리즘을 사용하였습니다.

  • Safety: 항상 올바른 결과를 리턴
  • Available: 서버가 몇 대 다운되더라도 항상 응답
  • Independent from timing: 네트워크 지연이 발생해도 로그의 일관성이 깨져서는 안됩니다.
  • Reactivity: 모든 서버에 복제되지 않았더라도 조건을 만족하면 빠르게 요청에 응답
cd /var/lib/etcd/

ls
tree

# 현재 context 확인
k config current-context

# 쿠버네티스 운영에 관련된 API들이 실행되는 공간
# kube-system 네임스페이스로 분리
# 쿠버네티스 클러스터가 동작되는데 필요한 파드, 서비스, 볼륨 등 확인
kubectl get pod -n kube-system

# static pod 형태로 저장하는 공간
cd /etc/kubernetes/manifests

ls
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml

cat etcd.yaml
...
- hostPath:
path: /var/lib/etcd # etcd 디렉토리 확인
type: DirectoryOrCreate
name: etcd-data
...

ETCD Backup

  • master 노드의 장애와 같은 예기치 못한 사고로 인해 ETCD 데이터베이스가 유실될 경우를 대비해서 Backup API를 제공
  • /var/lib/etcd에 있는 데이터베이스를 /data/etcd-snapshot.db에 스냅샷으로 백업
  • etcdctl snapshot save [snapshot filename]

ETCD Restore

Snapshot으로 저장한 데이터베이스 파일을 동작중인 etcd에 적용하여 snapshot 생성시점으로 되돌리기

  1. snapshot 파일을 데이터베이스 파일로 복원
  2. 동작중인 etcd 파드의 구성정보를 복원된 데이터베이스 위치로 수정 적용
  • /data/etcd-snapshot.db 스냅샷 파일을 var/lib/etcd-new로 복원해보기
  • etcdctl snapshot restore [snapshot filename]
kubectl config current-context

# example
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> \
snapshot save <backup-file-location>

# trusted-ca-file 디렉토리 검색
ps -ef | grep kube | grep trusted-ca-file

# cert-file 디렉토리 검색
ps -ef | grep kube | grep cert-file

# key-file 디렉토리 검색
ps -ef | grep kube | grep key-file

# 스냅샷 파일을 /tmp/etcd-backup에 저장
sudo ETCDCTL_API=3 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 \
snapshot save /tmp/etcd-backup

# nginx 디플로이먼트 삭제
kubectl get pods
kubectl delete deployment.apps nginx
kubectl get pods

# /var/lib/etcd-new에 restore
# example
ETCDCTL_API=3 etcdctl snapshot restore --data-dir <data-dir-location> snapshotdb

# /var/lib/etcd-new에 restore
sudo ETCDCTL_API=3 etcdctl \
snapshot restore --data-dir /var/lib/etcd-new \
/tmp/etcd-backup

# 디렉토리 확인
sudo tree /var/lib/etcd-new/

# etcd 파드의 데이터 저장소를 /var/libe/etcd-new로 변경
# static pod 구성 정보를 변경할 경우 파드에 반영
sudo vi /etc/kubernetes/manifests/etcd.yaml
...
- hostPath:
path: /var/lib/etcd-new # 변경
type: DirectoryOrCreate
name: etcd-data


# etcd status 확인
# exit -> up
sudo docker ps -a | grep etcd

# pod 확인
kubectl get pods