Featured image of post 헬스체크와 컨테이너 라이프사이클

헬스체크와 컨테이너 라이프사이클

헬스체크, 컨테이너 라이프사이클

헬스 체크와 컨테이너 라이프 사이클

헬스 체크

  • 파드가 정상인지 판단하는 기능
  • 이상 종료된 경우 spec.restartPolicy에 따라 파드 재시작

헬스체크 방법

Probe 종류 역할 실패 시 동작
Liveness Probe 파드 내부의 컨테이너가 정상 동작 중인지 확인 컨테이너 재가동
Readiness Probe 파드가 요청을 받아들일 수 있는지 확인 트래픽 차단(파드 재기동x)
Startup Probe 파드의 첫 번째 기동이 완료되었는지 확인 다른 Probe 실행 시작 x
  • Liveness Probe: 헬스 체크에 한 번 실패하면 재시작 없이는 복구가 어려울 때 사용
  • Readiness Probe: db에 정상적으로 접속되는지, 캐시에 로드가 끝났는지, 기동 시간이 오래 걸리는 프로세스가 끝났는지 등등 체크
    • 실패한 경우 트래픽이 파드에 전송되지 않도록 함
  • Startup Probe: 처음 기동하는데 시간이 오래 걸릴 경우 사용, 완료까지 다른 Probe나 서비스가 시작되지 않음

헬스체크 방식

  • 헬스 체크는 컨테이너별로 이루어짐
  • 하나의 컨테이너라도 실패하면 전체 파드가 실패한 것으로 간주
헬스 체크 방식 내용
exec 명령어를 실행하고 종료 코드가 0이 아니면 실패
httpGet HTTP GET 요청 실행 후 Status Code가 200~399가 아니면 실패
tcpSocket TCP 세션이 연결되지 않으면 실패
명령어 기반의 체크(exec)
  • 명령어로 실행하고 종료 코드로 확인
  • 가장 유연성이 높은 체크
  • 명령어는 컨테이너별로 실행
1
2
3
livenessProbe:
  exec:
    command: ["test", "-e", "/ok.txt"]
HTTP 기반의 체크(httpGet)
  • HTTP GET 요청의 Status Code로 확인
  • HTTP GET 요청은 kubelet에서 이루어짐
1
2
3
4
5
6
7
8
9
livenessProbe:
  httpGet:
    path: /health
    port: 80
    scheme: HTTP
    host: web.example.com
    httpHeaders:
      - name: Authorization
        value: Bearer Token
TCP 기반의 체크(tcpSocket)
  • TCP 세션 활성화를 검증하여 확인
1
2
3
livenessProbe:
  tcpSocket:
    port: 80

헬스 체크 간격

  • Liveness Probe는 실패시 파드가 재시작하므로 실패까지의 체크 횟수를 설정
  • successThreshold는 1이상, Liveness Probe와 Startup Probe의 경우 반드시 1
  • 첫 번째 체크까지의 지연은 가급적 사용 x, Startup Probe 사용
설정 항목 내용
initialDelaySeconds 첫 헬스 체크까지의 지연(최대 failureThreshold까지 연장)
periodSeconds 헬스 체크 간격 시간(초)
timeoutSeconds 타임아웃까지의 시간(초)
successThreshold 성공이라고 판단하기까지 체크 횟수
failureThreshold 실패라고 판단하기까지 체크 횟수
1
2
3
4
5
6
livenessProbe:
  initialDelaySeconds: 5
  periodSeconds: 5
  timeoutSecods: 1
  successThreshold: 1
  failureThreshold: 1

헬스 체크 생성

  • 헬스 체크 방법 세 가지와 헬스 체크 방식 세가지로 총 9가지 패턴의 헬스 체크 가능
  • Liveness, Readiness, Startup Probe는 하나 이상 지정 가능
1
2
## 파드에 생성된 Probe 확인
$ kubectl describe pod sample-healthcheck | egrep -E "Liveness|Readiness"
추가 Ready 조건을 추가하는 파드 ready++(ReadinessGate)
  • 파드가 정말 Ready 상태인지 추가 체크
  • 클라우드 외부 로드밸런서와의 연계에 시간이 걸리는 경우 사용
  • 일반적인 파드의 Ready 판단만으로는 롤링 업데이트시 기존 파드가 한 번에 사라져 안전하게 업데이트 할 수 없는 경우 사용
  • ReadinessGate를 통과할 때까지 서비스 전송 대상 x, 롤링 업데이트 시 다음 파드 기동으로 이동 x
  • 여러개 사용 가능. 모든 상태가 Ready가 되지 않으면 파드는 Ready 상태가 되지 않음
Readiness Probe를 무시한 서비스 생성
  • 스테이트풀셋에서 Headless 서비스 사용 시 파드가 Ready가 되지 않아도 클러스터 구성을 위해 파드의 이름 해석이 필요한 경우가 존재
  • Readiness Probe가 실패한 경우에도 서비스에 연결되게 하려면 spec.publishNotReadyAddresses를 true로 설정

Startup Probe를 사용한 지연 체크와 실패

  • Startup Probe의 경우 failureThreshold의 값을 충분히 크게 두는 것이 좋음
1
2
3
4
5
## Startup Probe에서 감시하고 있는 파일 생성
$ kubectl exec -it sample-startup -- touch /root/startup

## Startup Probe가 성공한 후 Liveness와 Readiness Probe가 실행된 것을 알 수 있음
$ kubectl exec -it sample-startup -- head /root/log

컨테이너 라이플사이클과 재기동(restartPolicy)

  • 컨테이너 프로세스 정지 또는 헬스 체크 실패시 컨테이너 재기동 여부, 방식 설정
  • 잡은 Always 선택 불가
restartPolicy 내용
Always 파드 정지시 항상 파드 재기동
OnFailure 예상치 못하게 파드가 정지한 경우(종료 코드 0 이외) 파드 재기동
Never 파드 재기동 x

초기화 컨테이너

  • 파드 내에서 메인이 되는 컨테이너 기동 전 별도의 컨테이너 기동
  • 설정에 필요한 스크립트 등을 메인 컨테이너에 보관하지 않는 상태 유지 가능(보안, 이미지 용량 감소)
  • spec.initContainers 복수 지정 가능, 위에서부터 순차적 커맨드 실행
  • 저장소에서 파일 가져오기, 컨테이너 기동 지연, 설정 파일 동적 생성, 서비스 생성 확인, 메인 컨테이너 기동 전 체크 작업 등
1
2
## 초기화 컨테이너에서 추가된 파일 순서 확인
$ kubectl exec -it sample-initcontainer -- cat /usr/share/nginx/html/index.html

기동 직후와 종료 직전에 임의의 명령어 실행(postStart/preStop)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
## 기동 후 바로 확인한 상태
$ kubectl exec -it sample-lifecycle-exec -- ls /tmp
started

## 기동 20초 경과 후 확인한 상태
$ kubectl exec -it sample-lifecycle-exec -- ls /tmp
poststart started

## 파드 정지
$ kubectl delete -f sample-lifecycle-exec.yaml

## 삭제 요청 후 바로 확인한 상태
$ kubectl exec -it sample-lifecycle-exec -- ls /tmp
poststart prestop started
  • postStart는 비동기 실행이므로 기동시 파일을 배치하는 작업은 초기화 컨테이너를 사용하거나 Entrypoint 안에서 실행
  • postStart, preStop은 여러 번 실행될 가능성도 있음
  • postStart에 타임아웃 설정 불가
    • postStart 실행 중에는 Probe 실행되지 않음

파드의 안전한 정지와 타이밍

  • 기동 중인 파드의 삭제 요청이 쿠버네티스 API 서버에 도착시 비동기로 ‘preStop 처리 + SIGTERM 처리’와 ‘서비스에서 제외 설정’이 이루어짐
  • 서비스 제외 처리가 끝나기 전 몇 초간 ‘preStop 처리 + SIGTERM 처리’에서 대기하거나 요청을 받으면서 정지 처리하는 것이 효과적
    • 전자는 애플리케이션 수정 필요 x
  • 파드에는 spec.terminationGracePeriodSeconds(기본 30초) 설정값이 있음
    • 해당 시간 안에 ‘preStop 처리 + SIGTERM 처리’ 끝내야 함
    • 끝나지 않는 다면 SIGKILL 신호가 컨테이너에 전달되어 강제 종료
  • 강제 종료를 막기 위해 ‘preStop 처리 + SIGTERM 처리’완료 시간을 충분히 확보해야 함
  • preStop 처리만으로 terminationGracePeriodSeconds 시간을 모두 사용한 경우에느 추가로 2초가 SIGTERM 시간으로 확보됨
1
2
3
4
5
## terminationGracePeriodSeconds=3으로 삭제
$ kubectl delete pod sample-termination --grace-period 3

## 강제로 즉시 삭제
$ kubectl delete pod sample-termination --grace-period 0 --force

리소스를 삭제했을 때의 동작

  • 레플리카셋등의 상위 리소스가 삭제되면 하위 리소스가 되는 파드 등을 삭제하기 위해 gc수행
  • 생성된 파드에는 어떤 레플리카셋으로 생성됐는지 판별하기 위해 metadata.ownerReferences 아래에 자동으로 정보 저장
1
2
## 파드 정의에 포함돈 상위 리소스 정보 확인
$ kubectl get pods sample-rs-l23kds -o json | jq .metadata.ownerReferences
  • 삭제됐을 때 동작
    • Background(기본값)
      • 레플리카셋 즉시 삭제 후 파드는 gc가 백그라운드에서 비동기로 삭제
    • Foreground
      • 레플리카셋을 즉시 삭제하지 않고 deletionTimestamp, metadata.finalizers = foregroundDeletion으로 설정
      • gc가 각 파드에서 blockOwnerDeletion = true 인것을 삭제 (false인 것은 Foreground 삭제라도 Background로 삭제)
      • 모든 삭제가 끝나면 레플리카셋 삭제
    • Orphan
      • 레플리카셋 삭제시 파드 삭제를 하지 않음
    • Foreground 사용하려면 API 조작해여 함
Hugo로 만듦
JimmyStack 테마 사용 중