IL-0072 Nordstrom · 2017-12-15 (게시일)kubernetesaws
Nordstrom 은 리뷰, 기프트 카드, 구매 주문 같은 마이크로서비스와 개발 도구, 로깅과 모니터링 스택 일부를 쿠버네티스에서 돌린다. 컨트롤 플레인은 etcd, API 서버, 스케줄러, 컨트롤러 매니저를 다섯 대씩 두는 고가용성 구성이었다. 어느 날 주 운영 클러스터가 전체 장애에 빠졌다.
etcd 는 쓰기를 항상 쿼럼을 거쳐 처리하지만, 읽기는 쿼럼 읽기를 명시적으로 요청하지 않으면 질의받은 로컬 멤버만 아는 데이터로 응답할 수 있다. 평소에는 작은 복제 지연 정도로 끝난다. 하지만 쓰기 지연이 커지면 이 차이가 크게 벌어지고, 리더 선출 타임아웃을 거듭 넘겨 선출이 연달아 일어날 수 있다. 당시 쿠버네티스 API 서버는 기본 설정에서 쿼럼 읽기를 요청하지 않았고, 고가용성 문서에도 그 내용이 없었다. etcd 쓰기 지연이 커지자 API 서버가 오래된 데이터를 읽었고 클러스터 상태가 두 가지로 번갈아 보였다. 발표자는 합의 모델 자체가 깨지는 스플릿 브레인은 아니었다고 밝혔다.
팀은 진단에 오래 매달리다가 결국 새 클러스터로 교체해 서비스를 되살렸고, 장애는 약 4시간 이어졌다. 교체도 쉽지 않았다. 볼륨은 한 노드에만 연결될 수 있어서 옛 클러스터에서 하나씩 손으로 풀어 줘야 새 클러스터에서 바인딩할 수 있었다. 로드 밸런서를 쓰던 몇몇 팀은 쿠버네티스가 만든 임시 이름을 DNS 레코드로 가리키고 있어서, 새 클러스터의 로드 밸런서 이름으로 레코드를 손으로 고쳐야 했다.
장애는 업무 시간에 일어나 팀 전체가 대응할 수 있었다. 팀은 근본 원인까지 분석했고, 그 결과 시스템을 더 잘 이해하게 됐고 코드와 절차도 크게 고쳤다.
사용자가 파드가 떴다가 사라진다고 클러스터 운영 팀에 알렸다.
kubectl get pods 를 실행하면 서로 다른 두 결과가 번갈아 나왔다. kubectl get nodes 도 마찬가지였다. 클러스터 상태를 두고 서로 다른 두 의견이 있는 것처럼 보였다.
제어 루프도 잘못 움직이기 시작했다. 컨트롤러 매니저가 번갈아 받는 데이터에 반응해 수천 개 파드를 띄웠다가 종료했다. 서비스 엔드포인트가 계속 바뀌었다. 인그레스 컨트롤러도 엇갈린 신호에 반응했고, 그 때문에 인그레스를 거쳐 가야 할 트래픽이 크게 망가졌다.
팀은 원인을 몰라 한참 혼란스러웠다. 클러스터를 교체하면 애플리케이션을 새로 배포해야 했기 때문에 교체를 망설이며 진단에 오래 매달렸다.
팀은 사용자가 파드가 떴다가 사라진다고 알려 와서 장애를 알게 됐다. 팀이 kubectl 로 확인하자 같은 명령이 실행할 때마다 다른 결과를 냈다.
etcd 는 쿼럼 읽기를 요청하지 않으면 오래된 데이터로 응답할 수 있고, 이 동작은 문서에 적혀 있다. 쿠버네티스 1.9 부터는 쿼럼 읽기가 기본이므로, 그 전 버전을 쓰면서 API 서버 설정을 직접 관리한다면 설정을 확인해야 한다. 쿼럼 읽기는 성능 걱정 때문에 처음에는 권장되지 않았지만, etcd 3.1 에서는 읽기가 디스크를 거치지 않아 부담이 크게 줄었다. etcd 는 쓰기 지연에 매우 민감하므로 데이터베이스 동기화 지연을 지켜봐야 한다. 고가용성 문서처럼 계속 바뀌는 문서는 꾸준히 다시 읽어야 한다. 로드 밸런서 이름을 직접 가리키는 DNS 레코드와 한 노드에 묶이는 볼륨은 클러스터 교체를 느리게 만든다.
같은 원인 · 공통 쿠버네티스 API 서버, etcd
같은 원인 · 공통 쿠버네티스 API 서버, etcd
같은 원인 · 공통 인그레스 컨트롤러
같은 원인 · 공통 인그레스 컨트롤러
같은 원인 · 공통 쿠버네티스 API 서버
같은 원인 · 공통 인그레스 컨트롤러
같은 원인 · 공통 etcd
같은 원인 · 공통 영구 볼륨과 스테이트풀셋
같은 원인 · 공통 인그레스 컨트롤러
같은 원인 · 공통 인그레스 컨트롤러
같은 원인 · 공통 쿠버네티스 API 서버