Kubernetes/Kubernetes Advanced

📌 [StatefulSet 심화편 #9] StatefulSet과 PreStop Hook을 활용한 안전한 Pod 종료 전략

ygtoken 2025. 3. 14. 10:14
728x90

 

1️⃣ 개요

 

StatefulSet의 Pod를 삭제하거나 재시작할 때 데이터 정합성을 유지하는 것이 매우 중요합니다.

특히 데이터베이스, 메시지 브로커, 캐시 시스템과 같은 Stateful 애플리케이션은 Pod가 종료되기 전에 데이터가 정상적으로 저장(Flush)되어야 합니다.

이를 위해 PreStop Hook을 활용하면 Pod가 종료되기 전에 특정 작업을 수행할 수 있습니다.

 

이번 글에서는 PreStop Hook의 개념과 StatefulSet에서 안전한 Pod 종료 방법을 설명하겠습니다. 🚀

 


2️⃣ PreStop Hook이란?

 

✅ 1. PreStop Hook의 개념

PreStop Hook은 Pod가 종료되기 전에 실행되는 명령 또는 스크립트

Stateful 애플리케이션에서는 데이터 Flush, 세션 종료, 리더 선출 변경 등의 작업을 수행하는 데 사용

PreStop Hook을 활용하면 StatefulSet Pod가 안전하게 종료될 수 있도록 보장 가능

 

📌 PreStop Hook이 실행되는 과정

1️⃣ Pod에 종료 신호(SIGTERM)가 전달됨

2️⃣ PreStop Hook이 실행되면서 애플리케이션이 정상 종료될 준비를 함

3️⃣ PreStop Hook이 완료되면, Kubernetes가 컨테이너를 종료

 

PreStop Hook을 사용하면 Pod가 강제 종료되지 않고, 안전하게 데이터 저장 작업을 수행할 수 있습니다.

 


3️⃣ StatefulSet에서 PreStop Hook을 활용한 안전한 Pod 종료 방법

 

StatefulSet에서 PreStop Hook을 설정하면, Pod가 종료될 때 데이터가 손실되지 않도록 보호할 수 있습니다.

아래는 MySQL, PostgreSQL, Redis, Kafka 등 주요 애플리케이션에서 PreStop Hook을 활용하는 방법입니다.

 


✅ 1. MySQL에서 안전한 Pod 종료

 

MySQL Pod가 종료될 때 모든 트랜잭션을 완료하고 안전하게 종료되도록 PreStop Hook을 설정할 수 있습니다.

 

📌 MySQL StatefulSet PreStop Hook 설정 예제

lifecycle:
  preStop:
    exec:
      command: [ "mysqladmin", "shutdown" ]

 

📌 MySQL에서 안전하게 종료되었는지 확인

kubectl logs mysql-1 | grep "mysqld: Shutdown complete"

PreStop Hook을 설정하면 MySQL이 안전하게 종료되고, 데이터 정합성이 보장됩니다.

 


✅ 2. PostgreSQL에서 PreStop Hook 활용

 

PostgreSQL은 PreStop Hook을 사용하여 클라이언트 연결을 차단하고, 안전한 종료를 수행할 수 있습니다.

 

📌 PostgreSQL StatefulSet PreStop Hook 설정 예제

lifecycle:
  preStop:
    exec:
      command: [ "pg_ctl", "stop", "-D", "/var/lib/postgresql/data", "-m", "fast" ]

 

📌 PostgreSQL 종료 상태 확인

kubectl logs postgres-1 | grep "shutting down"

PostgreSQL의 경우, fast 모드를 사용하면 안전하게 세션을 종료하면서도 빠른 Pod 종료가 가능합니다.

 


✅ 3. Redis에서 PreStop Hook 활용

 

Redis는 클러스터 환경에서 노드가 종료될 때 데이터를 디스크에 저장해야 합니다.

 

📌 Redis StatefulSet PreStop Hook 설정 예제

lifecycle:
  preStop:
    exec:
      command: [ "redis-cli", "save" ]

 

📌 Redis의 데이터 저장(Flush) 상태 확인

kubectl logs redis-1 | grep "Background saving terminated with success"

PreStop Hook을 설정하면 Redis가 데이터를 안전하게 저장하고 종료됩니다.

 


✅ 4. Kafka에서 PreStop Hook 활용

 

Kafka는 브로커가 종료될 때, 리더 파티션을 다른 노드로 이동시키고 안전하게 종료해야 합니다.

 

📌 Kafka StatefulSet PreStop Hook 설정 예제

lifecycle:
  preStop:
    exec:
      command: [ "kafka-server-stop.sh" ]

 

📌 Kafka 브로커의 종료 로그 확인

kubectl logs kafka-1 | grep "shutting down"

Kafka의 경우, 리더가 변경되지 않은 상태에서 브로커가 갑자기 종료되면 클러스터 장애가 발생할 수 있습니다.

 


4️⃣ PreStop Hook 적용 후 Pod 종료 테스트

 

📌 StatefulSet Pod 삭제 후 종료 프로세스 확인

kubectl delete pod mysql-1
kubectl logs mysql-1 -f

 

📌 정상적으로 PreStop Hook이 실행되었는지 확인

kubectl get events | grep mysql-1

PreStop Hook을 적용하면 Pod가 종료될 때 실행되는 명령이 정상적으로 수행되는지 확인할 수 있습니다.

 


5️⃣ PreStop Hook 설정 시 고려해야 할 점

 

✅ 1. PreStop Hook 실행 시간이 너무 길면 종료가 지연될 수 있음

 

PreStop Hook이 너무 오래 실행되면 Pod가 강제 종료될 가능성이 높아지므로, 실행 시간을 제한해야 합니다.

 

📌 PreStop Hook 실행 시간을 제한하려면 terminationGracePeriodSeconds 설정

spec:
  terminationGracePeriodSeconds: 30  # 30초 동안 PreStop Hook 실행 후 종료

기본값은 30초이며, 이 시간을 초과하면 Kubernetes가 컨테이너를 강제 종료할 수 있습니다.

 


✅ 2. PreStop Hook에서 중요한 작업이 실패하면 Pod가 비정상 종료될 수 있음

PreStop Hook에서 실행하는 명령어가 실패하면 애플리케이션이 올바르게 종료되지 않을 수 있습니다.

이를 방지하려면 PreStop Hook 실행 결과를 로그로 저장하고, 실행 실패 시 대체 프로세스를 실행하도록 설정해야 합니다.

 

📌 PreStop Hook 실행 결과를 로그 파일로 저장하는 예제

lifecycle:
  preStop:
    exec:
      command: [ "sh", "-c", "mysqladmin shutdown || echo 'Shutdown failed' > /var/log/shutdown.log" ]

이렇게 하면 MySQL이 정상적으로 종료되지 않더라도, Pod 종료 시 로그를 남길 수 있습니다.

 


✅ 3. PreStop Hook을 활용한 StatefulSet 무중단 배포 전략

PreStop Hook을 활용하면 RollingUpdate 시에도 데이터 정합성을 유지하면서 무중단 배포를 수행할 수 있습니다.

maxUnavailable=1 설정을 사용하여 한 번에 하나의 Pod만 업데이트되도록 구성하는 것이 좋습니다.

 

📌 StatefulSet 무중단 배포 설정 예제

strategy:
  type: RollingUpdate
  rollingUpdate:
    partition: 1  # 한 번에 1개의 Pod만 업데이트

PreStop Hook을 활용하면 무중단 배포 시 데이터 정합성을 유지할 수 있습니다.

 


🔥 6️⃣ 결론

 

PreStop Hook을 사용하면 StatefulSet Pod가 안전하게 종료될 수 있음

데이터베이스(MySQL, PostgreSQL), 메시지 브로커(Kafka), 캐시 시스템(Redis) 등에서 활용 가능

PreStop Hook 실행 시간이 너무 길면 종료가 지연될 수 있으므로 terminationGracePeriodSeconds를 적절히 설정해야 함

PreStop Hook을 활용하면 StatefulSet 무중단 배포 시에도 데이터 정합성을 유지할 수 있음

PreStop Hook 실행 실패 시 로그를 남기고, 적절한 대체 프로세스를 고려해야 함

728x90