Kubernetes/Kubernetes Best Practices

[Scenario Playbook - 심화편 | Medium Level #11] StatefulSet을 활용한 고가용성 서비스 구축 및 운영

ygtoken 2025. 3. 16. 18:58
728x90

 

쿠버네티스에서 일반적인 Deployment는 가변적인 Pod 이름을 사용하며, 특정 Pod 간의 고정적인 네트워크 식별자가 필요한 서비스에는 적합하지 않습니다.

반면, StatefulSet을 활용하면 특정 Pod에 고유한 ID와 네트워크 주소를 유지할 수 있어, 데이터베이스 및 상태 기반 애플리케이션을 안정적으로 운영할 수 있습니다.

이 글에서는 StatefulSet을 활용한 고가용성 서비스 구축 및 운영 전략을 다룹니다.

 


📌 글에서 다루는 상황들

 

1. StatefulSet을 사용하여 고정된 네트워크 식별자를 가진 Pod 배포

2. Pod 재시작 및 롤링 업데이트 시 데이터 및 네트워크 ID 유지

3. kubectl을 활용한 StatefulSet 운영 및 문제 해결 방법

 

각 문제를 실무에서 바로 활용할 수 있도록 Manifest 템플릿과 예상 결과 값을 제공합니다.

 


1️⃣ StatefulSet을 사용하여 고정된 네트워크 식별자를 가진 Pod 배포

 

❓ 문제 상황

 

운영팀에서 클러스터 내에서 실행되는 데이터베이스(Persistent 서비스)의 각 인스턴스가 고유한 네트워크 주소를 유지해야 합니다.

이를 위해 StatefulSet을 사용하여 MySQL을 배포하고, 고유한 호스트네임을 유지하도록 설정해야 합니다.

StatefulSet 이름: mysql

Pod 네트워크 주소: mysql-0.mysql.default.svc.cluster.local

PVC(Persistent Volume Claim) 사용하여 데이터 유지

 

✅ 어떻게 해결할 수 있을까요?

 


🛠️ 해결 방법

 

1. StatefulSet을 생성하여 각 Pod에 고정된 네트워크 ID를 부여합니다.

 

2. Headless Service를 설정하여 각 Pod이 개별적으로 DNS를 통해 접근 가능하도록 합니다.

 


✅ 정답 Manifest (StatefulSet 및 Headless Service 설정)

 

🔹 Headless Service (고정 네트워크 ID 유지)

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  clusterIP: None  # Headless Service 설정
  selector:
    app: mysql
  ports:
  - name: mysql
    port: 3306
    targetPort: 3306

 

🔹 StatefulSet 설정

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql"
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "rootpassword"
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

이제 mysql-0, mysql-1, mysql-2 노드가 각각 고유한 네트워크 주소를 가지며 데이터베이스를 운영 가능

 


📌 적용 후 예상 결과 값

 

1. StatefulSet 배포 후 Pod 상태 확인

kubectl get pods -l app=mysql

 

💡 예상 출력 값

NAME      READY   STATUS    RESTARTS   AGE
mysql-0   1/1     Running   0          5m
mysql-1   1/1     Running   0          5m
mysql-2   1/1     Running   0          5m

 

2. 고유한 네트워크 주소 확인

kubectl exec -it mysql-0 -- hostname

 

💡 예상 출력 값

mysql-0

각 Pod이 고유한 네트워크 ID를 유지함

 


2️⃣ Pod 재시작 및 롤링 업데이트 시 데이터 및 네트워크 ID 유지

 

❓ 문제 상황

 

운영팀에서 MySQL 인스턴스를 업데이트해야 하지만, 기존 데이터가 유지되도록 해야 합니다.

Deployment와 달리, StatefulSet은 기존 네트워크 ID 및 Persistent Volume을 유지하면서 롤링 업데이트를 수행해야 합니다.

MySQL 이미지 버전: mysql:5.7 → mysql:8.0

기존 데이터 유지 필수

 

✅ 어떻게 해결할 수 있을까요?

 


🛠️ 해결 방법

 

1. StatefulSet의 업데이트 전략을 RollingUpdate로 설정하여 하나씩 업데이트되도록 합니다.

 

2. Pod이 재시작되어도 같은 Persistent Volume을 유지하도록 설정합니다.

 


✅ StatefulSet 업데이트 적용 (RollingUpdate)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  updateStrategy:
    type: RollingUpdate  # 한 개씩 순차적으로 업데이트
  template:
    spec:
      containers:
      - name: mysql
        image: mysql:8.0  # 새로운 버전으로 업데이트

Pod이 하나씩 순차적으로 업데이트되면서 기존 데이터를 유지함

 


📌 적용 후 예상 결과 값

 

1. 업데이트 진행 상태 확인

kubectl rollout status statefulset mysql

 

💡 예상 출력 값

statefulset rolling update complete

 

2. 데이터 유지 여부 확인

kubectl exec -it mysql-0 -- mysql -uroot -prootpassword -e "SHOW DATABASES;"

 

💡 예상 출력 값

Database
information_schema
mysql
performance_schema
sys

업데이트 후에도 기존 데이터가 유지됨

 


3️⃣ kubectl을 활용한 StatefulSet 운영 및 문제 해결 방법

 

❓ 문제 상황

 

운영팀에서 StatefulSet이 정상적으로 동작하고 있는지 모니터링하고, 문제가 발생했을 때 원인을 분석해야 합니다.

kubectl 명령어를 활용하여 현재 배포 상태 및 볼륨 상태를 점검해야 합니다.

 

✅ 어떻게 해결할 수 있을까요?

 


🛠️ 해결 방법

 

1. kubectl get statefulset 명령어를 사용하여 현재 StatefulSet 상태를 확인합니다.

 

2. kubectl describe 명령어를 활용하여 StatefulSet 및 PersistentVolumeClaim(PVC) 상태를 분석합니다.

 


✅ StatefulSet 상태 확인 명령어

 

🔹 현재 StatefulSet 상태 확인

kubectl get statefulset

 

💡 예상 출력 값

NAME    READY   AGE
mysql   3/3     10m

 

🔹 PersistentVolumeClaim 상태 확인

kubectl get pvc

 

💡 예상 출력 값

NAME           STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql-data-mysql-0   Bound    pv-001   10Gi       RWO            standard       10m
mysql-data-mysql-1   Bound    pv-002   10Gi       RWO            standard       10m
mysql-data-mysql-2   Bound    pv-003   10Gi       RWO            standard       10m

StatefulSet과 연결된 PersistentVolume이 정상적으로 유지됨

728x90