쿠버네티스에서 StatefulSet은 애플리케이션이 안정적으로 실행되도록 도와주는 기능을 제공합니다.
이번 글에서는 Readiness Probe를 활용하여 안정적인 시작을 보장하는 방법과 Leader Election을 적용하여 고가용성(HA) 시스템을 구축하는 방법을 다룹니다.
📌 글에서 다루는 상황들
1️⃣ Readiness Probe를 활용한 안정적인 시작 보장
2️⃣ Leader Election을 적용하여 고가용성 시스템 구축
각 문제를 실무에서 바로 활용할 수 있도록 Manifest 템플릿과 예상 결과 값을 제공합니다.
1️⃣ Readiness Probe를 활용한 안정적인 시작 보장
❓ 문제 상황
운영팀에서 StatefulSet의 Pod이 애플리케이션이 완전히 준비된 후에만 트래픽을 받을 수 있도록 설정해야 하는 요구사항이 생겼습니다.
애플리케이션이 시작된 후에도 일정 시간이 지나야 정상적으로 요청을 처리할 수 있기 때문에 Readiness Probe를 설정해야 합니다.
• StatefulSet의 이름은 app-with-readiness이어야 합니다.
• readinessProbe를 사용하여 Pod이 준비될 때까지 트래픽을 차단해야 합니다.
• sleep 10을 실행하여 Pod이 준비되기까지 10초의 지연시간을 추가해야 합니다.
✅ 어떻게 해결할 수 있을까요?
🛠️ 해결 방법
1. StatefulSet의 컨테이너에 readinessProbe를 추가하여 애플리케이션이 준비된 후에만 서비스가 가능하도록 설정해야 합니다.
• exec을 사용하여 특정 조건이 충족될 때까지 트래픽을 차단
2. Pod이 시작된 후 일정 시간(10초) 동안 트래픽을 차단한 뒤 정상적으로 실행되는지 확인해야 합니다.
✅ 정답 Manifest (Readiness Probe가 적용된 StatefulSet 설정)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: app-with-readiness # StatefulSet 이름
spec:
serviceName: "app-readiness" # Headless Service와 연결될 이름
replicas: 3 # 실행할 Pod 개수
selector:
matchLabels:
app: app-readiness # 레이블을 기반으로 Pod을 선택
template:
metadata:
labels:
app: app-readiness # Pod 레이블
spec:
containers:
- name: readiness-test
image: busybox # 테스트용 컨테이너
command: ["sh", "-c", "sleep 10; echo Ready"]
readinessProbe:
exec:
command: ["sh", "-c", "test -f /tmp/ready"]
initialDelaySeconds: 5
periodSeconds: 3
📌 적용 후 예상 결과 값
1. StatefulSet 생성 확인
kubectl get statefulset
💡 예상 출력 값
NAME READY AGE
app-with-readiness 0/3 5s # Pod이 아직 준비되지 않음
2. Readiness Probe가 적용되어 Pod이 준비될 때까지 지연되는지 확인
kubectl describe pod app-with-readiness-0
💡 예상 출력 값
Readiness probe failed: No such file or directory: /tmp/ready
3. Pod이 완전히 준비된 후 트래픽을 받을 수 있는지 확인
kubectl get statefulset
💡 예상 출력 값
NAME READY AGE
app-with-readiness 3/3 30s # 모든 Pod이 준비됨
2️⃣ Leader Election을 적용하여 고가용성 시스템 구축
❓ 문제 상황
운영팀에서 StatefulSet을 사용하여 리더 선출(Leader Election)이 필요한 분산 애플리케이션을 구축해야 하는 요구사항이 생겼습니다.
애플리케이션이 여러 개의 인스턴스로 실행되지만, 그중 하나만 리더(Leader)로 작동하고 나머지는 팔로워(Follower)로 유지되어야 합니다.
• StatefulSet의 이름은 leader-election-app이어야 합니다.
• leader-elector 컨테이너를 실행하여 Pod 중 하나가 리더로 선출되도록 설정해야 합니다.
• 리더 Pod의 이름은 leader-election-app-0으로 유지되어야 합니다.
✅ 어떻게 해결할 수 있을까요?
🛠️ 해결 방법
1. StatefulSet의 첫 번째 Pod(pod-0)만 리더 역할을 수행하도록 설정해야 합니다.
• 환경 변수를 활용하여 pod-0만 리더로 설정
• 다른 Pod들은 자동으로 팔로워(Follower) 역할을 수행
2. 애플리케이션이 리더 선출 결과를 출력하도록 설정하여 로그를 통해 확인할 수 있도록 해야 합니다.
✅ 정답 Manifest (Leader Election이 적용된 StatefulSet 설정)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: leader-election-app # StatefulSet 이름
spec:
serviceName: "leader-election" # Headless Service와 연결될 이름
replicas: 3 # 실행할 Pod 개수
selector:
matchLabels:
app: leader-election # 레이블을 기반으로 Pod을 선택
template:
metadata:
labels:
app: leader-election # Pod 레이블
spec:
containers:
- name: leader-elector
image: busybox # 테스트용 컨테이너
command: ["sh", "-c", "if [ \"$HOSTNAME\" = \"leader-election-app-0\" ]; then echo 'I am the leader'; else echo 'I am a follower'; fi; sleep 3600"]
📌 적용 후 예상 결과 값
1. StatefulSet 생성 확인
kubectl get statefulset
💡 예상 출력 값
NAME READY AGE
leader-election-app 3/3 5s
2. 리더 선출 결과 확인 (leader-election-app-0이 리더인지 확인)
kubectl logs leader-election-app-0
💡 예상 출력 값
I am the leader
3. 팔로워 Pod이 정상적으로 실행 중인지 확인
kubectl logs leader-election-app-1
💡 예상 출력 값
I am a follower