IL-0028 Temporal · 2023-06-13 (게시일)kubernetesobservability
Temporal 블로그에 실린 글로, 쿠버네티스에 자체 호스팅한 Temporal Server 의 요청 지연을 낮추고 안정시키는 방법을 다룬다. 예시로 든 것은 History 서비스로, 워크플로 실행을 시작하고 워크플로 상태를 갱신하는 호출을 처리한다. 클러스터 모니터링은 kube-prometheus 스택으로 했다.
쿠버네티스는 컨테이너의 CPU 한도를 0.1초마다 쓸 수 있는 CPU 사이클 한도로 바꾸고, 컨테이너가 이 한도를 넘으면 실행을 늦춘다. 이것이 CPU 스로틀링이고, 락을 잡는 것처럼 CPU 를 많이 쓰는 요청일수록 지연이 커진다. Go 는 기본적으로 머신의 코어마다 프로세스 하나를 쓸 수 있다고 가정한다. 노드는 8코어, history 파드의 CPU 한도는 2코어였으므로 파드는 프로세스를 8개까지 만들 수 있었지만, 스로틀링 주기마다 쓸 수 있는 사이클은 2코어 몫뿐이었다. 프로세스들이 허용된 CPU 사이클을 놓고 서로 다퉜고, 가비지 컬렉션 같은 관리 작업까지 그 좁은 몫 안에서 돌아야 했다.
GOMAXPROCS 환경 변수를 CPU 한도와 같은 2로 설정하자 CPU 스로틀링이 완전히 사라졌고 지연이 안정됐다. CPU 사용량은 줄었고 요청 지연은 오히려 조금 낮아졌다. Temporal 의 모든 서비스에서 CPU 사용량이 함께 내려갔다. 글은 더 나아가 CPU 한도를 아예 쓰지 말고 CPU 요청값과 노드 CPU 사용량을 꼼꼼히 관찰하라고 권한다. 고객 격리 같은 업무상 이유로 한도를 없앨 수 없다면, Temporal 전용 노드를 두고 테인트와 톨러레이션으로 Temporal 배포를 그 노드에 고정한 뒤 Temporal 에서만 한도를 빼라고 한다. 또 History 서비스는 파드가 늘거나 줄 때마다 샤드를 다시 나누는데, 옮겨지는 샤드는 그동안 쓸 수 없어서 배포 중에 지연이 튄다. 파드가 10개보다 많으면 maxSurge 와 maxUnavailable 을 낮게 잡아 하나씩 천천히 교체하고, 그보다 적으면 빠르게 교체하라고 권한다. 4개 이하에서는 두 값을 50%로 두었을 때 결과가 좋았다.
자체 호스팅한 Temporal Server 의 History 서비스에서 요청 지연이 일정하지 않았다. 대시보드에서 history 파드의 CPU 사용률은 60% 아래로 나왔지만 파드는 CPU 스로틀링을 받고 있었다.
CPU 사용률 지표만으로는 이 문제가 보이지 않았다. 쿠버네티스는 컨테이너의 CPU 한도를 0.1초마다 쓸 수 있는 CPU 사이클 한도로 바꿔 적용한다. 반면 Prometheus 는 집계된 CPU 지표를 15초 이상의 간격으로 수집한다. 그래서 사용률이 100%에 한참 못 미쳐도 스로틀링이 일어날 수 있다.
스로틀링은 kube-prometheus 의 cAdvisor 지표로 확인했다. container_cpu_cfs_throttled_periods_total 의 증가량을 container_cpu_cfs_periods_total 의 증가량으로 나누고, namespace="temporal", workload="temporal-history" 로 걸러 이 비율이 0보다 큰지 보았다.
원인 ? 용량 한계
kube-prometheus 대시보드에서 history 파드의 CPU 사용률은 60% 아래였지만 스로틀링 비율은 0보다 컸다. 15초 이상 간격으로 수집하는 CPU 사용률 지표로는 0.1초 단위로 일어나는 스로틀링이 보이지 않으므로, 스로틀링 지표를 따로 보고서야 문제를 찾았다.
CPU 사용률이 낮게 나와도 스로틀링은 일어날 수 있으므로 스로틀링 지표를 따로 관찰해야 한다. Go 서비스에서는 GOMAXPROCS 를 CPU 한도의 정수 코어 수에 맞춘다. GOMAXPROCS 는 CPU 요청값으로는 자동 설정되지 않으므로, CPU 한도를 쓰지 않는다면 CPU 요청값과 같거나 조금 큰 값으로 직접 설정한다. 가능하면 CPU 한도를 쓰지 말고 CPU 요청값을 적절히 잡은 뒤 노드 CPU 사용량을 지켜본다. 노드 CPU 가 자주 바닥나면 파드가 요청값을 넘어 자주 버스트한다는 뜻이므로 요청값을 다시 잡는다.
같은 원인 · 공통 컨테이너 CPU 한도
같은 원인 · 공통 Prometheus
같은 원인 · 공통 Prometheus
같은 원인 · 공통 Prometheus
같은 원인 · 공통 Prometheus
같은 원인 · 공통 Prometheus