1. 종료 요청
kubectl delete pod [POD_NAME]
명령을 실행하거나, Pod의 수명 주기 정책(Lifecycle Policy)에 의해 Pod가 종료되어야 할 때, kube-apiserver는 종료 요청을 받는다.2. SIGTERM 신호 전송
3. Graceful Shutdown 처리
4. SIGKILL 신호 전송
5. Pod 상태 업데이트 및 정리
Service는 같은 파일을 쓰고 Deployment를 변경하면서 테스트를 진행
테스트 환경은 minikube, 사용자의 트래픽은 Locust를 사용
nginx- service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- protocol: TCP
port: 8080
targetPort: 80
nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
cpu: 200m
memory: 250Mi
limits:
cpu: 1000m
memory: 500Mi
ports:
- containerPort: 80
종료 테스트는 kubectl rollout restart deployment nginx-deployment
로 진행
(StrategyType: RollingUpdate)
downtime 발생
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2 # 2로 변경
downtime 발생
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 4 # 4로 변경
downtime 발생
replicas를 늘려도 downtime이 발생함을 알 수 있다.
이는 롤링 업데이트 전략을 적용하더라도 새로운 pod이 준비되지 않았거나 건강하지 않은 상태에서 트래픽을 받게 되어 downtime이 발생하는 상황이다.
컨테이너가 정상적으로 작동하고 있는지 확인한다. Liveness Probe가 실패하면, kubelet은 컨테이너를 재시작한다. 이는 컨테이너가 데드락에 빠지거나 응답하지 않는 상태에서 자동으로 복구되도록 돕는다.
컨테이너가 트래픽을 받을 준비가 되었는지 확인한다. Readiness Probe가 실패하면, 쿠버네티스는 해당 포드를 서비스의 트래픽 대상에서 제외한다. 이는 컨테이너가 아직 초기화 중이거나, 일시적으로 트래픽을 처리할 수 없는 상태일 때 유용하다.
컨테이너의 초기화가 완료되었는지 확인한다. Startup Probe는 애플리케이션의 긴 초기화 시간 동안 Liveness Probe의 조기 재시작을 방지한다. 초기화가 완료된 후에는 Liveness Probe가 컨테이너의 상태를 지속적으로 모니터링한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
cpu: 200m
memory: 250Mi!
limits:
cpu: 1000m
memory: 500Mi
ports:
- containerPort: 80
name: http # 추가
# 추가
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 10
downtime 발생
Probe를 설정해도 downtime이 발생함을 알 수 있다.
이는 기존 Pod에 대한 요청이 아직 처리 중인데 Pod이 삭제되면, 연결이 강제로 종료되어 오류가 발생할 수 있다.
애플리케이션 레벨에서 Graceful Shutdown 로직을 구현할 수 있지만 preStop으로도 비슷한 효과를 낼 수 있다.
앞에서 말한 Pod의 종료 과정에서 preStop hook을 설정하면 컨테이너에 SIGTERM 신호를 보내기 전에 실행되므로 진행 중인 요청을 처리하고 리소스를 정리하는 등의 작업을 수행할 수 있다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
cpu: 200m
memory: 250Mi
limits:
cpu: 1000m
memory: 500Mi
ports:
- containerPort: 80
name: http
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 10
# 추가
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- sleep 20
zero-downtime 성공
preStop hook의 시간이 30초 이상 걸린다면 terminationGracePeriodSeconds의 시간을 조절해 줘야 한다.
AWS Load Balancer Controller를 사용할때, 로드 밸런서의 타깃 그룹 등록 상태를 Pod의 준비 상태로 반영할 수 있도록 해주는 설정이다.
AWS Load Balancer Controller는 타깃 그룹에 Pod가 성공적으로 등록되면 해당 Pod의 readinessGate를 성공 상태로 업데이트한다. 이는 Pod가 외부 로드 밸런서에 의해 트래픽을 받을 준비가 되었다는 것을 나타낸다.
Kubernetes 클러스터와 외부 로드 밸런서 간의 상태를 동기화하여, Pod가 실제로 외부 트래픽을 처리할 준비가 되었는지 보다 정확하게 반영한다.
$ kubectl create namespace readiness
namespace/readiness created
$ kubectl label namespace readiness elbv2.k8s.aws/pod-readiness-gate-inject=enabled
namespace/readiness labeled
$ kubectl describe namespace readiness
Name: readiness
Labels: elbv2.k8s.aws/pod-readiness-gate-inject=enabled
Annotations: <none>
Status: Active