클라우드 타고 포트와 파도
article thumbnail

개요

개발 서버에서 CronJob을 이용한 자동 재시작 기능을 테스트하였으며,

재시작 원인에 따라 JANDI 알림이 전송되거나 차단되도록 하는 기능을 구현하였습니다.

 

이를 위해 환경 변수(RESTART_REASON) 를 도입하여

재시작 유형을 수동(MANUAL) 과 자동(CRONJOB) 으로 구분하고,

각 상황에 맞게 알림 전송 여부를 제어하도록 로직을 구성하였습니다.

 

특히, 매일 정기적으로 수행되는 자동 재시작(CronJob 기반) 의 경우

운영상 필수적인 동작이므로 불필요한 알림이 반복되지 않도록

slack 알림이 자동으로 차단되도록 처리하였으며,

반대로 운영자에 의한 수동 재시작 시에는

관련 변경 사항을 신속히 공유할 수 있도록 알림이 정상 전송되도록 설정하였습니다.

수동 재시작(MANUAL) → SLACK 알림 전송
CronJob 재시작(CRONJOB) → SLACK 알림 차단

 

환경변수 활용 방식 

(1) RESTART_REASON 개념 

Kubernetes에서는 컨테이너 내부 애플리케이션에 환경 변수를 주입할 수 있습니다.
이 값은 Pod 생성 시 env 필드에서 정의되며, 컨테이너 내부의 스크립트는 해당 값을 참조해 동작을 결정할 수 있습니다.

RESTART_REASON은 Pod의 재시작 원인을 명시적으로 나타내는 사용자 정의 환경 변수입니다.
기본값은 "MANUAL"이며, CronJob으로 실행될 때만 "CRONJOB"으로 변경됩니다

 

(2) RESTART_REASON 활용 방식

Deployment 설정 (기본값: MANUAL)

  - name: RESTART_REASON
    value: "MANUAL"  # 기본값 설정 (수동 재시작)
  - name: SLACK_WEBHOOK_API
    valueFrom:
      configMapKeyRef:
        name: slack_env
        key: SLACK_API

Pod 생성 시 기본적으로 RESTART_REASON="MANUAL"이 설정됩니다.
따라서 사용자가 직접 kubectl rollout restart 명령어로 재시작할 경우 Slack 알림이 전송됩니다.

 

(3) Pod 시작 시 실행되는 스크립트

if [ "$RESTART_REASON" != "CRONJOB" ]; then
  echo "Pod started with RESTART_REASON=$RESTART_REASON";
  echo "Sending restart alert to JANDI...";
  curl -s -X POST -H "Content-Type: application/json" \
       -d '{"body": "Pod restarted!", "connectInfo": [{"title": "Pod Name", "description": "'"$HOSTNAME"'"}, {"title": "Restart Reason", "description": "'"$RESTART_REASON"'"}]}' \
       $JANDI_WEBHOOK_API;
else
  echo "Slack 알림 차단됨 (RESTART_REASON=CRONJOB)";
fi

while true; do sleep 3600; done
  • RESTART_REASON != "CRONJOB" → JANDI 알림 전송
  • RESTART_REASON == "CRONJOB" → 알림 차단

즉, CronJob 기반 재시작은 자동화된 운영성 재시작으로 판단하여 알림을 생략하도록 했습니다.

 

(4) CronJob을 활용한 자동 재시작

apiVersion: batch/v1
kind: CronJob
metadata:
  name: test-restart-job
  namespace: test
spec:
  schedule: "* 23 * * *"
  jobTemplate:
    spec:
      ttlSecondsAfterFinished: 15
      template:
        spec:
          serviceAccountName: test-restart-sa
          restartPolicy: Never
          containers:
          - name: restart
            image: bitnami/kubectl:latest
            command:
            - /bin/sh
            - -c
            - >
              kubectl set env deployment test -n test RESTART_REASON=CRONJOB &&
              kubectl rollout restart deployment test -n test

이 CronJob은 다음 순서로 동작합니다:

  1. RESTART_REASON 값을 "CRONJOB"으로 변경
  2. kubectl rollout restart 명령으로 Deployment 재시작
  3. 새 Pod가 CRONJOB 이유를 인식하여 JANDI 알림을 차단

(5) Role & ServiceAccount 설정

CronJob이 Deployment를 재시작할 수 있도록 RBAC 권한을 구성합니다.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-restart-sa
  namespace: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: test
  name: test-restart-role
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: test
  name: test-restart-rolebinding
subjects:
- kind: ServiceAccount
  name: test-restart-sa
  namespace: test
roleRef:
  kind: Role
  name: test-restart-role
  apiGroup: rbac.authorization.k8s.io

 

  • ServiceAccount (test-restart-sa)
    → CronJob이 사용할 계정
  • Role (test-restart-role)
    → Deployment 재시작에 필요한 최소 권한 부여
  • RoleBinding
    → 두 리소스를 연결하여 CronJob이 권한을 행사할 수 있도록 설정

 

테스트 결과 및 문제점 

(1) 정상 동작 확인

CronJob 실행 시 Slack 알림이 정상적으로 차단됨

 

(2) 문제점

수동 재시작 시 Slack 알림 미전송

-> kubectl rollout restart 실행 시 이전 상태(RESTART_REASON=CRONJOB)가 유지되어 Slack 알림이 전송되지 않음

 

환경 변수 변경 반영 문제

-> Deployment 재시작 시에도 Pod의 env 값이 그대로 유지되어 새로운 값이 반영되지 않음

-> Kubernetes env 필드는 Pod 생성 시점에만 설정되므로 이후 변경 시 적용되지 않음 

 

수정 방향

(1) ConfigMap 활용한 환경 변수 관리 개선 

env 대신 ConfigMap + VolumeMount 구조를 사용하여
RESTART_REASON 값을 외부에서 유연하게 관리하도록 개선하였습니다. 

 

(2) Deployment 설정 변경

volumeMounts:
- name: restart-status
  mountPath: /config/restart-reason
volumes:
- name: restart-status
  configMap:
    name: restart-status
    items:
    - key: restart-reason
      path: restart-reason

 

 

(3) ConfigMap 설정

apiVersion: v1
kind: ConfigMap
metadata:
  name: restart-status
  namespace: test 
data:
  restart-reason: "MANUAL"

Pod 내부에서 /config/restart-reason/restart-reason 파일을 읽어
현재 재시작 이유를 실시간으로 확인할 수 있게 됩니다.

 

(4) CronJob 수정

기존의 kubectl set env 대신 ConfigMap을 직접 수정하는 구조로 변경하였습니다.

- name: restart
  image: bitnami/kubectl:latest
  command:
  - /bin/sh
  - -c
  - >
    kubectl create configmap restart-status --from-literal=restart-reason=CRONJOB -n test --dry-run=client -o yaml | kubectl apply -f - &&
    kubectl rollout restart -n test deployment test &&
    kubectl rollout status deployment test -n test &&
    sleep 10 &&
    kubectl create configmap restart-status --from-literal=restart-reason=MANUAL -n test --dry-run=client -o yaml | kubectl apply -f -

동작 순서는 다음과 같습니다:

  1. ConfigMap을 "CRONJOB" 값으로 임시 변경
  2. Deployment 재시작 및 상태 확인
  3. 재시작 완료 후 "MANUAL" 값으로 복구

이 과정을 통해 자동화 재시작 동안만 SLACK알림이 차단됩니다.

 

결론 

ConfigMap과 VolumeMount를 통해 환경 변수 관리 방식을 개선하였으며,
이를 통해 수동 재시작과 CronJob 재시작을 명확히 구분할 수 있게 되었습니다.

 

(1) 정상 동작 확인

  • CronJob 실행 시 → JANDI 알림 차단 ✅
  • 수동 재시작 시 → JANDI 알림 정상 전송 ✅
  • ConfigMap 변경 사항이 실시간 반영 ✅

(2) 개선 효과

  • 환경 변수 변경이 즉시 반영되도록 ConfigMap 기반 구조로 전환
  • Pod이 직접 RESTART_REASON 파일을 참조하도록 하여 운영 신뢰성 향상
  • CronJob과 수동 재시작 간의 구분이 명확해져 운영 알림 품질 향상
profile

클라우드 타고 포트와 파도

@cloudwave

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!