Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

안정적인 운영을 위한 Graceful Termination 활용하기 본문

☁️ 클라우드/Kubernetes

안정적인 운영을 위한 Graceful Termination 활용하기

Chamming2 2022. 5. 17. 10:34

쿠버네티스에서는 노드가 드레인되거나 노드의 가용 자원이 부족한 등의 이유로 파드가 종료되는 일이 비일비재한데요, 이 때 마치 두꺼비집을 내리는 것처럼 한순간에 모든 프로세스를 종료한다면 중요한 데이터나 네트워크 연결이 그대로 유실될 위험이 존재합니다.

 

이번 글에서는 사용자에게 미칠 영향과 복구 소요를 최소화하기 위한 컨테이너의 정상 종료(Graceful Termination) 방법을 소개합니다.

TL;DR

  • 파드 종료 시 kubelet에서 SIGTERM 신호를 송출하고, 컨테이너는 SIGKILL를 수신할 때까지 정상 종료를 위해 대기한다.
    (컨테이너 종료 시작 - SIGTERM 수신 - 정상 종료 동작 - SIGKILL 수신 - 컨테이너 강제 종료)
  • 컨테이너에서 SIGTERM 신호를 수신하지 못하는 경우를 대비해, preStop 훅에 정상 종료 동작을 구현해야 한다.
  • 파드의 terminationGracePeriodSeconds 속성을 통해 정상 종료 동작이 수행되는 기간(Grace Period)을 설정할 수 있다.
  • 만약 Grace Period 안에 정상 종료를 마치지 못하면 컨테이너는 곧바로 종료된다.

쿠버네티스의 종료 생명주기

컨테이너의 안전한 종료를 위해 쿠버네티스는 단숨에 파드를 종료하는 대신 일련의 과정을 수행합니다.

  • 파드의 상태가 Terminating 으로 변경되며 해당 파드로의 트래픽이 차단됩니다.
  • 파드 내 모든 컨테이너에 SIGTERM 신호가 전달되며 정상 종료 시간(Grace Period) 카운트다운이 시작됩니다.
  • 만약 정상 종료 시간 내에 어플리케이션을 종료하지 못했다면 SIGKILL 신호가 전달되며 곧바로 컨테이너가 종료됩니다.

이 과정을 조금 더 자세히 들여다볼까요?

 

원래 SIGTERM 신호를 수신하면 프로그램이 정상 종료를 수행하도록 구현되어야 하지만, 개발자가 깜빡하고 정상 종료 동작을 구현해두지 않거나 모종의 이유로 SIGTERM 신호를 받지 못하면 정상 종료 대신 곧바로 프로그램이 종료될 수도 있습니다. 

 

이처럼 컨테이너가 SIGTERM 신호에 반응하지 못하는 상황을 대비해 쿠버네티스의 preStop 훅을 사용할 수 있습니다.

preStop 훅

preStop 훅은 컨테이너의 종료 생명주기의 시작과 동시에 실행되는 동작으로, SIGTERM 신호가 전달되기 전에 수행됩니다.

이 점을 이용해 컨테이너가 SIGTERM 신호에 반응하지 못하더라도 preStop 훅에서 정상 종료 동작을 실행하도록 하면 됩니다.

  • preStop 훅을 사용해 nginx의 정상 종료를 시도하는 예시
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  template:
  # ...
    spec:
      containers:
      - name: nginx
        image: nginx
        # lifecycle 레벨에서 훅을 정의합니다.
        lifecycle:
          # 컨테이너가 종료 상태로 들어감과 동시에 preStop 훅이 호출됩니다. 
          preStop:
            exec:
              # 컨테이너 종료 시, nginx의 정상 종료를 시도합니다.
              command: ["/usr/sbin/nginx","-s","quit"]

terminationGracePeriodSeconds

preStop 훅에 정의된 동작은 컨테이너가 종료됨과 동시에 파드의 terminationGracePeriodSeconds 속성에 정의된 정상 종료 시간(Grace Period) 동안 실행됩니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  template:
  # ...
    spec:
      containers:
      - name: nginx
        image: nginx
        lifecycle:
          preStop:
            exec:
              command: ["/usr/sbin/nginx","-s","quit"]
              
      # SIGKILL 신호를 받기까지 60초의 유예시간이 주어집니다.
      # 기본값은 30초입니다.
      terminationGracePeriodSeconds: 60

만약 정의된 정상 종료 시간을 초과하면 정상 종료 여부와는 상관없이 SIGKILL 신호가 전달되어 컨테이너는 그 즉시 제거됩니다.

따라서 여유있는 정상 종료 시간을 확보하기 위해, terminationGracePeriodSeconds 에 적절한 시간을 설정해야 합니다. 🙂

참고

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆