-
[Kubernetes] ReadinessProbe 알아보기Kubernetes 2023. 6. 16. 12:29728x90반응형
- 목차
들어가며.
이번 글에서는 쿠버네티스의 ReadinessProbe 설정이 대해서 알아보려고 합니다.
쿠버네티스는 3가지 Probe 설정을 취합니다.
첫번째 Probe 는 livenessProbe 이고, 두번째 Probe 는 이번 글에서 알아볼 주제인 readinessProbe 입니다.
그리고 마지막으로 startupProbe 가 존재합니다.
Probe 는 Pod 의 컨테이너의 상태를 체크할 수 있는 기능입니다.
kubelet 은 주기적으로 Pod 의 컨테이너의 상태 체크를 수행하게 되는데요.
이름 그대로 livenessProbe 는 컨테이너가 정상적으로 살아있는지를 확인하는 절차입니다.
만약 livenessProbe 를 통한 상태체크의 결과가 정상적이지 않다면 해당 컨테이너는 재시작되게 됩니다.
그리고 readinessProbe 는 컨테이너가 외부에서 발생하는 요청을 정상적으로 처리할 준비가 되었는지를 판단합니다.
readinessProbe 가 정상적으로 동작한다면 이 시점부터 외부 네트워크 트래픽이 해당 Pod 의 컨테이너로 전달됩니다.
HTTP Api 서버 준비하기.
ReadinessProbe 를 실습하기 위해서 먼저 간단한 API 서버를 만들어보겠습니다.
3개의 파일이 필요합니다.
파일의 구성은 아래와 같구요. 모두 같은 Path 에 위치합니다.
├── Dockerfile ├── fast_api_main.py ├── requirements.txt
requirements.txt
annotated-types==0.6.0 anyio==4.3.0 click==8.1.7 exceptiongroup==1.2.0 fastapi==0.110.1 h11==0.14.0 idna==3.7 pydantic==2.6.4 pydantic_core==2.16.3 sniffio==1.3.1 starlette==0.37.2 typing_extensions==4.11.0 uvicorn==0.29.0
fast_api_main.py
from fastapi import FastAPI app = FastAPI() @app.get("/health") def health_check(): return {"message": ""}
Dockerfile.
FROM python:3.9 WORKDIR /code/app COPY ./requirements.txt /code/requirements.txt RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY . /code/app CMD ["uvicorn", "fast_api_main:app", "--host", "0.0.0.0", "--port", "8000"]
도커 이미지 만들기.
아래의 docker build 명령어를 통해서 도커 이미지를 생성합니다.
docker build -t fastapi:0.0.1 .
REPOSITORY TAG IMAGE ID CREATED SIZE fastapi 0.0.1 d1ff227f8298 5 minutes ago 1.02GB
KinD 로 쿠버네티스 실행하기.
아래의 링크는 KinD 로 로컬 환경에서 쿠버네티스를 실행할 수 있는 가이드를 담고 있습니다.
https://westlife0615.tistory.com/407
FastAPI 어플리케이션에 대한 도커 이미지를 생성하였기 때문에 쿠버네티스를 실행시킵니다.
FastAPI 도커 이미지를 쿠버네티스에 추가하기.
저희는 생성한 이미지를 Docker Hub 와 같은 레지스트리에 등록하지 않을 예정입니다.
그래서 아래와 같은 명령어를 통해서 KinD 로컬 쿠버네티스 내부로 이미지를 등록합니다.
kind load docker-image fastapi:0.0.1 --name test-cluster
Image: "fastapi:0.0.1" with ID "sha256:d1ff227f8298d61ce2379f7b67f24da98ad8a1136a3585d5385f2c144e12e1b9" not yet present on node "test-cluster-control-plane", loading...
Pod 와 Service 생성하기.
Pod 와 Service 를 위한 yaml 파일을 생성합니다.
아래의 /tmp/fastapi.yaml 파일은 하나의 Static Pod 와 Service 를 생성하는 내용을 담습니다.
그리고 위에서 생성한 Docker Image 를 기반으로 합니다.
cat <<EOF> /tmp/fastapi.yaml apiVersion: v1 kind: Pod metadata: name: fastapi namespace: default labels: app: fastapi spec: containers: - name: fastapi-container image: fastapi:0.0.1 imagePullPolicy: Never ports: - containerPort: 8000 readinessProbe: httpGet: path: /health port: 8000 initialDelaySeconds: 3 periodSeconds: 3 restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: fastapi-service namespace: default spec: selector: app: fastapi ports: - protocol: TCP port: 8000 targetPort: 8000 EOF
< Pod 와 Service 생성 Kubectl 명령어 >
kubectl apply -f /tmp/fastapi.yaml
ReadinessProbe 란 ?
위에서 간단히 설정하였지만, readinessProbe 를 통해서 Pod 의 컨테이너를 외부의 네트워크 트래픽을 전달받을 수 있습니다.
즉, ReadinessProbe 에 의해서 컨테이너의 준비 상태가 정상임이 파악되어야 비로소 클라이언트의 요청을 처리할 수 있게 됩니다.
이를 Pod 의 상태 관점에서 본다면 Running 상태에서 Ready 상태로 변경되는 기준을 제공합니다.
만약 ReadinessProbe 에 의해서 준비 단계에 대한 검증을 패스하지 못한다면,
아래의 Pod 의 상태가 아래처럼 READY 가 1/1 로 출력되지 않습니다.
0/1 과 같이 실행 중인 컨테이너가 없음이 표시되죠.
kubectl -n default get pod fastapi
NAME READY STATUS RESTARTS AGE fastapi 1/1 Running 0 3m22s
그리고 Ready 상태가 되어야지만 Service 와 Endpoint 가 연결됩니다.
Service 는 외부의 네트워크 트래픽을 Pod 에게 전달하는 기능을 수행합니다.
그리고 Endpoint 가 Pod 와 Pod 의 IP 를 Service 에게 제공하는 매개체 역할을 수행하죠.
Pod 가 Ready 상태가 되지 못한다면 Service 와 Endpoint 의 연결이 수립되지 않습니다.
Service 와 Endpoint.
Kubernetes 의 Service 에 대한 자세한 설명은 아래의 링크로 대체하겠습니다.
https://westlife0615.tistory.com/212
Ready 상태의 Pod 와 Service & Endpoint.
간단히 Ready 상태의 Pod 와 Service 가 어떻게 연결되어 있는지 살펴보겠습니다.
Pod 의 상태는 아래와 같습니다.
1개의 Container 가 정상적으로 동작 중이구요. Pod 의 상태 또한 Running 입니다.
kubectl get pod fastapi
NAME READY STATUS RESTARTS AGE fastapi 1/1 Running 0 8m26s
그리고 Pod 의 IP 는 10.244.0.9 로 설정되어 있죠.
kubectl get pod fastapi -o=jsonpath='{.status.podIP}'
10.244.0.9%
아래는 Service 의 상태입니다.
눈여겨 보아야할 점은 Endpoints 가 Pod 의 IP 인 10.244.0.9 로 설정되어 있다는 점입니다.
kubectl describe service fastapi-service
Name: fastapi-service Namespace: default Labels: <none> Annotations: <none> Selector: app=fastapi Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.241.183 IPs: 10.96.241.183 Port: <unset> 8000/TCP TargetPort: 8000/TCP Endpoints: 10.244.0.9:8000 Session Affinity: None Events: <none>
이렇게 Ready 상태의 Pod 는 Service 와 Endpoint 에 의해서 외부 트래픽을 수용할 수 있게 됩니다.
Not-Ready 상태의 Pod 와 Service & Endpoint.
Not-Ready 상태를 구현하기 위해서 저는 Pod 의 ReadinessProbe 를 수정하였습니다.
간단히 readinessProbe 의 httpGet 의 path 를 존재하지 않는 API Path 로 설정하였습니다.
cat <<EOF> /tmp/fastapi.yaml apiVersion: v1 kind: Pod metadata: name: fastapi namespace: default labels: app: fastapi spec: containers: - name: fastapi-container image: fastapi:0.0.1 imagePullPolicy: Never ports: - containerPort: 8000 readinessProbe: httpGet: path: /health-unknown port: 8000 initialDelaySeconds: 3 periodSeconds: 3 restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: fastapi-service namespace: default spec: selector: app: fastapi ports: - protocol: TCP port: 8000 targetPort: 8000 EOF
kubectl apply -f /tmp/fastapi.yaml
결과는 아래와 같습니다.
먼저 Pod 는 Ready 상태가 되지 못합니다.
kubectl get pod fastapi
NAME READY STATUS RESTARTS AGE fastapi 0/1 Running 0 25s
그리고 Service 또한 Endpoint 가 연결되지 않습니다.
kubectl describe service fastapi-service
Name: fastapi-service Namespace: default Labels: <none> Annotations: <none> Selector: app=fastapi Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.241.183 IPs: 10.96.241.183 Port: <unset> 8000/TCP TargetPort: 8000/TCP Endpoints: Session Affinity: None Events: <none>
ReadinessProbe 설정.
어떻게 ReadinessProbe 를 설정할 수 있는지에 대해서 알아보겠습니다.
Probe 의 적용 대상은 Pod 이며, 구체적으로 Pod 내부의 Container 를 그 대상으로 삼습니다.
Running 또는 Ready 상태가 아닌 Container 의 Health Check 와 조치를 취할 수 있습니다.
httpGet.
httpGet 은 Container 의 어플리케이션의 Probe Health Check 를 수행할 수 있도록 설정할 수 있는 방법 중 하나입니다.
http 프로토콜을 기반으로 Probe 를 적용하는 만큼 웹 애플리케이션 서버에게 이러한 Probe 방식이 적합합니다.
특정 Path 로 Health Check API 를 만들고 이를 외부로 노출시켜 사용합니다.
제가 실습을 위해서 사용한 FastAPI 예시에서 /health 라는 이름으로 API 를 만들어 사용하였고,
항상 200 StatusCode 를 리턴하도록 설계되어 있습니다.
initialDelaySeconds.
kubelet 은 Pod 의 Probe Health Check 를 수행합니다.
initialDelaySeconds 는 이름에서 유추할 수 있듯이, 최초 Probe Health Check 를 수행하기 전 대기하는 시간입니다.
아래 로그는 FastAPI 의 로그입니다.
저는 initialDelaySeconds 를 10초로 설정해두었는데요.
아래의 로그처럼 최초 서버 시작 로그 이후에 10초 정도가 지난 후에 최초의 /health API 가 호출됨을 확인할 수 있습니다.
2023-01-12T03:18:02+09:00 INFO: Started server process [1] 2023-01-12T03:18:02+09:00 INFO: Waiting for application startup. 2023-01-12T03:18:02+09:00 INFO: Application startup complete. 2023-01-12T03:18:02+09:00 INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) 2023-01-12T03:18:13+09:00 INFO: 10.244.0.1:36282 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:18:16+09:00 INFO: 10.244.0.1:36288 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:18:19+09:00 INFO: 10.244.0.1:36304 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:18:22+09:00 INFO: 10.244.0.1:34438 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:18:25+09:00 INFO: 10.244.0.1:34454 - "GET /health HTTP/1.1" 200 OK
periodSeconds.
periodSeconds 는 주기적으로 Health Check 를 수행하는 주기입니다.
아래는 FastAPI 의 로그인데요.
저는 periodSeconds 를 3초로 설정하였고, 아래와 같이 3초 주기로 /health API 가 호출됨을 확인할 수 있죠.
2023-01-12T03:54:32+09:00 INFO: 10.244.0.1:55196 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:35+09:00 INFO: 10.244.0.1:55206 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:38+09:00 INFO: 10.244.0.1:43406 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:41+09:00 INFO: 10.244.0.1:43422 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:44+09:00 INFO: 10.244.0.1:43432 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:47+09:00 INFO: 10.244.0.1:43442 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:50+09:00 INFO: 10.244.0.1:50598 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:53+09:00 INFO: 10.244.0.1:50612 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:56+09:00 INFO: 10.244.0.1:50628 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:54:59+09:00 INFO: 10.244.0.1:56818 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:55:02+09:00 INFO: 10.244.0.1:56826 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:55:05+09:00 INFO: 10.244.0.1:56838 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:55:08+09:00 INFO: 10.244.0.1:42786 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:55:11+09:00 INFO: 10.244.0.1:42798 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:55:14+09:00 INFO: 10.244.0.1:42810 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:55:17+09:00 INFO: 10.244.0.1:42822 - "GET /health HTTP/1.1" 200 OK 2023-01-12T03:55:20+09:00 INFO: 10.244.0.1:42514 - "GET /health HTTP/1.1" 200 OK
반응형'Kubernetes' 카테고리의 다른 글
Kubernetes Ephemeral Volume (0) 2023.08.09 [Kubernetes] Service 이해하기 (0) 2023.08.01 Kubernetes Pod 이해하기 (0) 2023.07.26 Kubernetes Event 이해하기 (0) 2023.06.16 [Kubernetes] Metrics Server 알아보기 (0) 2023.05.09