homelab89 Docs Logs Legacy Files ☰ TOC 🌓
guidek8s 2026-06-29etcdrecoveryraftquorum

05. etcd 복구 절차

복구 시나리오 분류

상황 방법
단일 노드 장애 (데이터 intact) etcd 재시작으로 자동 동기화
단일 노드 장애 (데이터 손상) 멤버 제거 → 재추가
과반수 장애 (데이터 intact) 모든 노드 재시작
전체 장애 / 데이터 손상 스냅샷으로 복구

복구 1: 단일 노드 자동 재동기화

etcd 데이터가 살아있고 단순히 프로세스가 죽은 경우입니다.

# ctrl3 재시작
ssh k8s-ctrl3 "sudo systemctl start etcd"

# Raft 로그 동기화 확인 (수 초 ~ 수십 초)
ssh k8s-ctrl3 "sudo journalctl -u etcd -f | grep -E 'synced|leader'"

# 멤버 상태 확인
ssh k8s-ctrl1 "sudo ETCDCTL_API=3 etcdctl \
  --endpoints=https://203.0.113.11:2379 \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/member-k8s-ctrl1.pem \
  --key=/etc/ssl/etcd/ssl/member-k8s-ctrl1-key.pem \
  endpoint status -w table"

복구 2: 스냅샷 백업 → 복구

스냅샷 생성 (정상 상태에서)

ssh k8s-ctrl1 "sudo ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/member-k8s-ctrl1.pem \
  --key=/etc/ssl/etcd/ssl/member-k8s-ctrl1-key.pem \
  snapshot save /tmp/etcd-snapshot-$(date +%Y%m%d-%H%M%S).db"

# 스냅샷 검증
ssh k8s-ctrl1 "sudo ETCDCTL_API=3 etcdctl snapshot status /tmp/etcd-snapshot-*.db -w table"

전체 클러스터 스냅샷 복구 절차

이 절차는 etcd 데이터가 완전히 유실된 극단적 상황에서 사용합니다. 모든 노드에서 동시에 진행해야 합니다.

Step 1: 모든 etcd + kube-apiserver 정지

for node in k8s-ctrl1 k8s-ctrl2 k8s-ctrl3; do
    ssh $node "sudo systemctl stop etcd kube-apiserver"
done

Step 2: 기존 etcd 데이터 백업 (혹시 모를 상황 대비)

for node in k8s-ctrl1 k8s-ctrl2 k8s-ctrl3; do
    ssh $node "sudo mv /var/lib/etcd /var/lib/etcd.bak.$(date +%s)"
done

Step 3: 각 노드에 스냅샷 복사 후 복구

SNAPSHOT="/tmp/etcd-snapshot-20240101-120000.db"

# ctrl1 복구
ssh k8s-ctrl1 "sudo ETCDCTL_API=3 etcdctl snapshot restore ${SNAPSHOT} \
  --name=k8s-ctrl1 \
  --initial-cluster=k8s-ctrl1=https://203.0.113.11:2380,k8s-ctrl2=https://203.0.113.12:2380,k8s-ctrl3=https://203.0.113.13:2380 \
  --initial-advertise-peer-urls=https://203.0.113.11:2380 \
  --data-dir=/var/lib/etcd"

# ctrl2 복구
ssh k8s-ctrl2 "sudo ETCDCTL_API=3 etcdctl snapshot restore ${SNAPSHOT} \
  --name=k8s-ctrl2 \
  --initial-cluster=k8s-ctrl1=https://203.0.113.11:2380,k8s-ctrl2=https://203.0.113.12:2380,k8s-ctrl3=https://203.0.113.13:2380 \
  --initial-advertise-peer-urls=https://203.0.113.12:2380 \
  --data-dir=/var/lib/etcd"

# ctrl3 복구
ssh k8s-ctrl3 "sudo ETCDCTL_API=3 etcdctl snapshot restore ${SNAPSHOT} \
  --name=k8s-ctrl3 \
  --initial-cluster=k8s-ctrl1=https://203.0.113.11:2380,k8s-ctrl2=https://203.0.113.12:2380,k8s-ctrl3=https://203.0.113.13:2380 \
  --initial-advertise-peer-urls=https://203.0.113.13:2380 \
  --data-dir=/var/lib/etcd"

Step 4: etcd 재시작

for node in k8s-ctrl1 k8s-ctrl2 k8s-ctrl3; do
    ssh $node "sudo systemctl start etcd"
done

# 클러스터 상태 확인
sleep 10
ssh k8s-ctrl1 "sudo ETCDCTL_API=3 etcdctl \
  --endpoints=https://203.0.113.11:2379,https://203.0.113.12:2379,https://203.0.113.13:2379 \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/member-k8s-ctrl1.pem \
  --key=/etc/ssl/etcd/ssl/member-k8s-ctrl1-key.pem \
  endpoint health -w table"

Step 5: kube-apiserver 재시작

for node in k8s-ctrl1 k8s-ctrl2 k8s-ctrl3; do
    ssh $node "sudo systemctl start kube-apiserver"
done

kubectl get nodes

복구 3: virsh 스냅샷으로 VM 롤백 (빠른 리셋)

실험이 잘못됐을 때 VM 레벨에서 롤백하는 방법입니다.

# 실험 전 스냅샷 생성 (항상 먼저 찍어두기)
for i in 1 2 3; do
    virsh snapshot-create-as k8s-ctrl${i} \
        "pre-experiment-$(date +%Y%m%d)" \
        "실험 전 안전 스냅샷"
done

# 스냅샷 목록 확인
virsh snapshot-list k8s-ctrl1

# 스냅샷으로 롤백 (VM 실행 중에도 가능)
for i in 1 2 3; do
    virsh snapshot-revert k8s-ctrl${i} "pre-experiment-20240101"
done

# 롤백 후 VM 시작
for i in 1 2 3; do
    virsh start k8s-ctrl${i}
done

복구 후 K8s 상태 검증 체크리스트

# 1. 노드 Ready 상태 확인
kubectl get nodes

# 2. 시스템 파드 정상 여부
kubectl get pods -n kube-system

# 3. etcd 멤버 동기화 확인
ssh k8s-ctrl1 "etcdctl member list -w table"
ssh k8s-ctrl1 "etcdctl endpoint status -w table"

# 4. 간단한 워크로드 배포 테스트
kubectl create deployment verify-nginx --image=nginx --replicas=3
kubectl get pods -l app=verify-nginx
kubectl delete deployment verify-nginx

# 5. PVC 테스트 (있는 경우)
kubectl get pv,pvc -A

Files