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이 해주는 일:

  1. 노드에 cordon 걸어서 새 Pod 배치 금지
  2. 기존 Pod들을 정상적으로 종료(graceful) 후 다른 노드에 재배치 유도
  3. 이 과정에서 Service Endpoint도 자연스럽게 갱신됨 → 무중단

노드 다운 시 Pod 동작

  • 노드 다운 → 5분 대기 (pod-eviction-timeout) → Pod를 다른 노드에 재스케줄링

  • ReplicaSet/Deployment로 관리되는 Pod: 다른 노드에 자동 재생성

  • 단독 Pod (Bare Pod): 영구 손실 → 복구 불가

ReplicaSet 없이 생성된 Pod는 노드 장애 시 복구되지 않음

drain, cordon, uncordon

명령어동작
kubectl drainPod를 다른 노드로 이동 + 노드를 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

전체 흐름:

  1. kubectl drain node-1 → node-1 unschedulable, Pod A·B 제거 → node-2에 Pod A·B 재생성
  2. OS 업그레이드 / 패치 수행
  3. 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 node01

133. Kubernetes Releases

버전 체계

위치의미빈도
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

업그레이드 원칙

  1. 한 번에 하나의 Minor 버전만 업그레이드 (v1.27 → v1.28 → v1.29)
  2. Master Node 먼저, 그 다음 Worker Node
  3. Master 업그레이드 중 → 관리 기능 중단, 워크로드는 계속 실행

업그레이드 순서

  1. Master Node 업그레이드
    • API Server / Controller / Scheduler 중단
      • 관리 명령 불가 (kubectl 등)
      • 기존 Pod / Service는 정상 동작
    • 업그레이드 완료 후 재시작
  2. Worker Node 업그레이드 (아래 3가지 전략)

Worker Node 업그레이드 전략

전략설명다운타임
모두 한번에모든 Worker 동시 업그레이드O
하나씩 (Rolling)노드를 하나씩 drain → 업그레이드 → uncordonX
새 노드 추가새 버전 노드 추가 → 기존 노드 제거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.0

kubeadm은 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 kubelet

Worker 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

  1. apt update kubeadm
  2. kubeadm upgrade plan
  3. kubeadm upgrade apply
  4. apt update kubelet kubectl
  5. restart kubelet

각 Worker Node (반복)

  1. kubectl drain nodeX
  2. apt update kubeadm
  3. kubeadm upgrade node
  4. apt update kubelet
  5. restart kubelet
  6. kubectl 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 wide

138. 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 Clusteretcdctl 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.key

Snapshot 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=table

ETCD 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-backup

Option 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-data

4. kube-apiserver 재시작

mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/

5. (non-kubeadm 환경) 서비스 재시작

systemctl daemon-reload
systemctl restart etcd
systemctl restart kube-apiserver

복원 흐름

  1. 스냅샷 파일 준비
  2. etcdctl snapshot restore (또는 etcdutl) → 새 data-dir 생성
  3. etcd.yaml 수정 (data-dir 경로 변경)
  4. etcd Pod 자동 재시작
  5. kube-apiserver 재시작
  6. 클러스터 복원 완료

백업 전략 비교

방법장점단점적합한 상황
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.db

etcd 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-namespaces

141. 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.db

etcd 인증서 경로 빠르게 찾기

시험 문제마다 인증서 경로가 다를 수 있음. 확실하게 찾는 방법:

# 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


핵심 명령어 요약

작업명령어
노드 drainkubectl 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