IL-0066 Pusher · 2019-05-21 (게시일)kubernetes
Pusher 의 고객 트래픽은 모두 브리지를 거친다. 브리지는 인증, HTTP/2, WebSocket 업그레이드 같은 Pusher 고유의 로직을 처리하는 자체 개발 7계층 프록시다. 브리지는 실행 중에 설정을 다시 읽지 못한다.
2018년 4월쯤 동료가 브리지 설정을 운영 클러스터에 배포했다. 이 설정은 문법이 맞고 린트도 통과했으며 브리지도 이 설정으로 시작할 수 있었다. 그러나 백엔드 서비스로 가는 트래픽 라우팅을 망가뜨렸다. 쿠버네티스에서 디플로이먼트는 ConfigMap 을 알지만 ConfigMap 은 자신을 쓰는 디플로이먼트를 모른다. ConfigMap 을 바꾸면 몇 초 뒤 각 파드의 파일 시스템에 있는 파일만 바뀔 뿐 새 레플리카셋이나 새 파드가 만들어지지 않는다. 그래서 잘못된 설정은 배포된 뒤에도 바로 드러나지 않았다.
3주에서 4주 뒤 클러스터 업그레이드로 노드를 교체하자 브리지 파드가 차례로 새로 떴고, 새 파드는 잘못된 설정으로 시작했다. 결국 모든 브리지 파드가 잘못된 설정으로 돌았고 클러스터로 가는 모든 트래픽이 멈췄다. 발표자에 따르면 같은 유형의 장애가 한 해 동안 서너 번에서 여섯 번 되풀이됐다.
팀은 이를 막으려고 Wave 라는 오픈소스 컨트롤러를 만들었다. Wave 는 디플로이먼트, 스테이트풀셋, 데몬셋이 참조하는 ConfigMap 과 Secret 을 감시하고, 그 데이터로 해시를 계산해 파드 템플릿에 넣는다. 설정이 바뀌면 해시가 바뀌므로 디플로이먼트 컨트롤러가 곧바로 새 파드를 롤아웃하고, 새 설정이 제대로 동작하는지 바로 알 수 있다.
Pusher 의 모든 제품으로 가는 트래픽이 멈췄다. 고객 트래픽은 ELB 와 nginx 를 지나, 브리지라고 부르는 자체 개발 7계층 프록시를 거쳐 각 제품 서비스로 간다. 그래서 브리지가 망가지면 플랫폼 전체가 내려간다. 발표자는 이때 요청이 모두 500 오류였던 것으로 기억했다.
문제의 설정은 3주에서 4주 전에 이미 운영 클러스터에 배포되어 있었다. 클러스터 업그레이드로 노드를 교체하면서 브리지 파드가 하나씩 새로 떴고, 새 파드는 잘못된 설정을 읽었다. 결국 모든 브리지 파드가 잘못된 설정으로 돌게 되자 클러스터로 가는 트래픽이 모두 멈췄다.
–
–
ConfigMap 을 바꿔도 디플로이먼트는 새 파드를 만들지 않는다. 설정을 실행 중에 다시 읽지 못하는 애플리케이션은 파드가 다시 뜰 때에야 새 설정을 읽으므로, 잘못된 설정이 몇 주 뒤에 드러날 수 있다.
설정을 바꾸면 곧바로 새 파드가 뜨게 해야 설정이 맞는지 그 자리에서 확인할 수 있다.
–