쿠버네티스에서 StatefulSet은 Pod 간 고유한 식별자를 유지해야 하는 애플리케이션을 배포하는 데 사용됩니다.
이번 글에서는 StatefulSet을 활용하여 기본적인 배포를 설정하는 방법과 Headless Service를 이용하여 개별 Pod의 고유 호스트네임을 유지하는 방법을 다룹니다.
📌 글에서 다루는 상황들
1️⃣ 기본적인 StatefulSet 배포
2️⃣ Headless Service를 이용한 고유 호스트네임 유지
각 문제를 실무에서 바로 활용할 수 있도록 Manifest 템플릿과 예상 결과 값을 제공합니다.
1️⃣ 기본적인 StatefulSet 배포
❓ 문제 상황
운영팀에서 각 Pod에 고유한 네트워크 ID를 유지하면서도 순차적으로 배포되는 애플리케이션을 구성해야 하는 요구사항이 생겼습니다.
Pod들은 순차적으로 생성되어야 하며, 삭제 후 재배포되더라도 같은 네트워크 식별자를 유지해야 합니다.
• StatefulSet의 이름은 web-statefulset이어야 합니다.
• Pod은 web-0, web-1, web-2 형식으로 생성되어야 합니다.
• 각 Pod은 같은 nginx 이미지를 실행해야 합니다.
✅ 어떻게 해결할 수 있을까요?
🛠️ 해결 방법
1. StatefulSet을 생성하여 각 Pod이 고유한 네트워크 ID(Stable Network Identity)를 유지하도록 설정해야 합니다.
• serviceName: web을 사용하여 고유 호스트네임을 유지
• Pod 이름이 web-0, web-1 형식으로 생성됨
2. 각 Pod이 순차적으로 생성되도록 설정해야 합니다.
• replicas: 3을 설정하여 3개의 Pod 실행
✅ 정답 Manifest (기본 StatefulSet 배포)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-statefulset # StatefulSet 이름
spec:
serviceName: "web" # Headless Service와 연결될 이름
replicas: 3 # 실행할 Pod 개수
selector:
matchLabels:
app: web # 레이블을 기반으로 Pod을 선택
template:
metadata:
labels:
app: web # Pod 레이블
spec:
containers:
- name: nginx
image: nginx:latest # Nginx 컨테이너 실행
ports:
- containerPort: 80
📌 적용 후 예상 결과 값
1. StatefulSet 생성 확인
kubectl get statefulset
💡 예상 출력 값
NAME READY AGE
web-statefulset 3/3 5s
2. StatefulSet에 의해 생성된 Pod 확인
kubectl get pods -l app=web
💡 예상 출력 값
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 5s
web-1 1/1 Running 0 5s
web-2 1/1 Running 0 5s
2️⃣ Headless Service를 이용한 고유 호스트네임 유지
❓ 문제 상황
운영팀에서 StatefulSet의 각 Pod이 고유한 DNS 이름을 유지하도록 설정해야 하는 요구사항이 생겼습니다.
이를 위해 Headless Service를 사용하여 개별 Pod의 네트워크 이름을 보장해야 합니다.
• 서비스의 이름은 web이어야 합니다.
• web-0.web, web-1.web, web-2.web 형식으로 DNS가 생성되어야 합니다.
• 클라이언트가 특정 Pod에 직접 접근할 수 있어야 합니다.
✅ 어떻게 해결할 수 있을까요?
🛠️ 해결 방법
1. Headless Service를 생성하여 StatefulSet의 Pod이 개별적인 DNS 레코드를 가지도록 설정해야 합니다.
• clusterIP: None을 설정하여 Headless Service로 지정
• 각 Pod은 web-0.web, web-1.web 형식의 DNS 이름을 가짐
2. StatefulSet과 연결될 수 있도록 selector를 설정해야 합니다.
✅ 정답 Manifest (Headless Service 설정)
apiVersion: v1
kind: Service
metadata:
name: web # StatefulSet과 연결될 서비스 이름
spec:
clusterIP: None # Headless Service 설정
selector:
app: web # StatefulSet과 연결
ports:
- protocol: TCP
port: 80
targetPort: 80
📌 적용 후 예상 결과 값
1. Headless Service 생성 확인
kubectl get svc web
💡 예상 출력 값
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web ClusterIP None <none> 80/TCP 5s
2. 각 Pod의 DNS 확인
kubectl exec -it web-0 -- nslookup web
💡 예상 출력 값
Name: web
Address 1: 10.244.1.10 web-0.web.default.svc.cluster.local
Address 2: 10.244.1.11 web-1.web.default.svc.cluster.local
Address 3: 10.244.1.12 web-2.web.default.svc.cluster.local
3. 특정 Pod에 직접 접근 테스트
curl http://web-0.web.default.svc.cluster.local
💡 예상 출력 값
<!DOCTYPE html>
<html>
<head><title>Welcome to nginx!</title></head>
<body>
<h1>Welcome to nginx!</h1>
</body>
</html>