[kubernetes] POD Lifecycle

728x90

Pod Lifecycle

공식 문서: https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/

파드의 단계

파드의 status 필드는 phase 필드를 포함하는 PodStatus 오브젝트로 정의된다.

파드의 phase는 파드가 라이프사이클 중 어느 단계에 해당하는지 표현하는 간단한 고수준의 요약이다. Phase는 컨테이너나 파드의 관측 정보에 대한 포괄적인 롤업이나, 포괄적인 상태 머신을 표현하도록 의도되지는 않았다.

파드 phase 값에서 숫자와 의미는 엄격하게 지켜진다. 여기에 문서화된 내용 이외에는, 파드와 파드에 주어진 phase 값에 대해서 어떤 사항도 가정되어서는 안 된다.

phase에 가능한 값은 다음과 같다.

Pending: 스케줄링 되기 전, 이미지를 받기 전, 컨테이너가 준비되기 전

Running: 컨테이너가 실행 중, 실행 전, 재시작 중

Succeeded: 정상 종료(0)

Failed: 비정상 종료(!0)

Unknown: 어떤 이유에 의해서 파드의 상태를 얻을 수 없다. 이 단계는 일반적으로 파드가 실행되어야 하는 노드와의 통신 오류로 인해 발생한다.

Container 상태

  • Waiting: 이미지 받기 전, 볼륨 연결 되기 전
  • Running: 실행 중
  • Terminated: 종료

재시작 정책

  • pod.spec.restartPolicy
    • Always(기본)
    • OnFailure
    • Never

지수 백오프

  • 파드 실패 시 재시작 정책에 의해 재시작을 하게 됨
    • 재시작 시간 10, 20, 40, 80…300 초 까지 유예 시간을 갖는다.

컨테이너 프로브(probe)

프로브 는 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단(diagnostic)이다. 진단을 수행하기 위해서, kubelet은 컨테이너 안에서 코드를 실행하거나, 또는 네트워크 요청을 전송한다.

프로브 종류

  • livenessProbe: 컨테이너가 동작 중인지 여부를 나타낸다. 만약 활성 프로브(liveness probe)에 실패한다면, kubelet은 컨테이너를 죽이고, 해당 컨테이너는 재시작 정책의 대상이 된다. 만약 컨테이너가 활성 프로브를 제공하지 않는 경우, 기본 상태는 Success 이다.
    • kubectl explain pods.spec.containers.livenessProbe
  • readinessProbe: 컨테이너가 요청을 처리할 준비가 되었는지 여부를 나타낸다. 만약 준비성 프로브(readiness probe)가 실패한다면, 엔드포인트 컨트롤러는 파드에 연관된 모든 서비스들의 엔드포인트에서 파드의 IP주소를 제거한다. 준비성 프로브의 초기 지연 이전의 기본 상태는 Failure 이다. 만약 컨테이너가 준비성 프로브를 지원하지 않는다면, 기본 상태는 Success 이다.
    • kubectl explain pods.spec.containers.readinessProbe
  • startupProbe: 컨테이너 내의 애플리케이션이 시작되었는지를 나타낸다. 스타트업 프로브(startup probe)가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않는다. 만약 스타트업 프로브가 실패하면, kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리된다. 컨테이너에 스타트업 프로브가 없는 경우, 기본 상태는 Success 이다. startupProbe 의 상태가 Success 가 되어야만 livenessProbe 가 실행된다.
    • kubectl explain pods.spec.containers.startupProbe

체크 메커니즘

프로브를 사용하여 컨테이너를 체크하는 방법에는 4가지가 있다. 각 프로브는 다음의 4가지 메커니즘 중 단 하나만을 정의해야 한다.

exec: 컨테이너 내에서 지정된 명령어를 실행한다. 명령어가 상태 코드 0으로 종료되면 진단이 성공한 것으로 간주한다.

grpc: gRPC를 사용하여 원격 프로시저 호출을 수행한다. 체크 대상이 gRPC 헬스 체크를 구현해야 한다. 응답의 status 가 SERVING 이면 진단이 성공했다고 간주한다. gRPC 프로브는 알파 기능이며 GRPCContainerProbe 기능 게이트를 활성화해야 사용할 수 있다.

httpGet: 지정한 포트 및 경로에서 컨테이너의 IP주소에 대한 HTTP GET 요청을 수행한다. 응답의 상태 코드가 200 이상 400 미만이면 진단이 성공한 것으로 간주한다. 애플리케이션이 web app 일 경우 사용한다.

  • kubectl explain pods.spec.containers.livenessProbe.httpGet

tcpSocket: 지정된 포트에서 컨테이너의 IP주소에 대해 TCP 검사를 수행한다. 포트가 활성화되어 있다면 진단이 성공한 것으로 간주한다. 원격 시스템(컨테이너)가 연결을 연 이후 즉시 닫는다면, 이 또한 진단이 성공한 것으로 간주한다.

  • kubectl explain pods.spec.containers.livenessProbe.tcpSocket

프로브 결과

각 probe는 다음 세 가지 결과 중 하나를 가진다.

Success: 컨테이너가 진단을 통과함.

Failure: 컨테이너가 진단에 실패함.

Unknown: 진단 자체가 실패함(아무런 조치를 수행해서는 안 되며, kubelet이 추가 체크를 수행할 것이다)


오류를 일으키키 위한 코드는 아래와 같다. livenessProbe 의 port 를 80 으로 수정하면 정상 작동한다.

myweb-liveness-err.yml

apiVersion: v1
kind: Pod
metadata:
  name: myweb-liveness-err
  labels:
    APP: apache
    ENV: dev
  annotations:
    Created-by: Choi
spec:
  containers:
    - name: myweb
      image: httpd
      livenessProbe:
        httpGet:
          path: "/"
#          port: 80
          port: 8080
      ports:
        - containerPort: 80
          name: myweb
          protocol: TCP

Liveness probe 가 실패한 것을 describe 에서 확인할 수 있다.

kubectl create -f myweb-liveness-err.yml

kubectl describe pods myweb-liveness-err
...
Events:
  Type     Reason     Age   From               Message
  ----     ------     ----  ----               -------
  Normal   Scheduled  13s   default-scheduler  Successfully assigned default/myweb-liveness-err to node-2
  Normal   Pulling    12s   kubelet            Pulling image "httpd"
  Normal   Pulled     10s   kubelet            Successfully pulled image "httpd" in 1.932221412s
  Normal   Created    10s   kubelet            Created container myweb
  Normal   Started    10s   kubelet            Started container myweb
  Warning  Unhealthy  3s    kubelet            Liveness probe failed: Get "<http://10.233.69.13:8080/>": dial tcp 10.233.69.13:8080: connect: connection refused

--watch 옵션으로 상태를 추적하면 계속해서 재시작되는 것을 확인할 수 있다.

kubectl get pods --watch
NAME                 READY   STATUS    RESTARTS   AGE
myweb-liveness       1/1     Running   0          2m42s
myweb-liveness-err   1/1     Running   0          24s
myweb-liveness-err   1/1     Running   1 (3s ago)   34s
myweb-liveness-err   1/1     Running   2 (3s ago)   64s

오류를 발생시키기 위한 startup 코드는 아래와 같다.

myweb-startup.yml

apiVersion: v1
kind: Pod
metadata:
  name: myweb-startup
  labels:
    APP: apache
    ENV: dev
  annotations:
    Created-by: Choi
spec:
  containers:
    - name: myweb
      image: httpd
      livenessProbe:
        httpGet:
          path: "/"
          port: 80
      startupProbe:
        exec:
          command:
            - "ls /tmp/abc"
# httpGet 으로 정상 작동시킬 수 있다.
#        httpGet:
#          path: "/"
#          port: 80
      ports:
        - containerPort: 80
          name: myweb
          protocol: TCP

Startup probe 가 실패한 것을 describe 에서 확인할 수 있다.

또한 Startup probe 의 특성상 성공할 때까지 다른 나머지 프로브는 활성화되지 않는다.

Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------
  Normal   Scheduled  7m9s                   default-scheduler  Successfully assigned default/myweb-startup to node-3
  Normal   Pulling    7m9s                   kubelet            Pulling image "httpd"
  Normal   Pulled     7m7s                   kubelet            Successfully pulled image "httpd" in 1.869534872s
  Normal   Created    7m7s                   kubelet            Created container myweb
  Normal   Started    7m7s                   kubelet            Started container myweb
  Warning  Unhealthy  6m59s                  kubelet            Startup probe errored: rpc error: code = Unknown desc = failed to exec in container: failed to start exec "d159db91a9f554ab155bd15e47b782ee35adee733973ef21baa90450ca04792e": OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ls /tmp/abc": stat ls /tmp/abc: no such file or directory: unknown
  Warning  Unhealthy  6m49s                  kubelet            Startup probe errored: rpc error: code = Unknown desc = failed to exec in container: failed to start exec "b49bcf86f7748bcb6824f1868264dcd09031c62a82de86b6bef11117d6b80292": OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ls /tmp/abc": stat ls /tmp/abc: no such file or directory: unknown
728x90