본문으로 건너뛰기

5.1. 장애 처리 가이드


장애 시 체크리스트

장애 발생 시 다음 순서로 점검하는 것을 권장합니다.

  1. 영향 범위 파악: 전체 클러스터 장애인지, 특정 노드/네임스페이스/애플리케이션 장애인지 확인
  2. Node 상태 확인: Node 상태 확인 절차 수행
  3. 클러스터 핵심 컴포넌트 상태 확인: API Server, etcd, CoreDNS 등
  4. 최근 변경 이력 확인: 최근 배포, 설정 변경, 업그레이드 여부 확인
  5. 로그/이벤트 확인: 관련 Pod 로그 및 클러스터 이벤트 확인
  6. MSAP Observability 대시보드 확인: 메트릭 추이로 원인 범위 좁히기
  7. 필요 시 기술 지원팀 문의

Node 상태 확인

# 전체 노드 상태 확인
kubectl get nodes -o wide

# 특정 노드 상세(Conditions, 할당 리소스 등)
kubectl describe node <node-name>

# 노드 서비스 상태 확인(각 노드에서 직접 실행)
systemctl status rke2-server # Master
systemctl status rke2-agent # Worker

# Kubelet 상태 확인
systemctl status kubelet

Node NotReady

  1. kubectl describe node <node-name>로 Conditions 항목(MemoryPressure, DiskPressure, PIDPressure, Ready) 확인
  2. 해당 노드에 SSH 접속하여 systemctl status rke2-server(또는 rke2-agent) 확인
  3. 디스크/메모리 부족 여부 확인 (컴포넌트별 장애 대응 참고)
  4. 필요 시 서비스 재시작
    systemctl restart rke2-agent # Worker 노드인 경우

클러스터 컴포넌트 상태 확인

OPENMARU COP는 RKE2 기반이므로 시스템 서비스 및 핵심 Pod 상태로 컴포넌트 정상 여부를 판단합니다.

# API Server 접근 가능 여부
kubectl get --raw='/readyz?verbose'

# API Server 리스닝 포트 확인(Master 노드에서)
ss -tlnp | grep 6443

# etcd 클러스터 상태(Master 노드에서, etcd 정적 Pod 내부의 etcdctl 실행)
# 호스트에는 etcdctl 바이너리가 없으므로 kubectl exec로 etcd Pod 내부에서 실행합니다.
kubectl exec -n kube-system etcd-<master-node> -- etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt \
--cert=/var/lib/rancher/rke2/server/tls/etcd/server-client.crt \
--key=/var/lib/rancher/rke2/server/tls/etcd/server-client.key \
endpoint status --cluster -w table

# CoreDNS 상태 확인
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl run -it --rm debug -n kube-system --image=busybox --restart=Never -- nslookup kubernetes.default

# 전체 네임스페이스에서 비정상 Pod 조회
kubectl get pods -A | grep -v Running

# 최근 클러스터 이벤트 확인
kubectl get events -A --sort-by='.lastTimestamp' | tail -20

Node 로그 확인

# RKE2 서비스 로그(Master)
journalctl -u rke2-server -f

# RKE2 서비스 로그(Worker)
journalctl -u rke2-agent -f

# 특정 Pod 이벤트에 의한 노드 리소스 압박 확인
kubectl get events --field-selector reason=Evicted -A

# 디스크 사용량 확인 및 미사용 이미지 정리
df -h
crictl rmi --prune
journalctl --vacuum-size=1G

Web Console 대시보드 확인

OPENMARU COP Console의 메인 대시보드에서 다음을 우선 확인합니다.

  1. 노드 상태 도넛 차트: NotReady 노드 존재 여부
  2. Pod 상태 도넛 차트: Pending/CrashLoopBackOff/Error 상태 Pod 비율
  3. 최근 이벤트 목록: Warning 수준 이벤트 확인
  4. CPU/Memory 게이지: 리소스 고갈 여부

콘솔 자체 접속이 안 되는 경우(502/504 오류)는 컴포넌트별 장애 대응 - Ingress 502/503을 함께 확인하십시오.


컴포넌트별 장애 대응

증상점검 항목해결
Pod 간 통신 불가CNI(Canal/Calico) Pod 상태, VXLAN(4789) 포트CNI Pod 재시작, 방화벽/보안그룹에서 VXLAN 포트 확인
Service 접근 불가Endpoint 존재 여부, kube-proxy 상태kubectl get endpoints로 백엔드 Pod 연결 확인
외부 통신 불가DNS, NAT, 방화벽노드 라우팅 테이블 및 방화벽 정책 확인
PVC PendingStorageClass, NFS Provisioner 상태kubectl describe pvc로 이벤트 확인, showmount -e <nfs-server>로 NFS 마운트 가능 여부 확인
NFS 마운트 실패(access denied)/etc/exports 설정, 방화벽NFS 서버의 allow IP 대역 확인
PV가 Terminating에서 멈춤Finalizerkubectl patch pv <name> -p '{"metadata":{"finalizers":null}}' (⚠️ 스토리지 실제 삭제 여부 별도 확인 필요)
Ingress 502/503백엔드 Pod 상태, Readiness Probe대상 Pod가 Ready 상태인지 확인
TLS 인증서 오류Secret 존재/만료일kubectl get secret <tls-secret> -n <ns> -o yaml, cert-manager 갱신 상태 확인
ImagePullBackOffImagePullSecret, 레지스트리 접근성kubectl describe pod의 이벤트에서 정확한 오류 메시지 확인
CrashLoopBackOff애플리케이션 로그kubectl logs <pod> --previous로 직전 종료 원인 확인
OOMKilled메모리 제한kubectl describe pod에서 OOMKilled 확인 후 resources.limits.memory 상향
Pod Pending(스케줄링 불가)Taint/Toleration, NodeSelector, 리소스 부족kubectl describe pod의 Events에서 스케줄링 실패 사유 확인
Node MemoryPressure노드 메모리 사용량 과다아래 메모리 부족(MemoryPressure) 대응 참고

메모리 부족(MemoryPressure) 대응

# 1. 노드 메모리 사용량 확인
free -h

# 2. 메모리 사용량 기준 Pod 정렬 조회(클러스터 전체)
kubectl top pod -A --sort-by=memory

# 3. Pod별 메모리 제한(limits) 설정값 확인
kubectl get pods -A -o custom-columns=\
'NAME:.metadata.name,MEM:.spec.containers[*].resources.limits.memory'

# 4. 불필요하거나 메모리를 과다 점유한 Pod 정리
kubectl delete pod <pod-name> -n <namespace>

노드가 MemoryPressure 상태가 되면 Kubernetes는 우선순위가 낮은 Pod부터 자동으로 Evict(축출)할 수 있습니다. Evict된 Pod 목록은 다음으로 확인합니다.

kubectl get events --field-selector reason=Evicted -A

서비스별 장애 대응

서비스대표 증상조치
GitLab서비스 시작 실패docker exec -it gitlab gitlab-ctl reconfigure, 필요 시 gitlab-ctl restart
GitLab500 에러Rails 캐시/DB 마이그레이션 재실행
GitLabGit Push/Pull 실패(Permission denied, Unable to create temporary file)docker exec -it gitlab df -h로 디스크 공간 확인 → 부족 시 gitlab-rake gitlab:cleanup:orphan_job_artifact_files로 정리, 권한 문제 시 chown -R git:git /var/opt/gitlab/git-data/repositories/
Jenkins빌드 실패(DinD/Kaniko)빌드 에이전트 Pod 로그 확인, PVC 마운트 상태 확인
HarborPush/Pull 실패docker login 재시도, 노드의 containerd 레지스트리 신뢰 설정(/etc/rancher/rke2/registries.yamlregistry.{sub_domain}.{domain}.{TLD}:8443 항목 및 insecure_skip_verify 값) 확인
Harbor취약점 스캔 실패Trivy DB 최신화 여부 확인
ArgoCD로그인 실패argocd-initial-admin-secret 값으로 재로그인
ArgoCD동기화 실패저장소 재연결 후 강제 동기화(argocd app sync <app> --force)
KeycloakSSO 로그인 실패클라이언트 Redirect URI 설정 확인
KeycloakLDAP 연동 실패LLDAP 서비스 상태 및 네트워크 연결 확인
Keycloak토큰/세션 만료(Token expired, Session has expired)Keycloak Admin Console Realm Settings > Tokens에서 Access Token Lifespan/SSO Session Max 연장, 또는 kcadm.sh update realms/openmaru -s accessTokenLifespan=1800 -s ssoSessionMaxLifespan=86400으로 CLI 조정
OPENMARU COP Console접속 불가(502)Console Pod/Ingress 상태 확인
OPENMARU COP Console클러스터 연결 실패RBAC/ServiceAccount 토큰 유효성 확인
MSAP Observability로그 수집 안 됨kubectl get pods -n openmaru-logging -l app.kubernetes.io/name=fluent-bit로 Fluent Bit DaemonSet 상태 확인, OpenTelemetry Collector 상태(kubectl get pods -n openmaru-observ -l app.kubernetes.io/name=openmaru-observ-otel-collector) 및 헬스체크(wget -qO- http://localhost:13133/health) 확인
MSAP Observability대시보드 로딩 안 됨/데이터 소스 오류kubectl get pods -n openmaru-observ로 전체 Pod 상태 확인, ClickHouse(-l app.kubernetes.io/name=openmaru-observ-clickhouse) 상태 확인 후 필요 시 kubectl rollout restart statefulset/openmaru-observ-server -n openmaru-observ

Keycloak 토큰/세션 만료 - Console 확인 화면: Keycloak Admin Console에서 대상 Realm(openmaru) 선택 후 Realm settings > Tokens 탭에서 Access Token Lifespan 값을 확인/연장할 수 있습니다. (SSO Session Max는 같은 화면의 Sessions 탭에 있습니다.)

Keycloak Realm settings - Tokens

GPU 장애 대응

GPU 노드가 있는 환경에서 발생하는 장애와 조치입니다.

증상별 조치

증상원인조치
GPU Pod가 계속 Pending장치를 이미 다른 워크로드가 점유kubectl get resourceclaims -A 로 점유 현황 확인. 공유가 목적이면 ResourceClaim을 이름으로 참조하도록 변경
GPU Pod가 계속 Pending, cannot allocate all claims장치 분할이 꺼져 있어 한 클레임이 장치를 통째로 점유장치의 allowMultipleAllocations 와 클러스터 기능 게이트 확인
Pod는 Running 인데 GPU 연산 실패장치가 컨테이너에 주입되지 않음Pod 안에서 nvidia-smi -L 확인. 목록이 비면 드라이버·장치 주입 설정 점검
워크로드가 갑자기 종료같은 GPU를 쓰는 다른 워크로드가 메모리를 모두 사용GPU 메모리는 물리적으로 나뉘지 않습니다. 함께 실행할 워크로드의 메모리 합계를 재조정
노드에 GPU가 표시되지 않음드라이버 또는 GPU Operator 이상kubectl get pods -n gpu-operator 로 구성 요소 상태 확인
장치 목록(resourceslices)이 비어 있음DRA 드라이버 이상kubectl get pods -n nvidia-dra-driver-gpu 로 kubelet 플러그인 상태 확인

DRA 드라이버 kubelet 플러그인 이상

드라이버 버전을 올린 뒤 플러그인이 CrashLoopBackOff 이고 로그에 다음이 나오는 경우입니다.

Error: error creating driver: unable to get checkpoint: checkpoint is corrupted

이전 버전이 남긴 체크포인트 파일이 새 버전과 호환되지 않는 것입니다. 해당 노드에서만 발생하며, 장치 할당 기록이 없던 노드는 영향을 받지 않습니다.

주의: 플러그인이 정상 동작하지 않으면 GPU를 사용하던 Pod가 Terminating 에서 멈춥니다. 장치를 정리할 주체가 없기 때문입니다.

# 1) 해당 노드의 GPU 워크로드를 비웁니다
kubectl scale deploy -n <네임스페이스> <워크로드> --replicas=0

# 2) 체크포인트를 백업하고 삭제합니다
ssh root@<노드> 'cp -a /var/lib/kubelet/plugins/gpu.nvidia.com/checkpoint.json \
/tmp/checkpoint.json.bak-$(date +%H%M%S) && \
rm -f /var/lib/kubelet/plugins/gpu.nvidia.com/checkpoint.json'

# 3) 플러그인 Pod를 재생성합니다
kubectl delete pod -n nvidia-dra-driver-gpu \
-l app.kubernetes.io/name=dra-driver-nvidia-gpu \
--field-selector spec.nodeName=<노드>

# 4) 워크로드를 복구합니다
kubectl scale deploy -n <네임스페이스> <워크로드> --replicas=1

타임슬라이싱 설정이 남아 있는 경우

타임슬라이싱을 끈 뒤에도 설정이 세 곳에 남아 계속 동작할 수 있습니다. GPU Operator 설치 스크립트가 이를 검사해 알려 주며, 정리 순서를 지켜야 합니다.

주의: ConfigMap을 먼저 삭제하면 DaemonSet에 볼륨 참조가 남아 Pod가 기동하지 못합니다(MountVolume.SetUp failed). ClusterPolicy를 먼저 비웁니다.

kubectl patch clusterpolicy cluster-policy --type=merge \
-p '{"spec":{"devicePlugin":{"config":{"name":"","default":""}}}}'
kubectl label node <노드> nvidia.com/device-plugin.config-
kubectl delete cm time-slicing-config-all -n gpu-operator
kubectl rollout restart ds/nvidia-device-plugin-daemonset ds/gpu-feature-discovery -n gpu-operator

주의: 정리하면 노드가 광고하는 GPU 개수가 줄어 그 GPU를 사용하던 Pod 일부가 Pending 이 됩니다. 작업 전에 워크로드를 확인하고 중단 시간을 확보하십시오.


Master 백업본으로 복원(etcd)

OPENMARU COP는 etcd 스냅샷을 통해 클러스터 상태(모든 Kubernetes 리소스 정의)를 백업/복원합니다.

스냅샷 생성(정기 백업)

rke2 etcd-snapshot save --name <snapshot-name>

# 저장된 스냅샷 목록 확인
rke2 etcd-snapshot ls

ℹ️ 참고: 정기 백업 스케줄은 설치 시 env.yaml의 백업 관련 설정을 통해 자동화할 수 있습니다.

스냅샷으로 복원

🚨 경고: 이 작업은 클러스터 전체 상태를 스냅샷 시점으로 되돌리는 되돌릴 수 없는 작업입니다. 반드시 사전에 현재 상태의 스냅샷을 추가로 생성한 후 진행하십시오.

  1. 복원 대상 Master 노드에서 RKE2 서비스 중지

    systemctl stop rke2-server
  2. 스냅샷으로 클러스터 재구성

    rke2 server --cluster-reset --cluster-reset-restore-path=<snapshot-path>
  3. RKE2 서비스 재시작

    systemctl start rke2-server
  4. 나머지 Master 노드는 클러스터 재조인 필요 여부 확인(일반적으로 데이터 디렉터리 초기화 후 재조인)

  5. 복원 후 검증

    kubectl get nodes -o wide
    kubectl get pods -A | grep -v Running

⚠️ 주의: --cluster-reset은 최후의 수단입니다. 가능하다면 먼저 Node NotReady클러스터 컴포넌트 상태 확인 절차로 정상화를 시도하고, 복구가 불가능한 경우에만 etcd 복원을 진행하십시오. 작업 전 반드시 기술 지원팀과 협의하는 것을 권장합니다.