본문 바로가기
카테고리 없음

어느날 나의 배치가 멈췄습니다. - K8S Command line Health Check 방식 적용기

by YangsDev 2025. 6. 9.

 

들어가며

OS EOS된 장비를 최근에 이전 했습니다. 

이전 후 문제가 없었으나, 사실 그건 폭풍전야 였습니다. 

이전이 끝나고 약 일주일 뒤, 관제센터에서 연락이 옵니다. 

 

"XXX 데이터가 적용되지 않았습니다. 확인 부탁드립니다."

뭔가 처리 중에 꼬였나 싶어서, Sentry나 에러 로그를 봐도 특이사항이 없었습니다.

 

 

그리고 전체 로그를 보는데, "처음에는 03:00"에 멈춰있었고 그때 당시 시간이 "09시" 쯤 이었다보니, "UTC로 바뀌면서 문제가 생겼나?" 하고 살펴 보는데  시간대는 죄가 없었습니다 10분 마다 시작 하는 배치 였거든요.

 

 

등에 땀이 주루룩 흐르면서 아차 싶었습니다. 바로 배치가 작업중에 멈춘(행) 것이었습니다. 

 

이상했습니다. 컨테이너는 살아 있고, 리소스 사용량도 정상이었으며 로그도 더 이상 출력되지 않았습니다.
겉보기엔 멀쩡하지만, 안에서는 루프가 멈춰 있는 상태였던 것이죠.

 

근본적인 원인은 다른 방안을 통해 해결 하는데, 일단 이 문제에 대해 모니터링이 미흡 했던 부분을 해소 해보려고 했습니다. 

 

이번 글에서는 무한 루프 기반 작업이 멈췄는지 감지하는 방법과, Kubernetes의 livenessProbe를 활용한 자동 복구 방법을 소개합니다.


🎯 문제 정의

  • 무한 루프를 돌며 배치 작업을 수행하는 Python 워커
  • 하지만 작업이 멈추거나 예외로 루프가 정지해도, 컨테이너는 정상 상태로 간주됨
  • Kubernetes의 기본 헬스 체크로는 이런 문제 감지가 어려움

💡 해결 아이디어

  • 정상적으로 루프가 동작 중이라면, 주기적으로 현재 시간(timestamp) 을 특정 파일에 기록
  • Kubernetes는 주기적으로 해당 타임스탬프와 현재 시간의 차이를 계산해, 일정 시간 이상 멈춰 있으면 컨테이너를 재시작

🔧 구현 방법

1. Python에서 heartbeat 기록

import time

def write_heartbeat(path="/tmp/heartbeat"):
    with open(path, "w") as f:
        f.write(str(int(time.time())))

def main():
    while True:
        # 실제 작업 로직
        process_job()

        # 헬스 체크를 위한 heartbeat 기록
        write_heartbeat()

        # 주기 설정 (예: 30초)
        time.sleep(30)

def process_job():
    # 여기에 작업 로직 작성
    print("작업 실행 중...")

if __name__ == "__main__":
    main()
  • /tmp/heartbeat에 현재 시간을 기록합니다.
  • 기록 주기는 Kubernetes에서 체크하는 주기보다 짧거나 같게 유지해야 합니다.

2. Kubernetes livenessProbe 설정

livenessProbe:
  exec:
    command:
      - /bin/sh
      - -c
      - test $(($(date +%s) - $(cat /tmp/heartbeat))) -lt 90
  initialDelaySeconds: 10
  periodSeconds: 30
  • 현재 시간과 heartbeat 파일의 시간 차가 90초 미만이면 정상
  • 90초 이상 heartbeat가 갱신되지 않으면 비정상 → 컨테이너 재시작

⚠️ 주의 사항

  • write_heartbeat() 호출이 작업 실패나 예외 등으로 인해 실행되지 않을 경우, Kubernetes가 자동으로 감지하고 재시작합니다.
  • /tmp/heartbeat는 컨테이너 내부 경로이므로, Pod 내 다른 컨테이너와는 공유되지 않습니다.
  • 실제 배치 주기보다 heartbeat 기록 주기를 조금 더 짧게 설정하는 것이 좋습니다.

🧩 맺음말

비교적, API 서비스에 대해서만 pod health check를 신경 쓰고, 당연히 배치는 누락 되었다는 점을 다시 한번 반성하게 되는 사건이 됩니다.

 

다행히도 좋은 방법론을 찾아 모니터링을 통해 빠르게 감지 및 복구가 가능하도록 도와주었습니다.

복잡한 방식이 아니더라도 간단한 파일 기록을 통해, 서비스 장애에 대해 모니터링 할 수 있는 방법 입니다.

 

비슷한 형태 (K8S + 무한 루프 배치)로 운영중이시라면, 꼭 이 방법을 적용 해보시길 바라고,

그 외에도 배치의 헬스체크를 소월하게 한것은 아닌지 돌아보시면 좋을 것 같습니다.

 

 

댓글