Kubernetes 로드밸런서 파드 연결 503 에러
안녕하세요! 오늘은 Kubernetes 로드밸런서 파드연결의 안정성을 위한 Probes와 Lifecycle설정에 대하여 깊이 있게 다뤄볼 예정입니다. 운영중 서비스 발생 현상으로 개선한 내역 확인해 봅시다.
목차
발생 현상
autoscale 2 → 40 증가시 워커 노드 증가 현상, 어플리케이션 늘어나는 정상 감지 시간 지연이 필요
autoscale시 몇몇 파드 재기동 현상발생, 시간이 지연 되나 결국 정상화 되는 현상 발생
조치 사항
- livenessProbe initialDelaySeconds 180 으로 변경
- ALB 연결 체크는 60초 이후 수행
- 비정상 체크는 180초 이후 수행
다시 시작 주기를 피하려면, livenessProbe.initialDelaySeconds 매개변수를 서비스가 초기화되는 데 걸리는 시간보다 반드시 더 길게 설정하십시오. 그런 다음 readinessProbe.initialDelaySeconds 속성에 대해 더 짧은 값을 사용하여 요청이 준비되는 즉시 서비스로 라우팅할 수 있습니다.
예제 구성은 아래 첨부 하도록 하겠습니다.
Kubernetes Probes란?
Kubernetes Probes는 kubelet이 주기적으로 컨테이너에 수행하는 진단입니다. Probes에는 세 가지 유형이 있습니다:
- Liveness Probes: 컨테이너가 정상 작동 중인지 판단합니다. 실패 시 컨테이너를 재시작합니다.
- Readiness Probes: 컨테이너가 요청을 처리할 준비가 되었는지 확인합니다. 실패 시 컨테이너를 서비스 로드 밸런서에서 제거합니다.
- Startup Probes: 컨테이너 애플리케이션이 시작되었는지 확인합니다. 성공할 때까지 다른 liveness 및 readiness 검사를 비활성화합니다.
Probes의 중요성
시작 시간이 긴 애플리케이션을 배포한다고 상상해보세요. Readiness probe 없이 Kubernetes는 포드가 준비된 것으로 오해할 수 있습니다. 이는 잠재적 오류를 초래할 수 있습니다. 마찬가지로, 애플리케이션이 반응하지 않는 경우 Liveness probe 없이는 Kubernetes가 오류가 있는 포드를 재시작해야 한다는 것을 인지하지 못하게 됩니다. 출처: https://cloud.ibm.com/docs
Probes 설정하기
Probes는 다양한 방법으로 설정할 수 있습니다:
- HTTP Get: 컨테이너에서 HTTP GET 작업을 수행합니다.
- TCP Socket: 컨테이너의 특정 포트에 TCP 연결을 시도합니다.
- Exec: 컨테이너 내에서 명령을 실행합니다.
다음은 Kubernetes 배포에서 HTTP Get liveness probe를 설정하는 예제입니다:
apiVersion: apps/v1 kind: Deployment metadata: name: api-product-deployment namespace: service labels: app: api-product spec: replicas: 1 selector: matchLabels: app: api-product template: metadata: labels: app: api-product spec: serviceAccountName: api-product-ac containers: - name: api-product image: ...api_product:1523 ports: - containerPort: 8093 resources: limits: cpu: 1000m requests: cpu: 500m livenessProbe: httpGet: path: /product/v1/check port: 8093 initialDelaySeconds: 180 periodSeconds: 10 readinessProbe: httpGet: path: /product/v1/check port: 8093 initialDelaySeconds: 60 periodSeconds: 5 nodeSelector: nodegroup-type: api1
모범 사례
- Probe 매개변수 조정:
initialDelaySeconds
,periodSeconds
,timeoutSeconds
,successThreshold
,failureThreshold
를 애플리케이션의 요구 사항에 맞게 조절하세요. - 과도한 검사 피하기: 너무 빈번한 검사는 비효율적일 수 있습니다.
- Liveness 명령어 주의 깊게 커스터마이징: Exec probes의 경우, 실행하는 명령어가 빠르게 완료되고 리소스를 과도하게 소모하지 않도록 주의하세요.
하지만 위 설정으로도 반쪽짜리 설정으로 볼 수 있습니다. Kubernetes 로드밸런서 파드 간 계속해서 AutoScale시 500에러가 간헐적 으로 발생하여 추가로 확인 작업을 진행하였습니다. 환경에서 리소스 관리와 스케쥴링은 중요한 추가 적용이 필요 하였습니다. 특히, Pod의 생명주기(Lifecycle)와 이에 따른 그레이스풀 종료(Graceful Termination)는 애플리케이션 운영 중에 발생할 수 있는 문제를 최소화하기 위한 핵심적인 개념입니다. 아래는 Pod의 그레이스풀 라이프사이클에 대하여 자세히 다루겠습니다.
그레이스풀 라이프사이클이란?
그레이스풀 라이프사이클은 Pod나 애플리케이션의 서비스를 중단할 때 발생하는 부작용을 최소화하기 위한 프로세스입니다. 이것은 실질적으로 서비스의 중단 시간을 최소화하고, 데이터의 손실이나 깨진 연결을 방지하기 위한 방법입니다.
Kubernetes에서의 그레이스풀 종료
Kubernetes에서 Pod를 종료하라는 명령을 내리면, 그레이스풀 종료 프로세스가 시작됩니다. 이 프로세스는 아래와 같은 순서로 진행됩니다:
- Pod를 Terminating 상태로 변경: 먼저, Kubernetes는 해당 Pod의 상태를 “Terminating”으로 변경합니다.
- 엔드포인트 제거: Service의 엔드포인트 목록에서 Pod를 제거하여 더 이상 트래픽이 Pod로 전송되지 않도록 합니다.
- 그레이스풀 종료 기간: Kubernetes는 기본적으로 30초의 그레이스풀 종료 기간을 제공합니다. 이 기간 동안 Pod는 현재 진행 중인 작업을 완료하고 준비를 할 수 있습니다.
- SIGTERM 시그널 전송: Kubernetes는 Pod 내의 모든 프로세스에 SIGTERM 시그널을 전송하여 종료를 시작합니다.
- 그레이스풀 종료 기간 후: 만약 Pod가 그레이스풀 종료 기간 내에 종료되지 않으면, SIGKILL 시그널이 전송되어 강제 종료됩니다.
그레이스풀 종료 기간 커스터마이징
기본 30초의 아래와 같이 필드를 통해 커스터마이즈할 수 있습니다.
... lifecycle: preStop: exec: command: [ "/bin/sh", "-c", "touch /tmp/lbdown ; sleep 30"
Kubernetes 로드밸런서 파드 안정성 개선 결론
preStop의 파일을 Back-End 어플리케이션이 감지하여 Readiness Probes 체크 URL을 사전에 비활성화 처리를 진행 하면 파드 안정성을 더욱 견고하게 설정 할 수 있습니다.
마무리
Kubernetes Probes는 클러스터에서 실행 중인 애플리케이션의 건강 상태와 성능을 유지하는 데 중요한 역할을 합니다. Liveness와 Readiness 검사를 적절하게 설정함으로써 응답성 있고 내구성 있는 애플리케이션을 확보할 수 있습니다. Pod의 그레이스풀 종료는 서비스 품질을 유지하고 데이터 손실을 방지하기 위한 중요한 과정입니다. Kubernetes 환경에서 애플리케이션을 운영할 때, 해당 프로세스를 정확히 이해하고 적절하게 활용하는 것이 필요합니다.
클라우드 네이티브에 최적화된 프레임워크 Quarkus에 대한 성능지표 아래에서 확인 해보세요!