Incident Library
  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례3건

3건 중 1~3번째

  1. 증상

    외부에서 쿠버네티스 클러스터에 접속할 수 없었다. 작성자는 컨트롤 플레인 노드로 들어가 sudo systemctl status kubelet 으로 kubelet 로그를 확인했다.

    촉발

    kubeadm 이 만든 하위 인증서의 기본 유효기간 1년이 2026-02-20 16:16 UTC 에 끝났다.

    원인
    구성 요소
    기여 요인
    감지

    외부에서 클러스터에 접속이 안 되는 것으로 알아챘다. 컨트롤 플레인 노드에서 kubelet 로그, containerd 로그, kube-apiserver 컨테이너 로그를 차례로 보다가 kube-apiserver 로그의 x509 만료 오류에서 원인을 확인했다.

    조치
    • sudo kubeadm certs renew all 로 만료된 인증서를 한 번에 갱신했다.
    • containerd 와 kubelet 을 재시작해 Static Pod 로 도는 컨트롤 플레인 컴포넌트를 새 인증서로 다시 띄웠다.
    • /etc/kubernetes/admin.conf 를 $HOME/.kube/config 로 복사하고 소유자를 바꿔 kubeconfig 를 새 인증서로 바꿨다.
    교훈

    sudo kubeadm certs check-expiration 으로 만료일을 주기적으로 확인하고, 만료 30일 전부터 갱신하는 것이 좋다. kubeadm upgrade apply 를 실행하면 인증서도 함께 갱신되므로, 1년에 한 번 이상 쿠버네티스 버전을 올리는 클러스터는 이 문제를 자연스럽게 피한다. 버전을 올리지 않고 오래 운영하는 클러스터라면 kubeadm certs renew all 과 kubelet 재시작을 cron 으로 매년 걸어 둘 수 있다. 작성자가 든 예시에서는 매년 1월 1일 새벽 3시에 실행한다.

  2. 증상

    2022년 8월 3일 11:38 UTC 에 한 사용자 팀이 해당 쿠버네티스 클러스터에 Service 리소스를 적용하는 데 문제가 있다고 알려 왔다.

    촉발

    서드파티 애플리케이션이 쓰는 인증서 체인이 만료되면서 Kyverno 가 크래시 루프에 빠졌다. DFDS 쪽에서는 아무것도 바꾸지 않았다.

    원인
    구성 요소
    기여 요인
    감지

    11:38 UTC 에 한 사용자 팀이 클러스터에 Service 리소스를 적용하지 못한다고 알려 오면서 장애가 드러났다. 팀은 11:50 UTC 에 조사를 시작했고, 보고서는 탐지까지 걸린 시간을 12분으로 적었다.

    조치
    • 쿠버네티스 샌드박스에서 문제를 재현하고, Kyverno 를 더 새 Helm 차트 버전으로 올리는 수정을 샌드박스에 먼저 배포했다.
    • 13:06 UTC 에 같은 수정을 영향받은 운영 클러스터에 배포했다.
    후속 조치
    • Kyverno 를 모니터링 대상에 넣는다.
    • Kyverno 를 어떻게 구성했는지 내부 문서로 정리한다.
    • 애플리케이션의 인증서에서 정확히 무엇이 문제였는지 조사한다.
    • 앞으로 ClusterPolicy 리소스의 failurePolicy 를 바꿀지 검토한다.
    교훈

    운영 문제는 처음부터 'Ops Day to Day' 보드에 올려야 한다.

  3. 증상

    07:32 에 자동 모니터링이 장애를 잡아 온콜 엔지니어를 호출했다. 07:31 부터 GoCardless API 로 가는 요청이 전부 실패했고, 대시보드, 결제 페이지, 파트너 연동을 거치는 작업도 쓸 수 없었다. 07:32 부터 07:54 GMT 까지 22분 동안 서비스 전체가 멈췄다.

    촉발

    cert-manager 가 Vault 의 TLS 인증서를 갱신했지만 Vault 는 새 인증서를 다시 읽지 않고 옛 인증서를 계속 썼다. 07:22 에 그 옛 인증서가 만료됐다.

    원인
    구성 요소
    기여 요인
    감지

    07:32 에 자동 모니터링이 장애를 잡아 온콜 엔지니어를 호출했다.

    조치
    • 07:42 에 인증서가 만료됐다고 보고 cert-manager 가 인증서를 다시 만들도록 손으로 강제했다. 실제로 인증서는 이미 갱신돼 있어 이 단계는 필요 없었다.
    • 07:48 에 새 인증서가 만들어지자 Vault 가 그 인증서를 읽도록 Vault 클러스터를 손으로 재시작했다.
    • 중요한 워크로드의 파드 몇 개를 직접 삭제해 5분까지 늘어난 지수 백오프를 건너뛰었고, 서비스가 몇 분 일찍 완전히 돌아왔다.
    후속 조치
    • L7 로드 밸런서에만 있던 TLS 인증서 만료 모니터링을 Vault 가 쓰는 단순 TCP 로드 밸런서까지 넓히고, Blackbox exporter 로 그 인증서도 주기적으로 검사한다.
    • Vault 서버가 바뀐 인증서를 스스로 다시 읽는 기능이 없으므로, Reloader 컨트롤러를 배포해 인증서 데이터가 바뀌면 Vault 를 롤링 업데이트한다.
    • Vault 로 가는 네트워크 분할 같은 다른 장애가 실행 중인 서비스에 번지지 않도록, theatre-envconsul 을 바꿔 envconsul 이 자식 프로세스를 관리하지 않게 하고 컨테이너 시작 때 비밀 환경 변수를 넣는 일만 하게 한다.
    교훈

    Vault 를 쓸 수 없게 된 것보다 Vault 에 기대는 모든 애플리케이션이 거의 곧바로 실패한 것이 훨씬 나빴다. 이런 장애 상황을 충분히 시험하지 않았고, 단일 장애점과 피해 범위를 줄여야 한다는 것을 장애를 겪고서야 다시 확인했다. 대응 중에는 인증서 자체가 만료됐다고 여겨 인증서를 다시 만들게 했다. 실제로는 인증서가 이미 갱신돼 있었고 Vault 가 다시 읽지 않았을 뿐이었다. 그래서 DNS 검증 때문에 몇 분 걸리는 이 단계는 건너뛸 수 있었다.

내 클러스터에도 있는지 확인하기

이 3건에서 가장 많이 나오는 구성 요소: 어드미션 웹훅, Calico. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별1