Kubernetes/Kubernetes Best Practices

[Scenario Playbook Ep.22] 🚀 StatefulSet 편 #1 | 기본적인 StatefulSet 설정 및 Headless Service

ygtoken 2025. 3. 16. 14:53
728x90

 

쿠버네티스에서 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>
728x90