일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 쿠버네티스
- aws saa
- EC2 인스턴스
- FTP
- IAM
- aws SAA-c03
- KUBECTL
- docker
- GNS3
- load balancer
- Kubernetes
- DNS
- SAA-C03
- Troubleshooting
- aws iam
- AWS 자격증
- aws cloud
- NAT
- 네트워크
- tftp
- Firewall
- aws cloud school
- aws cloud shcool 8
- Ebs
- linux
- vyos
- EC2
- vmware
- ALB
- AWS
- Today
- Total
나의 공부기록
[Kubernetes] 08. Container Health Check(컨테이너 헬스체크) - livenessProbe, readinessProbe 본문
[Kubernetes] 08. Container Health Check(컨테이너 헬스체크) - livenessProbe, readinessProbe
나의 개발자 2025. 4. 17. 17:46Container Health Check (컨테이너 헬스체크)
1️⃣ livenessProbe
- livenessProbe가 실패 시, 컨테이너를 재시작
➡️ 컨테이너에 이상이 있다고 간주
2️⃣ readinessProbe
- 실패해도 정상동작하지만, 서비스에서 해당 Pod로 트래픽을 인가하지 않음
- 보통 livenessProbe보다 readinessProbe를 많이 사용함
httpGet을 통한 probe
1. 디렉토리 생성
root@master-250410:~/mani# mkdir -p 250417/probe
root@master-250410:~/mani# cd 250417/probe/
root@master-250410:~/mani/250417/probe#
2. pod 컨테이너 정의
- periodSeconds : 헬스체크 주기
- initialDelaySeconds : 부팅 대기 시간
- 처음에 2초 대기 후, 5초에 한 번씩 curl localhost/와 비슷하다고 생각하면 좋음
root@master-250410:~/mani/250417/probe# vi pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: 61.254.18.30:5000/nginx
# 일반적인 Pod의 컨테이너 정의
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
initialDelaySeconds: 2
3. Pod 컨테이너 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f pod.yml
pod/nginx-pod created
4. 결과 확인
- 컨테이너 정상 작동 확인
root@master-250410:~/mani/250417/probe# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 10s 10.244.1.14 worker1-250410 <none> <none>

- Readiness 결과 확인
root@master-250410:~/mani/250417/probe# kubectl describe pod nginx-pod
- health check에 1번 성공 / 3번 실패 ➡️ delay 시간을 늘려주면 성공이 늘것 같음


5. Health Check 실패 경우 확인
5-1. 실패하는 Pod 정의
root@master-250410:~/mani/250417/probe# cp pod.yml rf-pod.yml
root@master-250410:~/mani/250417/probe# vi rf-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: 61.254.18.30:5000/nginx
readinessProbe:
httpGet:
path: /
port: 800
periodSeconds: 5
initialDelaySeconds: 2
5-2. 실패하는 Pod 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f rf-pod.yml
pod/rf-nginx-pod created
5-3. Pod 접속 실패 확인


6. Service
- ClusterIP 타입(기본값)으로 svc 생성
6-1. Service 정의
root@master-250410:~/mani/250417/probe# vi svc.yml
apiVersion: v1
kind: Service
metadata:
name: svc-test
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
6-2. Service 반영
root@master-250410:~/mani/250417/probe# kubectl apply -f svc.yml
service/svc-test unchanged
6-3. Service 생성 확인

6-4. 접속 거부 확인

6-5. SVC에 Endpoint에 포함되지 않음을 확인

- 컨테이너가 준비가 되지 않았지만, 커네이너가 작동이 잘 되는 것을 확인 가능

- rf-nginx-pod 포트 수정
root@master-250410:~/mani/250417/probe# vi rf-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: rf-nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: 61.254.18.30:5000/nginx
#일반적인 pod의 컨테이너 정의
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
initialDelaySeconds: 2
6-6. 컨테이너 삭제 & 시작
root@master-250410:~/mani/250417/probe# kubectl delete -f rf-pod.yml
pod "rf-nginx-pod" deleted
root@master-250410:~/mani/250417/probe# vi rf-pod.yml
root@master-250410:~/mani/250417/probe# kubectl apply -f rf-pod.yml
pod/rf-nginx-pod created
7. 결과 확인

실습 - 01
문제
61.254.18.30:5000/nginx 이미지로 httpGet 으로 /test경로에 80요청이 성공하도록 만들어보세요!
➡️ configMap으로 index파일을 만들어서 컨테이너에 /usr/share/nginx/html/test 경로에 넣어줄 예정
풀이
1. Manifest file 정의
root@master-250410:~/mani/250417/probe# vi test.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-index
data:
index.html: |
readiness success
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: nginx
image: 61.254.18.30:5000/nginx
volumeMounts:
- name: vol-index
mountPath: /usr/share/nginx/test
readinessProbe:
httpGet:
path: /test
port: 80
initialDelaySeconds: 3
periodSeconds: 5
volumes:
- name: vol-index
configMap:
name: cm-index
2. 컨테이너 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f test.yml
configmap/cm-index unchanged
pod/test-pod configured
3. 결과 확인


실습 - 02
문제
실패하는 livenessProbe를 구성해보세요.
이후에 kubectl get pod --watch 같은 옵션을 통해 어떤 현상이 발생하는지 한 번 확인해보세요.
풀이
1. 컨테이너 정의
root@master-250410:~/mani/250417/probe# vi lf-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: lf-nginx-pod
labels:
app: lf-nginx
spec:
containers:
- name: nginx
image: 61.254.18.30:5000/nginx
livenessProbe:
httpGet:
path: /fail #curl localhost:80/fail
port: 80
periodSeconds: 5
initialDelaySeconds: 5
2. 컨테이너 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f lf-pod.yml
pod/lf-nginx-pod created
3. 결과 확인
- 무한 재부팅 ➡️ livenessProbe가 실패했기 때문에, 계속 재부팅


4. yml파일 수정 ➡️ 정상
root@master-250410:~/mani/250417/probe# vi lf-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: lf-nginx-pod
labels:
app: lf-nginx
spec:
containers:
- name: nginx
image: 61.254.18.30:5000/nginx
livenessProbe:
httpGet:
path: / #curl localhost:80/
port: 80
periodSeconds: 5
initialDelaySeconds: 5
5. manifest file 반영
root@master-250410:~/mani/250417/probe# kubectl apply -f lf-pod.yml
pod/lf-nginx-pod created
6. 결과 확인
- 컨테이너 재시작을 안할것

tcpSocket을 통한 Probe
- MySQL 같은 앱은 httpGet같은 요청으로는 응답을 주지 않음
➡️ 따라서, MySQL의 기본 포트인 3306으로 tcpSocket이 유효한지를 검증하여 probe하는 방식
1.컨테이너 정의
root@master-250410:~/mani/250417/probe# vi redis.yml
apiVersion: v1
kind: Pod
metadata:
name: redis
labels:
app: redis
spec:
containers:
- name: redis
image: 61.254.18.30:5000/redis
readinessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 3
2. 컨테이너 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f redis.yml
pod/redis created
3. 컨테이너 생성 확인

💡컨테이너 정상 작동 확인 명령어
- $? : 직전에 실행한 명령이 어떻게 종료되었는지 종료코드를 조회
- 정상종료 = 0 반환, 비정상종료 = 1 또는 2 반환
- 0을 반환 ➡️ readinessProbe 성공
- 1, 2 반환 ➡️ readinessProbe 실패
Command를 통한 probe
1. 임시 컨테이너 생성
root@master-250410:~/mani/250417/probe# vi cmd-mysql.yml
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- name: mysql
image: 61.254.18.30:5000/mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
2. 컨테이너 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f cmd-mysql.yml
pod/mysql created
3. 컨테이너 정상 작동 확인

4. 컨테이너 진입 & 정상 작동 명령어 확인
- 어떤 명령이 수행됐을 때, 0을 반환하는지 모르기 때문에, 컨테이너 안으로 들어가서 확인

5. 컨테이너 삭제
root@master-250410:~/mani/250417/probe# kubectl delete -f cmd-mysql.yml
6. 컨테이너 수정
root@master-250410:~/mani/250417/probe# vi cmd-mysql.yml
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- name: mysql
image: 61.254.18.30:5000/mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
readinessProbe:
exec:
command: ["mysqladmin","ping","-ppassword"]
initialDeplaySeconds: 10
periodSeconds: 3
6. 컨테이너 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f cmd-mysql.yml
pod/mysql created
7. 컨테이너 정상 작동 확인

실습 - 03
문제
이 readinessProbe가 성공하는 pod 매니페스트 파일을 작성해보세요.
풀이
💡 방법
1️⃣ pv-pvc로 호스트에 존재하는 파일 넣어주기 - 별로
2️⃣ configMap - 세련됨 ✅
3️⃣ ⚠️command - 금지
- command 명령 = Dockerfile CMD, CMD가 무시된
- 컨테이너 정상 작동 ❌
4️⃣ Dockerfile을 통한 이미지빌드 - 귀찮
1. 컨테이너 정의
root@master-250410:~/mani/250417/probe# vi cmd-txt.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: 61.254.18.30:5000/nginx
2. 컨테이너 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f cmd-txt.yml
pod/nginx created
3. 컨테이너 내부 진입 & 정상 작동 확인

4. 컨테이너 삭제
root@master-250410:~/mani/250417/probe# kubectl delete -f cmd-txt.yml
configmap "cm-test" deleted
pod "nginx" deleted
5. 컨테이너 정의 - 수정
- ConfigMap과 VolumeMount를 사용해서 경로 & 파일 생성
root@master-250410:~/mani/250417/probe# vi cmd-txt.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-test
data:
test.txt: |
test
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: 61.254.18.30:5000/nginx
volumeMounts:
- name: config-volume
mountPath: /test
readinessProbe:
exec:
command: ["cat","/test/test.txt"]
initialDelaySeconds: 10
periodSeconds: 3
volumes:
- name: config-volume
configMap:
name: cm-test
6. 컨테이너 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f cmd-txt.yml
configmap/cm-test created
pod/nginx created
7. 결과 확인 - 정상 작동

Kubernetes Resource
StatefulSet
- 우리가 deployment를 통해 pod를 여러 개 띄우면 pod의 이름이 우리가 예상할 수 없는 형태의 랜덤한 이름이 부여
➡️ 딱히 내가 앱을 배포할 때, pod의 이름이 크게 중요하지 않고 빠르게 배포하고 싶다면 아래와 같이 생성
👉 하지만, 때에 따라서는 pod의 이름을 신경써야하는 경우도 존재 - 예시) mysql을 구성하는데, 하나는 master로 구성하고 다른 하나는 slave로 구성하는 경우, 첫 번째 리소스가 항상 mysql-0으로 생성되고, 두번째 리소스는 항상 mysql-1로구성된다면, mysql-0 = master / mysql-1 = slave로 구성하면 됨
👉 이렇게 일정한 이름을 갖도록 구성되는 리소스 ➡️ StatefulSet
StatefulSet 실습
1. 리소스 정의
root@master-250410:~/mani/250417/probe# cat sts.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sts-mysql
spec:
serviceName: "mysql" #반드시 svc를 이 이름으로 만들어줘야한다
replicas: 3
selector:
matchLabels:
app: sts-mysql
template:
metadata:
labels:
app: sts-mysql
spec:
containers:
- name: sts-mysql
image: 61.254.18.30:5000/mysql
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
2. 리소스 배포
root@master-250410:~/mani/250417/probe# kubectl apply -f sts.yml
statefulset.apps/sts-mysql created
3. 결과 확인 - Pod의 이름이 일정함을 확인 가능

DaemonSet
- Docker-swarm에서 deploy.mode.global: 옵션과 비슷
- 각 노드마다 무조건 한개씩만 파드를 띄우고 싶을 때
- 모니터링 시스템처럼 모든 노드에 자원을 수입할 exporter들을 배치하고 싶은 경우 사용
- 예시
- kube-system의 kube-proxy, metallb-system의 speaker 같은 리소스에 해당
DaemonSet 실습
1. 리소스 정의
root@master-250410:~/mani/250417/probe# vi kube-ds.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-nginx
spec:
selector:
matchLabels:
app: ds-nginx
template:
metadata:
labels:
app: ds-nginx
spec:
containers:
- name: ds-nginx
image: 61.254.18.30:5000/nginx
2. 리소스 생성
root@master-250410:~/mani/250417/probe# kubectl apply -f kube-ds.yml
daemonset.apps/ds-nginx created
3. 결과 확인

'CS > Kubernetes' 카테고리의 다른 글
[Kubernetes] 11. Node Selector, Node Affinity, Taints & Tolerations (0) | 2025.04.22 |
---|---|
[Kubernetes] 10. HPA(Horizontal Pod AutoScaler) & Control Plane 3중화(HAProxy) (1) | 2025.04.19 |
[Kubernetes] 07. 자율과제 - Dynamic Provisioner (0) | 2025.04.17 |
[Kubernetes] 06. RBAC, Dynamic Provisioner (0) | 2025.04.16 |
[Kubernetes] 04. Resource - PV(Persistent Volume), StorageClass, ConfigMap, Secret (0) | 2025.04.15 |