쿠버네티스 교육/강의 내용 정리

220622_2_k8s_파드의 생명 주기와 프로브-livenessProbe, startupProbe

kimhope 2022. 6. 22. 16:36
728x90

파드의 생명 주기


파드의 생명 주기

오브젝트 상태 모니터링 (파드 생성)

vagrant@kube-master1:~$ kubectl get pods --watch

 

  • watch: 정해진 시간 뒤에 명령어를 실행함
vagrant@kube-master1:~$ watch -n1 kubectl get pods

 

kubelet

  • 쿠버네티스 노드의 구성 요소
  • 파드의 컨테이너 상태 추적
  • 오류 발생 시 정상 상태로 만들기 위한 조치로 컨테이너를 재시작할 수 있음

 

파드의 생명 주기

  • 파드는 정의된 순서대로 생명 주기를 가짐 (Pending > Running > Succeeded or Failed)
  • 파드는 임시로 사용하기 위한 워크로드 리소스 (영구적으로 사용 X)
  • 파드가 생성되면 파드를 식별하기 위한 고유의 UID가 할당되고, 종료될 때까지 특정 노드에서만 실행
  • 쿠버네티스는 파드를 일회용으로 간주하며, 상위 레벨의 추상화 리소스인 컨트롤러 리소스를 이용하여 파드 관리

 

파드의 단계

  • kubectl get pods 명령 결과 중 STATUS 필드에서 확인
Pending - 파드가 클러스터에서 승인되었지만, 실행되고 있지 않음
- 파드가 스케줄링되기 전
- 이미지 풀링
Running - 파드가 노드에 할당됨
- 하나 이상의 컨테이너가 실행 중
- 시작 또는 재시작 중
Succeeded - 모든 컨테이너가 정상적으로 종료
- 재시작되지 않음
Failed - 모든 컨테이너가 종료
- 하나 이상의 컨테이너가 실패로 종료
Unknown - 알 수 없음
- 일반적으로 노드와의 통신 오류

 


 

 

컨테이너 상태

컨테이너 상태

  • 스케줄러가 파드를 특정 노드에 할당하면, kubelet은 컨테이너 런타임을 이용하여 컨테이너를 생성하며, kubelet은 컨테이너의  상태를 주기적으로 모니터링
  • 컨테이너의 상태는 kubectl describe pod 명령의 결과 중 Containers 항목으로 확인 가능
Waiting - 컨테이너가 Running 또는 Terminated 상태가 아닌 상태
- 컨테이너 시작 전 필요한 작업 중(이미지 풀링, 스토리지 연결 등)
- Reason 필드에 이유가 표시됨
Running - 실행 중
- 해당 상태가 된 시각 표시
Terminated - 컨테이너 실행이 완료됨
- 실패
- Reason 필드에 이유가 표시됨
- 해당 상태가 된 시각 표시

 

컨테이너 재시작 정책

.spec.restartPolicy: 재시작 정책

  • 모든 컨테이너는 컨테이너의 오류 발생 시 재시작을 하기 위한 재시작 정책을 가지고 있음
  • 최대 300초로 제한된 지수 백오프 지연 시간을 순차적으로 가지며 재시작 (10초, 20초, 40초, 80초, ...)
  • 10동안 이상 없이 동작하면 지수 백오프 지연 시간 초기화
Always - 기본값
- 종료/실패 시 항상 재시작
Onfailure 실패 시 재시작 (정상 종료 시 재시작하지 않음)
Never 재시작 하지 않음

 

 


 

kubelet으로 컨테이너 진단


컨테이너 프로브

컨테이너 프로브는 kubelet이 컨테이너를 주기적으로 진단하는 프로브 핸들러를 호출함

  • 프로브 핸들러
  • 세 가지 메커니즘을 가지고 컨테이너의 상태 진단
HTTPGetAction - 특정 경로에 HTTP GET 요청
- HTTP 응답 코드가 2XX 또는 3XX 인지 확인함
TCPSocketAction - 특정 TCP 포트 연결
- 포트가 활성화되어 있는지 확인
ExecAction - 컨테이너 내의 지정된 바이너리 실행
- 명령의 종료 코드가 0인지 확인

 

  • 프로브 핸들러 상태
Success 진단 통과
Failure 진단 실패
Unknown 진단 자체가 실패

 

  • 프로브 종류
livenessProbe - 컨테이너가 동작 중인지 확인
- 진단에 실패하면 재시작 정책 적용
- livenessProbe를 선언하지 않으면, 기본 상태는 Success
readinessProbe - 컨테이너가 요청을 처리할 준비가 되었는지 확인
- 진단에 실패하면 엔드포인트 컨트롤러는 파드의 IP 주소를 엔드포인트에서 제거
- readinessProbe를 선언하지 않으면, 기본 상태는 Success
startupProbe - 컨테이너 내의 애플리케이션이 시작되었는지 확인
- startupProbe가 선언되었을 경우, 진단을 통과하기 전까지 다른 프로브를 활성화하지 않음

 

 

  • 프로브 정의
.spec.containers.*Probe 라이브니스 프로브 정의
.spec.containers.*Probe.httpGet HTTP GET 프로브 정의
.spec.containers.*Probe.tcpSocket TCP 소켓 프로브 정의
.spec.containers.*Probe.exec Exec 프로브 정의

 

 


 

livenessProbe

livenessProve란

  • 컨테이너가 실행되었는지 확인하고 진단이 실패하면 컨테이너를 종료시키고, 재시작 정책에 따라서 컨테이너를 재시작함
  • 컨테이너에 livenessProbe를 명시하지 않았다면 기본 상태 값 Success로 표시

 

정상 실행

  • testapp-pod-liveness.yaml 파일 생성
# testapp-pod-liveness.yaml

apiVersion: v1
kind: Pod
metadata:
  name: testapp-pod-liveness
spec:
  containers:
  - image: ghcr.io/c1t1d0s7/go-myweb
    name: testapp
    ports:
    - containerPort: 8080
      protocol: TCP
    livenessProbe:
      httpGet:
        path: /health
        port: 8080

 

  • 파드 생성
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod-liveness.yml
pod/testapp-pod-liveness created

 

  • 실행 결과 확인
vagrant@kube-master1:~/test$ kubectl get pods --watch
NAME                READY   STATUS    RESTARTS   AGE
testapp-pod-liveness   0/1     Pending       0          0s
testapp-pod-liveness   0/1     Pending       0          0s
testapp-pod-liveness   0/1     ContainerCreating   0          0s
testapp-pod-liveness   1/1     Running             0          3s

 

비정상 실행: 404

  • liveness 작동을 확인하기 위해 에러가 발생하도록 설정
  • livenessProbe.httpGet.path 부분 수정
#testapp-pod-liveness-404.yaml

apiVersion: v1
kind: Pod
metadata:
  name: testapp-pod-liveness-404
spec:
  containers:
  - image: ghcr.io/c1t1d0s7/go-myweb
    name: testapp
    ports:
    - containerPort: 8080
      protocol: TCP
    livenessProbe:
      httpGet:
        path: /health?code=404
        port: 8080

 

  • 파드 생성
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod-liveness-404.yml
pod/testapp-pod-liveness-404 created

 

  • 파드 상태 확인
  • 시간이 지나면 RESTART 필드가 0에서 양수로 변경됨
  • => livenessProbe에 의해 컨테이너가 건강한 상태가 아님을 감지하고 재시작을 시도했다는 의미
  • 시간이 더 지나면 CrashLoopBackOff 상태인 것을 확인할 수 있음
  • => 지수 백오프 지연을 나타냄
vagrant@kube-master1:~/test$ kubectl get pods --watch
NAME                READY   STATUS    RESTARTS   AGE
testapp-pod-liveness-404   0/1     Pending             0          0s
testapp-pod-liveness-404   0/1     Pending             0          0s
testapp-pod-liveness-404   0/1     ContainerCreating   0          0s
testapp-pod-liveness-404   1/1     Running             0          3s
testapp-pod-liveness-404   1/1     Running             1          33s
testapp-pod-liveness-404   1/1     Running             2          62s
testapp-pod-liveness-404   1/1     Running             3          92s
testapp-pod-liveness-404   1/1     Running             4          2m2s
testapp-pod-liveness-404   0/1     CrashLoopBackOff    4          2m31s

 

  • Containers.Liveness 필드 값 확인
  • livenessProbe의 경우 초기 지연 시간(initialDelaySeconds)을 설정하는 것이 중요한데, 파드(컨테이너)가 실행되고 난 이후 애플리케이션에 따라 애플리케이션이 정상 동작하는 데 시간이 걸릴 수 있기 때문임
  • 간혹 초기 지연 시간을 설정하지 않아 계속적인 재시작을 초래할 수 있음
  • livenessProbe가 동작하여 컨테이너를 종료하고 재시작하는 것을 확인할 수 있음
vagrant@kube-master1:~/test$ kubectl describe pods testapp-pod-liveness-404
~
 Liveness:       http-get http://:8080/health%3Fcode=404 delay=0s timeout=1s period=10s #success=1 #failure=3
~

delay - 프로브를 초기화 하기 전 지연
- 기본값: 0초
- .spec.contianers.*Probe.initialDelaySeconds
timeout - 프로브 타임아웃
- 기본값: 1초
- .spec.containers.*Probe.timeoutSeconds
period - 프로브 주기
- 기본값: 10초
- .spec.containers.*Probe.periodSeconds
success - 진단 성공 임계값
- 기본값: 1
- .spec.containers.*Probe.successThreshold
failure - 진단 실패 임계값
- 기본값: 3
- .spec.containers.*Probe.failureThreshold

 


 

startupProbe

startupProbe란

  • 컨테이너 내의 애플리케이션이 시작되었는지 확인
  • startupProbe가 선언되었을 경우, 진단을 통과하기 전까지 다른 프로브를 활성화하지 않음
  • startupProbe가 실패하면 kubelet은 컨테이너를 종료하고 컨테이너는 재시작 정책을 수행함

 

정상 실행

  • 파일 생성
vagrant@kube-master1:~/test$ cat testapp-pod-startup.yml

apiVersion: v1
kind: Pod
metadata:
  name: testapp-pod-startup
spec:
  containers:
  - name: testapp
    image: ghcr.io/c1t1d0s7/go-myweb
    ports:
    - containerPort: 8080
    startupProbe:
      httpGet:
        path: /health
        port: 8080
    livenessProbe:
      httpGet:
        path: /health
        port: 8080

 

  • 파드 생성
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod-startup.yml
pod/testapp-pod-startup created

 

  • 실행 결과
  • 파드가 정상적으로 생성됨
vagrant@kube-master1:~$ kubectl get pods --watch

 

vagrant@kube-master1:~$ watch -n1 kubectl get pods

 

vagrant@kube-master1:~$ kubectl describe pod testapp-pod-startup

 

비정상 실행: 404

  • 파일 생성
  • 파드가 정상적으로 생성되지 않도록 파일 수정
  • startupProbe.httpGet.path 부분 수정
vagrant@kube-master1:~/test$ cat testapp-pod-startup-404.yml

apiVersion: v1
kind: Pod
metadata:
  name: testapp-pod-startup-404
spec:
  containers:
  - name: testapp
    image: ghcr.io/c1t1d0s7/go-myweb
    ports:
    - containerPort: 8080
    startupProbe:
      httpGet:
        path: /health?code=404
        port: 8080
    livenessProbe:
      httpGet:
        path: /health
        port: 8080

 

  • 파드 생성
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod-startup-404.yml
pod/testapp-pod-startup-404 created

 

  • 실행 결과
  • 파드의 상태가 Running 상태이지만 준비(READY 0/1)가 되지 않고 있음
  • startupProbe에 실패한 것을 확인할 수 있음
  • startupProbe에 실패하면 livenessProbe는 활성화되지 않음
vagrant@kube-master1:~$ kubectl get pods --watch

 

vagrant@kube-master1:~$ watch -n1 kubectl get pods

 

vagrant@kube-master1:~$ kubectl describe pod testapp-pod-startup-404

728x90