
K8s 운영 과정에서 ConfigMap/Secret 변경 시 Pod를 재기동하는 것은 꼭 필요한 프로세스입니다.
다만 사람이 수동으로 처리하기 어렵기 때문에, 보통은 Helm 템플릿 + checksum annotation(`checksum/config`) 방식으로 ConfigMap/Secret 변경을 감지해 자동으로 Rolling Update가 일어나도록 구성합니다.
하지만 사내에서는 아직 Helm을 도입하지 않았고(준비중), Kustomize를 활용하여 리소스를 관리하고 있기 때문에 오픈소스인 stakater/reloader를 도입해 ConfigMap/Secret 변경 시 워크로드를 자동으로 재배포하도록 운영하고 있습니다.
그런데 운영 중 ConfigMap이 변경되었음에도 간헐적으로 Pod가 재시작되지 않는 현상이 발생했고, 이를 명확히 파악하기 위해 테스트 환경을 구성하여 검증을 진행했습니다.
테스트 시나리오 및 전체 플로우 요약
1. ConfigMap 변경이 정상적으로 감지되는지
2. 감지되었다면, 워크로드가 정상적으로 롤링 업데이트(또는 재시작) 되는지
2-1.감지는 되는데 재시작이 안 된다면
- Reloader의 롤아웃 전략 설정 문제
- Rollout/Deployment 리소스 종류에 따른 처리 방식 차이
- ArgoCD가 drift로 인식하여 적용을 되돌리거나 충돌하는 문제
2-2. 감지 자체가 안 된다면
- Reloader 리소스 라벨/annotation 매칭 문제
- Helm 도입 + checksum annotation 방식 검토
위 목표 및 가설을 토대로 테스트를 진행하였습니다.
환경 구성
reloader 설정 수정 (slack webhook 발송)
...
ALERT_ON_RELOAD: "true"
ALERT_SINK: "slack"
ALERT_WEBHOOK_URL: webhook url
ALERT_ADDITIONAL_INFO: "configmap-reloader 알람 (재시작 발생하는지 확인용)"
...
위와 같이 configmap reloader에서 감지되면 slack으로 메시지를 보내게끔 설정했습니다.
Test Pod의 Configmap 수정
apiVersion: v1
kind: ConfigMap
metadata:
name: dev-reloader-test-configmap
annotations:
reloader.stakater.com/match: "true"
data:
TEST_VALUE: "initial-value-1"
TEST_TIMESTAMP: "2024-01-01T00:00:00Z"
TEST_DESCRIPTION: "ConfigMap Reloader 테스트용 ConfigMap"
초기에 구성한 configmap입니다.
`reloader.stakater.com/match: "true"`로 Reloader가 변경을 감지할 수 있도록 구성하였고, 테스트를 진행하면서 해당 값들이 변경되는것을 의도하였습니다.
Test Pod yaml 수정
...
spec:
nodeSelector:
dedicate: worker
containers:
- name: reloader-test
image: busybox:1.36
command:
- sh
- -c
- |
echo "=== ConfigMap Reloader Test Pod 시작 ==="
echo "Pod 시작 시간: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "TEST_VALUE: $TEST_VALUE"
echo "TEST_TIMESTAMP: $TEST_TIMESTAMP"
echo "TEST_DESCRIPTION: $TEST_DESCRIPTION"
echo "Pod UID: $(cat /proc/self/cgroup | grep -oP 'docker/\K[^/]+' || echo 'unknown')"
echo "=== 환경변수 확인 완료 ==="
# ConfigMap 변경 감지를 위해 주기적으로 로그 출력
while true; do
echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] Pod 실행 중... TEST_VALUE=$TEST_VALUE"
sleep 30
done
...
위와 같이 busybox image를 받아와 configmap의 값을 로그로 출력하는 pod를 구성합니다.
Test Pod 배포 후 log 확인

위에 구성한 pod를 배포한 후 log를 확인해보면 위와 같이 현재의 `TEST_VALUE=initial-value-1` 값을 출력하고 있는 것을 확인할 수 있습니다.
1차 테스트 진행 (configmap 수정)
configmap 수정
...
data:
TEST_VALUE: "updated-value-2"
TEST_TIMESTAMP: "2024-12-19T12:00:00Z"
TEST_DESCRIPTION: "ConfigMap Reloader 테스트용 ConfigMap - 수정됨"
...
위와 같이 값을 수정하고 확인해보겠습니다.
slack 확인

위와 같이 slack 메시지가 정상적으로 오는 것을 확인했습니다.
Reloader log 확인

Changes detected in 'dev-reloader-test-configmap' of type 'CONFIGMAP' in namespace 'dev-reloader-test'; updated 'dev-reloader-test' of type 'Rollout' in namespace 'dev-reloader-test'"
reloader pod에서 위의 로그가 쌓여 감지는 정상적으로 이루어진 것을 확인할 수 있었습니다.
Test Pod log 확인

하지만 pod가 정상적으로 재시작되지 않았고, 그에 따라 configmap도 이전의 configmap이 보여집니다.
1차 테스트 결론
현재 감지는 되지만, 재배포가 이루어지지 않음
가설 : ArgoCD 환경에서 기본 전략이 drift로 감지될 수 있음

해당 오픈소스의 공식문서를 확인해보면, ArgoCD 환경에서는 기본 rollout 전략이 `configuration drift` 로 감지될 수 있어 `restart` 전략을 사용해야 한다고 합니다.
(즉, Reloader가 워크로드에 변화를 주더라도 ArgoCD가 이를 “원하지 않는 변경”으로 보고 되돌리거나 충돌할 수 있음)
2차 테스트 진행 (Rollout Strategy를 restart로 변경)
Test Pod 수정
...
annotations:
reloader.stakater.com/auto: "true"
reloader.stakater.com/rollout-strategy: "restart"
...
pod의 annotation에 `rollout-strategy: “restart”` 를 추가하여, 기본 배포 방식을 rolling update에서 restart로 변경합니다.
Test Pod log 확인

이전에 수정했었던 `TEST_VALUE=updated-value-2` 이 출력되고 있는 것을 확인할 수 있습니다.
Test Pod ConfigMap 수정
...
TEST_VALUE: "updated-value-3"
TEST_TIMESTAMP: "2024-12-19T14:30:00Z"
TEST_DESCRIPTION: "ConfigMap Reloader 테스트용 ConfigMap - 2차 수정 (restart 전략 테스트)"
...
Slack으로 Reloader 감지 확인

ArgoCD에서 Application 확인

그 후 ArgoCD에서 해당 Test Application을 확인해보면 pod가 재시작되고 있는 것을 확인할 수 있습니다.
2차 테스트 결론
restart로 배포 방식을 변경하면 configmap이 수정될 시에 재시작됨.
restart 전략은 원하는 흐름대로 동작합니다. 하지만 restart 전략을 운영 환경에서 사용한다면 매우매우 리스크가 큽니다.(당연히...)
대안: reloadStrategy를 annotations로 설정하여 drift 회피 + rolling update 유도
Reload Strategies

그렇게 테스트를 진행하면서 해당 이슈를 해결하기 위해 공식문서를 보던 중 `--reload-strategy=annotations` 을 `configmap-reloader` 에 설정하면 ArgoCD drift를 피하면서도 rolling update가 가능하다고 합니다. (오!!!)
3차 테스트 - reloadStrategy를 annotations로 설정
reloader 설정 변경
...
isArgoRollouts: true
reloadStrategy: "annotations"
...
Test Pod의 Configmap 수정
...
TEST_VALUE: "updated-value-5-rolling-update-test"
TEST_TIMESTAMP: "2024-12-19T17:00:00Z"
TEST_DESCRIPTION: "ConfigMap Reloader 테스트용 ConfigMap - rolling update 테스트"
...
이전에 설정했던 restart는 삭제하고, configmap을 수정합니다.
결과

그 후 ArgoCD에서 확인해보면 rolling upgrdate 방식으로 배포가 이루어지는 것을 확인할 수 있었습니다.

또한, 로그도 수정된 configmap으로 쌓이는 것을 확인할 수 있었습니다.

Pod의 상세 내용을 확인해보면, 이전에 없던 annotation이 생성된 것을 확인할 수 있tmqslek.
이는 설정한 reload-strategy으로 인해 pod에 설정된 annotation인데, 해당 설정을 통해 마지막 수정날짜를 확인해서 ArgoCD에서 diff 인식하게끔 만들고 rolloing upgrade 트리거로 동작하게끔 동작합니다.
결론
현재 구성된 Slack 알림 및 reloader 로그를 통해 확인해본 결과 Reloader는 ConfigMap 변경을 정상적으로 감지했습니다. 하지만 이 이슈의 근본적인 문제는 configmap 변경의 감지에 대한 것이 아닌 아닌, ArgoCD 환경에서 실제 롤아웃이 누락될 수 있음이었습니다.
대응 방안으로 `rollout-strategy: restart` 는 재시작을 확실하게 트리거한다는 장점이 있지만, 운영 환경에서는 트래픽 단절 등 가용성 측면의 리스크가 있어 신중한 적용이 필요했기에 사용할 수 없습니다.
반면 `reloadStrategy: annotations` 는 ArgoCD의 drift 문제를 회피하면서도 Rolling Update를 유도할 수 있는 방식으로, 운영 환경에서도 충분히 현실적인 대안이 될 수 있었고, 테스트를 통해 적절한 대안인 것을 확인할 수 있었습니다.
사실 Helm을 사용한다면 checksum을 통해 더 쉽게 configmap/secret 변경을 감지해서 Pod를 재시작할 수 있습니다.
stakater/Reloader을 사용하시면서 이와 같은 이슈를 만나신 분들은 이러한 시행착오가 도움이 되셨으면 좋겠습니다.
'데브옵스 이야기' 카테고리의 다른 글
| Terraform으로 AWS RDS MySQL 8.0에 감사 로그(Audit Log) 설정하기 (0) | 2025.05.04 |
|---|---|
| 자고 일어나니 Argo Project Member? (19) | 2024.11.22 |
| 명심 (3) | 2024.10.06 |
| AWS S3 Bucket ACL은 권장사항이 아닙니더! (1) | 2024.08.20 |