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

사례3건

3건 중 1~3번째

  1. 증상

    Secure Connect 를 켠 커넥터를 쓰려던 고객이 연결 타임아웃과 실패를 겪었다. Secure Connect 를 켠 git 커넥터 테스트가 연결 타임아웃으로 실패했고, Secure Connect 를 켠 CI 파이프라인은 멈추거나 실패했다. Secure Connect 없이 도는 커넥터는 정상이었다.

    촉발

    Secure Connect 의 내부 FRPS 인프라를 돌리는 GKE 클러스터에서 컨트롤 플레인 자동 업그레이드가 두 단계로 잇달아 실행됐고, 단계마다 GKE 클라우드 컨트롤러 매니저가 재시작됐다.

    원인
    구성 요소
    기여 요인
    –
    조치
    • FRPS 디플로이먼트를 롤아웃 재시작해 클라이언트가 FRPS 서버에 다시 연결되게 했다. IP 예약이 사라진 근본 문제는 이 조치로 풀리지 않았다.
    • 내부 쿠버네티스 서비스 frps-internal 을 지우고 다시 만들어, GKE 가 새 IP 주소로 새 로드 밸런서를 만들게 했다.
    • Cloud DNS A 레코드가 새 로드 밸런서 IP 를 가리키게 바꿔, Secure Connect 트래픽 전체의 경로를 되살렸다.
  2. 증상

    us-central1 에서 새로 만든 VM 은 네트워크가 동작하기까지 오래 기다려야 했고, 라이브 마이그레이션된 VM 은 마이그레이션 뒤 오래 연결을 잃었다. us-central1 을 오가는 리전 간 트래픽에서 패킷 손실이 났다. 기존 VM 중 마이그레이션되지 않고 상태도 바뀌지 않은 VM 은 직접 영향을 받지 않았다.

    촉발

    관리 플레인의 동작 변경이 us-central1 에 배포됐다. 이 변경은 로드 밸런서 백엔드로 쓰는 GCP Instance Group 과 Network Endpoint Group 의 API 업데이트 처리를 더 잘 분리하려는 것이었다. 이 리전의 큰 워크로드 규모 때문에 가상 네트워크 라우터 컨트롤 플레인의 메모리가 예상 밖으로 늘었다.

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

    엔지니어들은 10월 4일 미국 태평양 시간 21:45 에 us-central1 가상 네트워크 컨트롤 플레인이 느리다는 알림을 받았고, 10월 5일 02:11 에 가상 네트워크 라우터 컨트롤러가 메모리를 다 써서 실패한다는 알림을 받았다. 03:08 부터는 네트워크 텔레메트리가 us-central1 을 오가는 리전 간 패킷 손실을 보여 주었다.

    조치
    • 컨트롤러에 메모리를 더 할당하는 변경을 배포했고, 이 변경은 미국 태평양 시간 05:27 부터 운영 환경에 닿았다. 08:15 에 리전 안 패킷 손실이 가라앉았다.
    • 08:52 에 관리 플레인 변경의 롤백을 시작해 09:35 에 us-central1 에서 마쳤고, 이때 메모리 부족이 모두 멈췄다.
    • 업데이트를 받지 않던 라우터 몇 대를 손으로 재시작했다. 이 재시작으로 패킷 손실이 더 생기지는 않았다.
    후속 조치
    • 메모리 위험과 예상 밖의 메모리 증가를 미리 알리는 알림을 만든다.
    • 엔지니어가 메모리를 훨씬 빨리 다시 할당할 수 있도록 배포 설정을 다시 짠다.
    • API 조정 작업의 기존 관행과 안전장치를 다시 평가하고 새 관행과 안전장치를 만든다.
    • 관리 플레인 변경을 여러 팀이 더 잘 볼 수 있게 해 장애와 더 빨리 연결 짓게 한다.
    • 리전 단위 API 변경 때문에 리전 전체의 메모리가 한꺼번에 바닥나는 일이 줄도록 배포 구성을 바꾼다.
    • 트래픽 라우터와 컨트롤러의 메모리를 최적화해 불필요한 부담을 없앤다.
  3. 증상

    2023-07-07 11:05 UTC 부터 15:25 UTC 까지 Jenkins 인프라의 공개 서비스 여럿이 완전히 멈췄다. accounts.jenkins.io, get.jenkins.io, plugins.jenkins.io 를 비롯해 Azure 의 공개 쿠버네티스 클러스터에서 돌던 서비스가 모두 내려갔다.

    촉발

    1.25 업그레이드 뒤 파드의 출발 IP 대역이 바뀌어 LDAP 접근이 막히자, 파드 IP 대역을 지정하는 수정인 Azure PR 431 을 10:55 UTC 에 배포했다. 이 변경으로 노드 풀이 모두 지워졌고 다시 만들어지지 않았다.

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

    10:30 UTC 에 1.25 업그레이드를 마친 뒤 팀이 클러스터 안 서비스가 LDAP 서비스에 닿지 못한다는 것을 알아챘다.

    조치
    • 네트워크 설정을 고쳐 클러스터를 처음부터 다시 만들었다. 11:16 부터 13:16 UTC 까지 두 시간이 걸렸다.
    • 파드 CIDR 을 가상 네트워크와 겹치지 않는 별도 대역으로 지정했다.
    • 서비스의 공개 IP 와 DNS 레코드를 새 주소 20.7.178.24 와 2603:1030:408:5::15a 로 바꿨다.
    • 15:17 UTC 에 IP 설정을 포함해 클러스터를 손으로 다시 만든 작업을 PR 로 올려 코드에 반영했다.
    후속 조치
    • Management Lock 을 걸어 공개 IP 가 지워지지 않게 한다.
    • 공개 IP 를 별도 리소스 그룹에 두고, 쿠버네티스가 관리하는 로드 밸런서가 그 그룹을 쓰도록 service.beta.kubernetes.io/azure-load-balancer-resource-group 애너테이션으로 설정한다.
    • 작업을 준비할 때 네트워크 구성과 대역이 겹칠 가능성을 쉽게 볼 수 있도록 네트워크 다이어그램과 문서를 개선한다.
    • AKS 노드 풀 설정을 한꺼번에 바꾸지 않는다. 첫 노드 풀에서 문제를 잡았다면 전체 장애를 피할 수 있었다. arm64 노드 풀에서 PR-3623 으로 이 작업을 하고 있다.
    교훈

    허용 목록을 둔 회사 방화벽 뒤의 사용자가 있어서 공개 IP 는 되도록 바뀌지 않아야 한다. 그런데 원래 클러스터를 지우면서 노드 리소스 그룹과 함께 공개 IP 가 지워졌다. 노드 풀 설정을 한꺼번에 바꾸지 않았다면 첫 노드 풀에서 문제를 잡아 전체 장애를 피할 수 있었다. 팀은 거의 모든 공개 서비스를 담은 클러스터가 완전히 무너져도 4시간 안에 복구할 수 있다는 것을 이번에 확인했다. 그 바탕은 여러 해 동안 함께 해 온 아키텍처 정의, 인프라 구축, 데이터 백업 작업이라고 했다.

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

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

원인별3