✔️ Pod의 LifeCycle
✔️ Pod의 Phase (파드의 단계)
✔ Pending
- 파드가 쿠버네티스 클러스터에서 승인되었지만, 하나 이상의 컨테이너가 설정되지 않았고 실행할 준비가 되지 않았다. 여기에는 파드가 스케줄되기 이전까지의 시간 뿐만 아니라 네트워크를 통한 컨테이너 이미지 다운로드 시간도 포함된다.
이미지의 크기가 크면 pending
시간이 오래걸린다.
그러나 이미지를 다 받았음에도 불구하고 여전히 pending
상태라면 문제 확인이 필요하다.Events
정보의 순서를 잘 보면 첫번째 순서가 스케줄링인데 스케줄러가 어떤 노드에 배치할 것인지를 결정한다.
워커 노드가 3대가 있을때 cpu, memory가 부족하다면 스케줄링을 할 수 없다.
insufficient node
~ 메세지를 출력 → 만족하는 노드가 없어 배치될 수 없다.
배치가 안되면 계속 pending
이 걸릴 수 밖에 없다.
스케줄링이 완료되면 해당 노드의 kubelet은 이미지를 받는다.
🔎 Pending이 지속되는 이유
- 배치할 수 있는 노드가 없어(insufficient node) 스케줄링 불가
- 이미지를 잘못 지정해서 이미지를 못받는 경우
- 프라이빗 레지스트리에 인증이 잘못되었음
- 컨테이너가 만들어졌지만 실행할 준비가 되지 않음
- 볼륨이 연결되지 않음
✔ Running
- 파드가 노드에 바인딩되었고, 모든 컨테이너가 생성되었다. 적어도 하나의 컨테이너가 아직 실행 중이거나, 시작 또는 재시작 중에 있다.
✔ Succeeded
- 파드에 있는 모든 컨테이너들이 성공적으로 종료되었고, 재시작되지 않을 것이다.
Return Code , Exit Code, Exit Signal 이 0인것은 정상 종료, 그 외의 모든 것은 비정상 종료
✔ Failed
- 파드에 있는 모든 컨테이너가 종료되었고, 적어도 하나 이상의 컨테이너가 실패로 종료되었다.
즉, 해당 컨테이너는 non-zero 상태로 빠져나왔거나(exited) 시스템에 의해서 종료(terminated)되었다.
✔ Unknown
- 어떤 이유에 의해서 파드의 상태를 얻을 수 없다. 이 단계는 일반적으로 파드가 실행되어야 하는 노드와의 통신 오류로 인해 발생한다.
알 수 없는 경우의 대부분은 컨트롤 플레인이 해당되는 워커 노드에 통신할 수 없어서 워커 노드의 상태를 알 수 없을 때 발생한다.
파드의 단계에는 이 외에 몇가지가 더 존재한다.
특히 pending
상태가 어떤 상태인지 아는 것이 제일 중요하다.
➕ Terminating이란 ?
kubectl delete
를 실행하면 Terminating
이라고 표시된다.Terminating
은 파드의 단계(status)에 포함되지 않으며 정상 종료시 SIGTERM 15
신호를 날린다.
파드를 삭제할 때 gracefully
하게 종료할 수 있는 기간이 부여되고 기본값은 30초이다.
즉, 실제 어플리케이션이 종료될 때까지 30초(default)를 기다린다.
그 안에 종료되지 않으면 SIGTERM 9
시그널을 전송한다.
만약 강제로 종료하고 싶다면 --force
플래그를 설정하면 된다.
파드의 상태에는 컨테이너의 상태도 영향을 미친다.
✔️ Container의 states (컨테이너의 상태)
✔ Waiting
만약 컨테이너가 Running
또는 Terminated
상태가 아니면, Waiting
상태이다. Waiting
상태의 컨테이너는 시작을 완료하는 데 필요한 작업(예를 들어, 컨테이너 이미지 레지스트리에서 컨테이너 이미지 가져오거나, 시크릿(Secret) 데이터를 적용하는 작업)을 계속 실행하고 있는 중이다. kubectl
을 사용하여 컨테이너가 Waiting
인 파드를 쿼리하면, 컨테이너가 해당 상태에 있는 이유를 요약하는 Reason 필드도 표시된다.
✔ Running
Running
상태는 컨테이너가 문제없이 실행되고 있음을 나타낸다. postStart
훅이 구성되어 있었다면, 이미 실행되고 완료되었다. kubectl
을 사용하여 컨테이너가 Running
인 파드를 쿼리하면, 컨테이너가 Running
상태에 진입한 시기에 대한 정보도 볼 수 있다.
✔ Terminated
Terminated
상태의 컨테이너는 실행을 시작한 다음 완료될 때까지 실행되었거나 어떤 이유로 실패했다. kubectl
을 사용하여 컨테이너가 Terminated
인 파드를 쿼리하면, 이유와 종료 코드 그리고 해당 컨테이너의 실행 기간에 대한 시작과 종료 시간이 표시된다.
컨테이너에 구성된 preStop
훅이 있는 경우, 컨테이너가 Terminated
상태에 들어가기 전에 실행된다.
Hooking
이라고 하는 것은 정상적인 절차로 진행되고 있을 때 무언가를 밀어넣는 것을 말한다.
start 후에 뭔가의 작업을 할 때 사용하는 것이 postStart 훅
이며preStop 훅
은 컨테이너가 Terminated
상태에 들어가기 전에 실행한다.
✔️ Container restart policy (컨테이너 재시작 정책)
사용 가능한 값은 Always
, OnFailure
그리고 Never
이며 기본값은 Always
이다.
vagrant@k8s-node1:~$ kubectl explain pods.spec.restartPolicy
KIND: Pod
VERSION: v1
FIELD: restartPolicy <string>
DESCRIPTION:
Restart policy for all containers within the pod. One of Always, OnFailure,
Never. Default to Always. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
📌 YAML 파일 작성시의 필드들은 두번째 명사부터 대문자를 사용한다.
두번째부터 대문자를 쓰는 것을 Camel Pattern
이라고 한다.
✔️ 지수 백오프 (Log Backoff)
myweb.yaml
apiVersion: v1
kind: Pod # kubectl api-resources
metadata:
name: myweb
spec:
containers:
- name: myweb
image: httpd:2.7
ports:
- containerPort: 80
protocol: TCP
일부러 존재하지 않는 httpd 이미지를 지정했다.
vagrant@k8s-node1:~/podlife$ kubectl get pods --watch
NAME READY STATUS RESTARTS AGE
myweb 0/1 ErrImagePull 0 75s
myweb-label-anno 1/1 Running 1 (46m ago) 11h
기본 재시작 정책이 always
이기 때문에 계속 재시작이 걸린다.
이때 재시작 하는 시간이 점점 길어지는데 이를 지수 백오프
라고한다.
vagrant@k8s-node1:~/podlife$ kubectl get pods --watch
NAME READY STATUS RESTARTS AGE
myweb 0/1 ErrImagePull 0 75s
myweb-label-anno 1/1 Running 1 (46m ago) 11h
myweb 0/1 ImagePullBackOff 0 79s
myweb 0/1 ErrImagePull 0 108s
myweb 0/1 ImagePullBackOff 0 119s
myweb 0/1 ErrImagePull 0 3m23s
myweb 0/1 ImagePullBackOff 0 3m35s
myweb 0/1 ErrImagePull 0 6m12s
myweb 0/1 ImagePullBackOff 0 6m23s
myweb 0/1 ErrImagePull 0 11m
myweb 0/1 ImagePullBackOff 0 11m
myweb 0/1 ErrImagePull 0 16m
myweb 0/1 ImagePullBackOff 0 16m
myweb 0/1 ErrImagePull 0 21m
myweb 0/1 ImagePullBackOff 0 21m
약 20분 정도의 시간을 두고 지켜보았다.
존재하지 않는 이미지를 지정했으므로 이미지 풀링을 할 수 없다.
재시작 정책에 의해서 백오프 : 원래대로 돌아감 한뒤 다시 이미지를 받는다.
재시작 정책이 always
이므로 백오프만 하게되면 계속 받기 시도를 하는 재시작이 걸린다.
그렇게되면 결과적으로는 실행에 실패할 작업이지만 재시작 정책에의해 불필요하게 리소스를 소모하게 된다.
이를 방지하기위해 지수적으로 재시작 간격을 점점 길게 두고 최대 5분으로 제한한다.
이후로 계속 5분마다 재시도를 한다.
그렇지만 정확히 10초, 20초, 40초가 걸리는 것은 아니다.Jitter(편차)
라는 것이 있다.
만약 파드에 컨테이너가 3개있다면 모든 컨테이너가 실행이 안될 수 있다.
3개의 컨테이너의 재시작 타이밍이 10초, 20초, 40초 완전하게 같게되면 재시작 순간에 리소스를 많이 사용하게 된다.
그래서 약간씩의 편차를 둔다.
📌 watch
명령 사용 팁--watch
옵션 : 값이 변경될 때만 출력이 변경watch
명령어는 unix 명령어이다.
vagrant@k8s-node1:~/podlife$ watch kubectl get pods,nodes,services
vagrant@k8s-node1:~/podlife$ kubectl get pods,nodes,services --watch
error: you may only specify a single resource type
--watch
옵션 사용시 여러개의 타입을 지정하는 것은 불가하다.
kubectl을 윈도우에 설치하면 watch 명령을 사용할 수 없다.
✔️ Pod conditions (파드의 컨디션)
파드는 하나의 PodStatus를 가지며, 그것은 파드가 통과했거나 통과하지 못한 PodConditions 배열을 가진다.
PodScheduled
: 파드가 노드에 스케줄되었다.ContainersReady
: 파드의 모든 컨테이너가 준비되었다.Initialized
: 모든 초기화 컨테이너가 성공적으로 완료(completed)되었다.Ready
: 파드는 요청을 처리할 수 있으며 일치하는 모든 서비스의 로드 밸런싱 풀에 추가되어야 한다.
✔️ Container probes (컨테이너 프로브)
프로브 는 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단(diagnostic)이다.
진단을 수행하기 위해서, kubelet은 컨테이너 안에서 코드를 실행하거나, 또는 네트워크 요청을 전송한다.
✔️ 프로브 종류
livenessProbe
- 컨테이너가 동작 중인지 여부를 나타낸다.
- 만약 활성 프로브(liveness probe)에 실패한다면, kubelet은 컨테이너를 죽이고, 해당 컨테이너는 재시작 정책의 대상이 된다.
- 만약 컨테이너가 활성 프로브를 제공하지 않는 경우, 기본 상태는 Success 이다.
readinessProbe
- 컨테이너가 요청을 처리할 준비가 되었는지 여부를 나타낸다.
- 만약 준비성 프로브(readiness probe)가 실패한다면, 엔드포인트 컨트롤러는 파드에 연관된 모든 서비스들의 엔드포인트에서 파드의 IP주소를 제거한다.
- 준비성 프로브의 초기 지연 이전의 기본 상태는 Failure 이다.
- 만약 컨테이너가 준비성 프로브를 지원하지 않는다면, 기본 상태는 Success 이다.
startupProbe
- 컨테이너 내의 애플리케이션이 시작되었는지를 나타낸다.
- 스타트업 프로브(startup probe)가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않는다.
- 만약 스타트업 프로브가 실패하면, kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리된다.
- 컨테이너에 스타트업 프로브가 없는 경우, 기본 상태는 Success 이다.
참고로 v1.19 이하에는 startupProbe
가 존재하지 않는다.
livenessProbe
컨테이너가 활성 상태라는 것은 컨테이너가 제대로 동작 중이라는 것이다.
동작 여부를 판단하는 프로브이다.
vagrant@k8s-node1:~/podlife$ kubectl explain pods.spec.containers.livenessProbe.exec
FIELDS:
command <[]string>
Command is the command line to execute inside the container, the working
directory for the command is root ('/') in the container's filesystem. The
command is simply exec'd, it is not run inside a shell, so traditional
shell instructions ('|', etc) won't work. To use a shell, you need to
explicitly call out to that shell. Exit status of 0 is treated as
live/healthy and non-zero is unhealthy.
exec 같은 경우는 하위에 또 필드가 있다.
command 필드 뒤에는 실행할 명령을 지정한다. list 타입의 string으로 지정한다.
vagrant@k8s-node1:~/podlife$ kubectl explain pods.spec.containers.livenessProbe.tcpSocket
KIND: Pod
VERSION: v1
RESOURCE: tcpSocket <Object>
DESCRIPTION:
TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported
TCPSocketAction describes an action based on opening a socket
FIELDS:
host <string>
Optional: Host name to connect to, defaults to the pod IP.
port <string> -required-
Number or name of the port to access on the container. Number must be in
the range 1 to 65535. Name must be an IANA_SVC_NAME.
tcpSocket
의 경우 호스트와 포트가 있고 포트는 필수사항이다.
포트는 1 ~ 65535 사이의 숫자로 쓰거나 IANA_SVC_NAME
이름을 지정할 수 있다.
Service Name and Transport Protocol Port Number Registry (iana.org)
해당 URL에서 IANA_SVC_NAME
이름을 확인할 수 있으며 이름은 주기적으로 변경된다.
예를 들어 80번 포트를 사용하고 싶다면 http
, www
, www-http
를 사용할 수 있다.
이름을 지정하는 경우를 많이 사용하지는 않는다.
호스트는 옵션 값이며 default 값은 자기 자신의 파드의 ip이다.
파드의 ip를 몇번으로 할지 지정할 수는 있긴 하나 사용하고 있지 않은 랜덤한 ip가 할당된다.
vagrant@k8s-node1:~/podlife$ kubectl explain pods.spec.containers.livenessProbe.httpGet
FIELDS:
host <string>
Host name to connect to, defaults to the pod IP. You probably want to set
"Host" in httpHeaders instead.
httpHeaders <[]Object>
Custom headers to set in the request. HTTP allows repeated headers.
path <string>
Path to access on the HTTP server.
port <string> -required-
Name or number of the port to access on the container. Number must be in
the range 1 to 65535. Name must be an IANA_SVC_NAME.
scheme <string>
Scheme to use for connecting to the host. Defaults to HTTP.
- 포트를 지정하는 부분이 있다.
- 스키마를 지정하는 부분의 default는 HTTP이며 다른 프로토콜을 지정할 수 있다.
- 경로가 있다면 경로를 지정할 수도 있다.
http://호스트 이름/포트(일반적으로 생략)/ 경로
https://호스트 이름 - 호스트를 지정하지 않으면 자기 자신이다.
- HTTP에 추가 헤더가 필요한 경우 헤더를 지정하면 헤더와 함께 요청한다.
✔️ 프로브 결과
- Success - 네트워크 신호를 컨테이너에 보냈을 때 응답이 돌아옴
- Failure - 원하는 결과가 아닐 때, 잘못된 값이 돌아올 때
- Unknown - 아무 응답이 돌아오지 않음, 진단 자체에 실패함
컨테이너를 만들고 start 되면 내부 App의 작동 여부는 상관없이 살아있다라고 판단한다.
하지만 컨테이너 시작 후 App의 start 도중 오류가 날 수 있다.
컨테이너의 start와 App의 정상 실행은 별개의 문제이다.
ex) mysql root pw 환경 변수를 주지 않았다면 컨테이너가 start되었지만 오류
livenessProbe
를 사용하지 않으면 어플리케이션 작동 여부는 판별하지 않는다.
우리는 컨테이너가 start 되는 것도 중요하지만 app이 제대로 작동하는 것도 중요하며 그것이 실질적으로 컨테이너가 제대로 작동한다고 볼 수 있는 것이다.
app이 살아있는지 죽어있는지 명확하게 판단하는것이 livenessProbe
이다.livenessProbe
진단 후 재시작 정책에 의해 재시작한다.
물론 재시작 정책이 never면 재시작하지 않고 always 또는 onfailure인 경우 재시작 정책에 의해 재시작을 한다.
따라서 livenessProbe
는 필수이다.
✔️ 체크 매커니즘
✔ exec
웹도 아니고 네트워크를 이용하는 서비스도 아닐 때 명령어를 실행
한다.
명령어의 상태 코드, 종료 코드, 종료 상태를 사용한다.
해당 App에서 상태를 명령어 형태로 체크할 수 있도록 제공하는 경우도 있다.
mysql이나 mariadb에서는 mysqladm ping
이라는 명령을 실행해서 컨테이너가 실행되고 있는지 확인할 수 있다.
✔ grpc
- 최근에 추가되었다. grpc로 만들어진 App을 진단하는 방법이 grpc이다.
✔ httpGet
- HTTP 200 이상 400 미만
- 1xx 정보
- 2xx 성공
- 3xx 리다이렉션
- 따라서 3xx 일부는 성공이라고 봐도 된다. (ex. HTTP -> HTTPS 변경)
- 4xx 클라이언트 오류
- 5xx 서버 오류
✔ tcpSocket
웹이 아닌 네트워크를 사용하는 서비스들은 (UDP 제외) TCP 통신을 연결해본다.
TCP는 기본적으로 3-way handshaking을 해야 연결이 되는데 이 과정을 걸어보는 것이다.
예로 88번이라는 포트에 서비스하지만 웹 서비스는 아니라면 HTTP 프로토콜을 전송해봤자 응답하지 않을 것이다.
그런 경우에는 TCP 소켓으로 TCP 포트가 열려있는지 응답이 돌아오는지를 확인한다.
프로브 매커니즘은 여러가지를 조합해서 사용할 수 있다.
✔️ 프로브 결과
livenessProbe
의 결과는 App이 작동할 때부터 진행된다.
vagrant@k8s-node1:~/podlife$ kubectl explain pods.spec.containers.livenessProbe
periodSeconds <integer>
How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
value is 1.
주기성을 가지고 체크한다. 기본값은 10초이며 최소값은 1초이다.
이러한 주기가 너무 짧으면 프로브 신호를 전송하는 것도 파드 입장에서는 부하가 될 수 있으므로 적당한 간격을 두는 것이 좋다.
failureThreshold <integer>
Minimum consecutive failures for the probe to be considered failed after
having succeeded. Defaults to 3. Minimum value is 1.
successThreshold <integer>
Minimum consecutive successes for the probe to be considered successful
after having failed. Defaults to 1. Must be 1 for liveness and startup.
Minimum value is 1.
failureThreshold
- 상태가 failed
되기 위한 기준successThreshold
- 상태가 successful
되기 위한 기준
consecutive(연속)으로 몇번을 성공해야 하는가에 달려있다.
컨테이너가 있고 프로브 신호를 보내서 정상 응답이 한번 돌아오면 성공이다.
이 값을 3이라고 세팅하면 프로브 신호를 보내고 성공 응답이 연속적으로 3번 돌아와야 성공으로 간주하겠다는 의미이다.
이는 2번 응답이 연속적으로 돌아왔지만 3번째 응답이 돌아오지 않으면 실패로 간주한다는 것이다.
실패는 연속적으로 3번의 실패가 돌아올 때까지 실패라고 간주하지 않는다.
initialDelaySeconds <integer>
Number of seconds after the container has started before liveness probes
are initiated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
기본적으로 세팅하지 않으면 0이다.
컨테이너가 start하고 어플리케이션을 실행할 때, 규모가 있는 Java 코드 같은 것들은 실행하는데 오래걸린다.
실행되는데만 몇분이 걸리는 경우가 있다.
만약 최소한 20분이 걸린다고 가정하자.
컨테이너가 start하고 App이 실행될 때 10초 후 프로브를 보냈는데 응답이 안돌아오는 경우가 있을 것이다.
또 다른 상황으로 App 가동까지 1분이 걸리며 30초 동안 10초 간격으로 3번의 프로브를 보냈다고 하자. 제대로 실행되기 전에 계속 재시작이 걸린다.
initialDelaySeconds
- App이 실행되기 전까지 유예기간을 준다.
즉, 최초의 프로브를 보내기전 딜레이를 준다.
App이 가동될 때까지 평균적으로 얼마정도의 시간이 걸리는지를 체크하고 설정해야 한다.
timeoutSeconds <integer>
Number of seconds after which the probe times out. Defaults to 1 second.
Minimum value is 1. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
timeoutSeconds
- 프로브의 응답이 돌아올 때까지 1초를 준다. 1초안에 응답이 돌아오지 않으면 실패로 간주한다.
✔️ 실습
livenessProbe
와 startupProbe
를 검증해보자
✔️ livenessProbe 실습
우선 livenessProbe
의 정상적인 작동을 확인해보자
myweb-liveness.yaml
apiVersion: v1
kind: Pod # kubectl api-resources
metadata:
name: myweb-liveness
spec:
containers:
- name: myweb
image: httpd
ports:
- containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: "/"
port: 80
vagrant@k8s-node1:~/podlife$ kubectl create -f myweb-liveness.yaml
pod/myweb-liveness created
vagrant@k8s-node1:~/podlife$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myweb-liveness 1/1 Running 0 6s
vagrant@k8s-node1:~/podlife$ kubectl describe pods myweb-liveness
Liveness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
http-get
방식port
: 80initialDelaySeconds
: 0초timeout
: 1초period
: 10초success(성공 횟수)
: 1failure
: 3
10초마다 한번씩 확인을 한다. 현재는 아무런 문제가 없는 상태이다.
에러를 발생시켜보자myweb-liveness-err.yaml
apiVersion: v1
kind: Pod # kubectl api-resources
metadata:
name: myweb-liveness-err
spec:
containers:
- name: myweb
image: httpd
ports:
- containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: "/"
port: 8080
vagrant@k8s-node1:~/podlife$ kubectl create -f myweb-liveness-err.yaml
pod/myweb-liveness-err created
vagrant@k8s-node1:~/podlife$ kubectl describe pods myweb-liveness-err
Liveness: http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
vagrant@k8s-node1:~/podlife$ kubectl get pods --watch
NAME READY STATUS RESTARTS AGE
myweb-liveness 1/1 Running 0 5m3s
myweb-liveness-err 1/1 Running 1 (26s ago) 57s
myweb-liveness-err 1/1 Running 2 (3s ago) 64s
myweb-liveness-err 1/1 Running 3 (3s ago) 94s
myweb-liveness-err 1/1 Running 4 (2s ago) 2m3s
재시작 중에도 상태는 Running
임을 확인할 수 있다.
10초마다의 간격으로 3번의 실패가 있어야 실패로 간주한다. 지수 백오프 간격은 계속 늘어날 것이다.
vagrant@k8s-node1:~/podlife$ kubectl describe pods myweb-liveness-err
Warning Unhealthy 4s (x4 over 34s) kubelet Liveness probe failed: Get "http://10.233.96.13:8080/": dial tcp 10.233.96.13:8080: connect: connection refused
describe를 통해 보면 8080 포트가 거부되었음을 알 수 있다.
어플리케이션이라고 하는 것은 전체적으로는 문제가 없지만 특정 조건에서 문제가 발생하는 경우가 있기 때문에 재시작을 하면 이상이 없을 가능성이 있다.
그렇다고 재시작이 만능 해결책은 아니다.
📌 livenessProbe
의 문제점livenessProbe
를 사용할 때initialDelaySeconds
로 유예기간을 둘 수 있다는 점을 간과하고 설정하지 않아 무기한 재시작이 걸리는 경우가 발생한다.
이를 위해 1.20 버전부터 추가된 기능으로 startupProbe
이 있다.startupProbe
는 어플리케이션이 시작될 때 적용된다.
즉, 어플리케이션이 시작되었는지를 프로브한다.
startupProbe
가 성공 상태가 되어야지만 livenessProbe
를 실행한다.
✔️ startupProbe 실습
myweb-startup.yaml
apiVersion: v1
kind: Pod
metadata:
name: myweb-startup
spec:
containers:
- name: myweb
image: httpd
ports:
- containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: "/"
port: 80
startupProbe:
exec:
command:
- "ls /tmp/abc"
startupProbe:
exec:
command:
- "ls /tmp/abc"
다음과 같이 절대 실행되지 않을 트릭을 걸어 startupProbe
가 실행되지 않으면 livenessProbe
가 실행되지 않는 것을 증명한다.
tmp에는 abc라는 하위 디렉토리가 존재하지 않는다.
vagrant@k8s-node1:~/podlife$ kubectl describe pods myweb-startup
Warning Unhealthy 3s (x7 over 63s) kubelet (combined from similar events): Startup probe errored: rpc error: code = Unknown desc = failed to exec in container: failed to start exec "4f40e5a8edf87badb831e1f7ef0ae83b5ea500b5f09616a3c34f2d817a7298b1": 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
Events
를 확인하면 Startup probe errored
가 발생한 것을 볼 수 있다.
livenessProbe
와 관련된 오류 메세지는 하나도 출력되지 않았다.startupProbe
가 실행되지 않았기 때문에 livenessProbe
는 실행 조차 안한것이다.
startupProbe
를 다음과 같이 변경하고 다시 시도해보자
myweb-startup.yaml
apiVersion: v1
kind: Pod # kubectl api-resources
metadata:
name: myweb-startup
spec:
containers:
- name: myweb
image: httpd
ports:
- containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: "/"
port: 80
startupProbe:
httpGet:
path: "/"
port: 80
vagrant@k8s-node1:~/podlife$ kubectl get pods --watch
NAME READY STATUS RESTARTS AGE
myweb-liveness 1/1 Running 0 5m22s
myweb-liveness-err 1/1 Running 6 (101s ago) 5m22s
myweb-startup 1/1 Running 0 12s
myweb-liveness-err 0/1 CrashLoopBackOff 6 (1s ago) 5m32s
vagrant@k8s-node1:~$ kubectl describe pods myweb-startup
Liveness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
Startup: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
정상적으로 실행되며 오류가 발생하지 않았다.startupProbe
, livenessProbe
모두 통과했다.
이 방식을 통해 어플리케이션이 제대로 작동하는지를 확인할 수 있다.
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] DaemonSet (데몬셋) (0) | 2022.05.20 |
---|---|
[Kubernetes] ReplicationController & ReplicaSets (0) | 2022.05.19 |
[Kubernetes] Annotation (어노테이션) (0) | 2022.05.18 |
[Kubernetes] Label, LabelSelector (레이블, 레이블셀렉터) (0) | 2022.05.18 |
[Kubernetes] Namespace ( + 오브젝트의 이름와 UID) (0) | 2022.05.18 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!