130. Cluster Maintenance - Section Introduction
- OS 업그레이드 및 노드 유지보수
- Kubernetes 클러스터 버전 업그레이드
- 백업 및 재해 복구 (Backup & Disaster Recovery)
131. OS Upgrades
공식문서: Safely Drain a Node
왜 drain/cordon이 필요한가?
“노드를 점검/재부팅하기 전에, 그 위에서 돌고 있는 Pod들을 미리 다른 노드로 옮겨놓기 위함”
그냥 노드를 끄면 안 되나?
- 노드가 갑자기 죽으면 → 쿠버네티스가 5분 뒤에야 이상을 감지하고 복구 시작
- 그 5분 동안 서비스 중단 발생
- 단일 Pod(ReplicaSet 아닌 것)는 영영 복구 안됨
drain이 해주는 일:
- 노드에
cordon걸어서 새 Pod 배치 금지 - 기존 Pod들을 정상적으로 종료(graceful) 후 다른 노드에 재배치 유도
- 이 과정에서 Service Endpoint도 자연스럽게 갱신됨 → 무중단
노드 다운 시 Pod 동작
-
노드 다운 → 5분 대기 (pod-eviction-timeout) → Pod를 다른 노드에 재스케줄링
-
ReplicaSet/Deployment로 관리되는 Pod: 다른 노드에 자동 재생성
-
단독 Pod (Bare Pod): 영구 손실 → 복구 불가
ReplicaSet 없이 생성된 Pod는 노드 장애 시 복구되지 않음
drain, cordon, uncordon
| 명령어 | 동작 |
|---|---|
kubectl drain | Pod를 다른 노드로 이동 + 노드를 unschedulable 표시 |
kubectl cordon | 노드를 unschedulable 표시만 (기존 Pod 유지) |
kubectl uncordon | 노드를 다시 schedulable 상태로 복원 |
# 노드 drain (유지보수 전)
kubectl drain node-1 --ignore-daemonsets --force
# 유지보수 완료 후 복원
kubectl uncordon node-1
# 스케줄 방지만 (기존 Pod 유지)
kubectl cordon node-2전체 흐름:
kubectl drain node-1→ node-1 unschedulable, Pod A·B 제거 → node-2에 Pod A·B 재생성- OS 업그레이드 / 패치 수행
kubectl uncordon node-1→ node-1 schedulable 복원- node-2 Pod A·B는 그대로 유지 (기존 Pod는 자동 이동 안 됨)
uncordon후에도 기존 Pod가 자동으로 돌아오진 않음. 새로운 Pod만 해당 노드에 스케줄링됨
drain 옵션
# DaemonSet Pod 무시 (필수 - 없으면 에러)
kubectl drain node-1 --ignore-daemonsets
# ReplicaSet 없는 단독 Pod 강제 삭제
kubectl drain node-1 --ignore-daemonsets --force
# 특정 Pod 제외
kubectl drain node-1 --ignore-daemonsets --pod-selector='app!=critical'132. Lab - OS Upgrades
# 노드 상태 확인
kubectl get nodes
# 노드의 Pod 확인
kubectl get pods -o wide | grep node-1
# 특정 노드의 Pod 중 ReplicaSet 없는 것 확인
kubectl get pods -o wide --field-selector spec.nodeName=node01
# drain → 유지보수 → uncordon 전체 흐름
kubectl drain node01 --ignore-daemonsets --force
# ... 유지보수 작업 ...
kubectl uncordon node01133. Kubernetes Releases
공식문서: Releases / Version Skew Policy
버전 체계
| 위치 | 의미 | 빈도 |
|---|---|---|
| 1 (Major) | 큰 변경 | 드물게 |
| 28 (Minor) | 새 기능 | 몇 개월마다 |
| 3 (Patch) | 버그 수정, 보안 패치 | 자주 |
예:
v1.28.3→ Major 1, Minor 28, Patch 3
컴포넌트별 버전
- 모든 Control Plane 컴포넌트가 동일 버전일 필요 없음
- kube-apiserver가 기준 버전
kube-apiserver v1.28 ← 기준
controller-manager v1.28 또는 v1.27 (apiserver -1까지 허용)
kube-scheduler v1.28 또는 v1.27 (apiserver -1까지 허용)
kubelet v1.28 ~ v1.26 (apiserver -2까지 허용)
kube-proxy v1.28 ~ v1.26 (apiserver -2까지 허용)
kubectl v1.29 ~ v1.27 (apiserver ±1 허용)
Kubernetes는 최근 3개 Minor 버전만 지원. 예: v1.28이 최신이면 v1.28, v1.27, v1.26 지원
134. References
135. Cluster Upgrade Introduction
업그레이드 원칙
- 한 번에 하나의 Minor 버전만 업그레이드 (v1.27 → v1.28 → v1.29)
- Master Node 먼저, 그 다음 Worker Node
- Master 업그레이드 중 → 관리 기능 중단, 워크로드는 계속 실행
업그레이드 순서
- Master Node 업그레이드
- API Server / Controller / Scheduler 중단
- 관리 명령 불가 (kubectl 등)
- 기존 Pod / Service는 정상 동작
- 업그레이드 완료 후 재시작
- API Server / Controller / Scheduler 중단
- Worker Node 업그레이드 (아래 3가지 전략)
Worker Node 업그레이드 전략
| 전략 | 설명 | 다운타임 |
|---|---|---|
| 모두 한번에 | 모든 Worker 동시 업그레이드 | O |
| 하나씩 (Rolling) | 노드를 하나씩 drain → 업그레이드 → uncordon | X |
| 새 노드 추가 | 새 버전 노드 추가 → 기존 노드 제거 | X |
kubeadm 업그레이드 명령어
# 1. 업그레이드 계획 확인
kubeadm upgrade plan
# 출력 예시:
# Components that must be upgraded manually after you have upgraded the control plane:
# COMPONENT CURRENT TARGET
# kubelet v1.28.0 v1.29.0
#
# Upgrade to the latest stable version:
# COMPONENT CURRENT TARGET
# kube-apiserver v1.28.0 v1.29.0
# kube-controller-manager v1.28.0 v1.29.0
# kube-scheduler v1.28.0 v1.29.0
# kube-proxy v1.28.0 v1.29.0
# 2. kubeadm 업그레이드
kubeadm upgrade apply v1.29.0kubeadm은 kubelet을 업그레이드하지 않음 → 수동으로 업그레이드 필요
136. Demo - Cluster Upgrade (v1.34 → v1.35)
Control Plane 업그레이드
# 1. 패키지 저장소 업데이트 (v1.34용)
# /etc/apt/sources.list.d/kubernetes.list 에서 버전 변경
# before
# deb [signed-by=...] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /
#
# after (editor로 수정)
# deb [signed-by=...] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /
# 2. kubeadm 업그레이드
apt-get update
apt-get install -y kubeadm=1.35.0-*
# 3. 업그레이드 계획 확인
kubeadm upgrade plan
# 4. 클러스터 업그레이드 적용
kubeadm upgrade apply v1.35.0
# 5. kubelet & kubectl 업그레이드
apt-get install -y kubelet=1.35.0-* kubectl=1.35.0-*
systemctl daemon-reload
systemctl restart kubeletWorker Node 업그레이드
# Control Plane에서:
kubectl drain node01 --ignore-daemonsets
# Worker Node (node01)에서:
# 마찬가지로 패키지 저장소 1.34 -> 1.35 로 수정 후 진행
apt-get update
apt-get install -y kubeadm=1.35.0-*
kubeadm upgrade node
apt-get install -y kubelet=1.35.0-*
systemctl daemon-reload
systemctl restart kubelet
# Control Plane에서:
kubectl uncordon node01전체 업그레이드 흐름 요약
Control Plane
apt update kubeadmkubeadm upgrade plankubeadm upgrade applyapt update kubelet kubectlrestart kubelet
각 Worker Node (반복)
kubectl drain nodeXapt update kubeadmkubeadm upgrade nodeapt update kubeletrestart kubeletkubectl uncordon nodeX
137. Lab - Cluster Upgrade
# 현재 클러스터 버전 확인
kubectl get nodes
# v1.28 이후로 depractaed
kubectl version --short
# kubeadm 현재 버전 확인
kubeadm version
# 업그레이드 가능 버전 확인
kubeadm upgrade plan
# 업그레이드 중 Pod 상태 확인
kubectl get pods -o wide138. Backup and Restore Methods
왜 백업 3가지 방식이 있나?
“클러스터에서 데이터를 잃을 수 있는 층위가 3개이기 때문”
| 데이터 층위 | 잃으면 어떻게 되나? | 백업 방법 |
|---|---|---|
| YAML 정의 (Deployment, Service 등) | 다시 배포 못함 — but 재작성 가능 | Git 저장소 |
| ETCD 데이터 (클러스터 상태 전체) | 클러스터 자체가 사라짐 | etcd snapshot |
| PV 데이터 (사용자 파일) | DB 데이터, 로그, 파일 영구 손실 | 스토리지 벤더 백업 / Velero |
실무 권장:
- 평소엔 GitOps (YAML을 Git으로 관리) 가 본질적으로 백업 역할
- 재해 복구용으로 주기적 etcd snapshot
- 중요 PV는 Velero 또는 클라우드 스냅샷 병행
백업 대상 3가지
- Resource Configs (YAML 파일) → Git 저장소에 보관 (가장 권장)
- ETCD Cluster →
etcdctl snapshot - Persistent Volumes → 별도 스토리지 백업 (Velero 등)
방법 1: Resource Config 백업
# 모든 리소스를 YAML로 추출
kubectl get all --all-namespaces -o yaml > all-deploy-services.yaml
# 도구 사용 (Velero 등)
# Velero는 Kubernetes 리소스 + PV를 함께 백업/복원 가능방법 2: ETCD Snapshot 백업
etcdctl vs etcdutl
- etcdctl: online tool — 실행 중인 etcd 서버와 통신하는 클라이언트. 인증서 3종 필수
- etcdutl: offline tool (etcd v3.5+) — 로컬 스냅샷 파일만으로 동작. 인증서 불필요
- Save(백업): 살아있는 etcd 서버에 접근해야 하므로
etcdctl만 가능- Restore/Status: 로컬 파일 작업이므로
etcdutl권장 (etcd v3.6부터etcdctl snapshot restore는 제거됨)
Snapshot Save — etcdctl 전용
# ETCD 스냅샷 생성 (살아있는 etcd 서버 필요)
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.keySnapshot Status — 둘 다 가능
# etcdctl 방식 (서버 통신, 인증서 필요)
ETCDCTL_API=3 etcdctl snapshot status /opt/snapshot-pre-boot.db --write-out=table
# etcdutl 방식 (로컬 파일 작업, 인증서 불필요 - 권장)
etcdutl snapshot status /opt/snapshot-pre-boot.db --write-out=tableETCD Restore 절차
1. kube-apiserver 중지
kubeadm 환경에서는 static pod 매니페스트를 이동시켜 중지:
mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/2. ETCD 스냅샷 복원
Option A: etcdutl (etcd v3.5+ 권장)
로컬 파일 작업이므로 endpoints/인증서 옵션이 불필요:
etcdutl snapshot restore /opt/snapshot-pre-boot.db \
--data-dir=/var/lib/etcd-from-backupOption B: etcdctl (legacy, v3.5 미만 또는 기존 관행)
ETCDCTL_API=3 etcdctl snapshot restore /opt/snapshot-pre-boot.db \
--data-dir=/var/lib/etcd-from-backup
# 참고: restore는 로컬 작업이라 endpoints/인증서는 실제로 사용되지 않음
# 단, 일부 버전에서는 옵션 누락 시 에러 → 필요하면 함께 지정etcd v3.6부터
etcdctl snapshot restore제거됨 →etcdutl필수v3.5에서는 deprecated warning만 출력되고 아직 동작함
3. etcd 매니페스트 수정
/etc/kubernetes/manifests/etcd.yaml에서 --data-dir과 volume 경로를 새 디렉토리로 변경:
# before
- --data-dir=/var/lib/etcd
...
volumes:
- hostPath:
path: /var/lib/etcd
name: etcd-data
# after
- --data-dir=/var/lib/etcd-from-backup
...
volumes:
- hostPath:
path: /var/lib/etcd-from-backup
name: etcd-data4. kube-apiserver 재시작
mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/5. (non-kubeadm 환경) 서비스 재시작
systemctl daemon-reload
systemctl restart etcd
systemctl restart kube-apiserver복원 흐름
- 스냅샷 파일 준비
etcdctl snapshot restore(또는etcdutl) → 새 data-dir 생성- etcd.yaml 수정 (data-dir 경로 변경)
- etcd Pod 자동 재시작
- kube-apiserver 재시작
- 클러스터 복원 완료
백업 전략 비교
| 방법 | 장점 | 단점 | 적합한 상황 |
|---|---|---|---|
| Git 저장소 | 버전 관리, 협업 | Imperative로 만든 리소스 누락 가능 | 일상적 관리 |
| kubectl get all -o yaml | 전체 리소스 추출 | 모든 리소스 타입 포함 안 될 수 있음 | 빠른 백업 |
| ETCD Snapshot | 클러스터 전체 상태 백업 | 복원 과정 복잡 | 재해 복구 |
| Velero | 리소스 + PV 통합 백업 | 별도 설치 필요 | 프로덕션 환경 |
139. Working with ETCDCTL and ETCDUTL
공식문서: etcd client commands (etcd 공식)
# ETCDCTL_API=3 설정 필수
export ETCDCTL_API=3
# 필수 인증서 옵션 (모든 etcdctl 명령에 필요)
--cacert=/etc/kubernetes/pki/etcd/ca.crt
--cert=/etc/kubernetes/pki/etcd/server.crt
--key=/etc/kubernetes/pki/etcd/server.key
# etcdutl (v3.5+) - 로컬 작업용 (snapshot 관련)
etcdutl snapshot restore /opt/snapshot.db --data-dir=/var/lib/etcd-from-backup
etcdutl snapshot status /opt/snapshot.dbetcd v3.5+에서는
etcdctl snapshot restore대신etcdutl snapshot restore사용 권장
140. Lab - Backup and Restore Methods
# ETCD Pod에서 설정값 확인
kubectl describe pod etcd-controlplane -n kube-system
# 인증서 경로 확인
# --trusted-ca-file → cacert
# --cert-file → cert
# --key-file → key
# --data-dir → 현재 데이터 디렉토리
# --listen-client-urls → endpoints
# 스냅샷 생성
ETCDCTL_API=3 etcdctl snapshot save /opt/snapshot.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
# 복원 후 확인
kubectl get all --all-namespaces141. Certification Exam Tip!
시험 팁
- etcdctl 명령 시 인증서 3개 (cacert, cert, key)와 ETCDCTL_API=3 잊지 말기
etcd.yaml의 volumes/volumeMounts 경로를 정확히 수정해야 복원 성공- 복원 후 etcd Pod가 재시작될 때까지 잠시 대기 필요
kubectl get pods -n kube-system으로 etcd Pod 상태 확인
호스트에 etcdctl이 없을 때 (시험장 대응)
kubeadm 환경의 일부 노드에서는 etcdctl 바이너리가 설치되지 않은 경우가 있음. 이때 etcd Pod 안에서 직접 실행하면 됨.
# ── etcd 파드 이름 확인 ───────────────────────────────────
kubectl get pods -n kube-system | grep etcd
# 예: etcd-controlplane
# ── 파드 내부에서 etcdctl 실행 ────────────────────────────
kubectl exec -n kube-system etcd-controlplane -- sh -c "\
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 \
member list"
# ── 스냅샷 생성 (파드 내부에서) ──────────────────────────
kubectl exec -n kube-system etcd-controlplane -- sh -c "\
ETCDCTL_API=3 etcdctl snapshot save /var/lib/etcd/snapshot.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"
# 파드에서 생성한 파일을 호스트로 복사
kubectl cp -n kube-system etcd-controlplane:/var/lib/etcd/snapshot.db /opt/snapshot.db시험용 etcdctl alias (시간 단축)
# 매번 긴 옵션 치기 귀찮을 때 alias 설정
alias etcdctl='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'
# 이후 짧게 사용
etcdctl member list
etcdctl snapshot save /opt/snapshot.dbetcd 인증서 경로 빠르게 찾기
시험 문제마다 인증서 경로가 다를 수 있음. 확실하게 찾는 방법:
# etcd Pod spec에서 직접 확인
kubectl describe pod -n kube-system etcd-controlplane | grep -E "cert-file|key-file|trusted-ca-file|data-dir"
# 또는 매니페스트에서
grep -E "cert-file|key-file|trusted-ca-file|data-dir" /etc/kubernetes/manifests/etcd.yaml
# 출력 예:
# --cert-file=/etc/kubernetes/pki/etcd/server.crt
# --key-file=/etc/kubernetes/pki/etcd/server.key
# --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
# --data-dir=/var/lib/etcd
# 매핑
# --trusted-ca-file → --cacert
# --cert-file → --cert
# --key-file → --key실전 Backup/Restore 축약 (시험용)
# ── Backup ────────────────────────────────────────────────
ETCDCTL_API=3 etcdctl snapshot save /opt/snapshot.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
# ── Restore ───────────────────────────────────────────────
# 1. etcdutl로 복원 (v3.5+ 권장)
etcdutl snapshot restore /opt/snapshot.db --data-dir=/var/lib/etcd-backup
# 2. etcd 매니페스트의 hostPath 경로를 새 디렉토리로 변경
sudo sed -i 's|/var/lib/etcd|/var/lib/etcd-backup|g' /etc/kubernetes/manifests/etcd.yaml
# 3. kubelet이 자동 감지하여 etcd Pod 재시작
watch kubectl get pods -n kube-system시험 시 주의: snapshot restore 후 etcd.yaml 수정 시 hostPath.path만 바꾸면 됨.
--data-dir인자도 함께 바꿔야 하는 경우가 있으니 둘 다 확인.
142. References
핵심 명령어 요약
| 작업 | 명령어 |
|---|---|
| 노드 drain | kubectl drain <node> --ignore-daemonsets --force |
| 노드 복원 | kubectl uncordon <node> |
| 노드 스케줄 방지 | kubectl cordon <node> |
| 업그레이드 계획 | kubeadm upgrade plan |
| 클러스터 업그레이드 | kubeadm upgrade apply v1.29.0 |
| Worker 노드 업그레이드 | kubeadm upgrade node |
| ETCD 스냅샷 생성 | etcdctl snapshot save <path> (인증서 3종 필요) |
| ETCD 스냅샷 복원 | etcdutl snapshot restore <path> --data-dir=<new-dir> (v3.5+ 권장) |
| ETCD 스냅샷 상태 | etcdutl snapshot status <path> --write-out=table |