Ssoon
Helm : 5.7 Triggering a Rolling Update Automatically 본문
🚀 Helm으로 ConfigMap 변경 시 Rolling Update 자동 트리거하기
- Kubernetes에서 ConfigMap은 애플리케이션의 환경 설정을 외부에서 관리할 수 있게 해주는 매우 유용한 리소스입니다.
하지만 ConfigMap이 변경되어도 Deployment가 자동으로 업데이트되지 않는 문제가 있습니다.
Helm을 사용해 ConfigMap 변경 시 자동으로 Rolling Update가 일어나도록 설정하는 방법
📘 문제 상황
- Kubernetes에서 Deployment는 기본적으로 Pod의 스펙이 변경될 때만 새로운 Pod를 생성합니다.
즉, ConfigMap이 수정되어도 Deployment 자체가 변하지 않으면 Rolling Update는 발생하지 않습니다.
그 결과, 새로운 설정값이 반영되지 않은 채 기존 Pod가 그대로 실행되는 문제가 생깁니다.
"ConfigMap이 변경되어도 Deployment가 변경되지 않으면 Pod는 재시작되지 않는다."
⚙️ Kustomize의 방식
- Kustomize에는 ConfigMapGenerator라는 기능이 있습니다.
이 기능은 ConfigMap이 변경될 때마다 자동으로 이름 뒤에 해시(Hash)를 붙여 새로운 ConfigMap 이름을 생성합니다.
이로 인해 Deployment 파일의 참조가 변경되고, Kubernetes는 이를 감지해 자동으로 Rolling Update를 수행합니다.
# Kustomize 예시
configMapGenerator:
- name: app-config
files:
- config.yaml
- 이름이 자동으로 생성되며, ConfigMap 내용이 바뀌면 해시 값이 변경되어 자동 업데이트가 일어납니다.
"Kustomize는 ConfigMap 변경 시 자동으로 이름에 해시를 붙여 Rolling Update를 트리거한다."
🧩 Helm에서는 어떻게 할까?
- Helm에는 Kustomize처럼 자동으로 해시를 붙여주는 기능은 없습니다.
하지만 Helm 템플릿 내에서 sha256sum 함수를 사용하면 유사한 효과를 낼 수 있습니다.
이 함수를 통해 ConfigMap 파일의 내용을 해시화하고, 그 해시 값을 Deployment의 annotation에 추가하면 됩니다. - annotation 값이 변경되면 Deployment 템플릿이 달라졌다고 인식되어 Pod가 자동으로 재배포됩니다.
"Helm에서는 sha256sum 함수를 이용해 ConfigMap 내용의 해시값을 annotation에 추가해 Rolling Update를 유도한다."

🌐 예제: Greetings 애플리케이션
이제 실제 예시를 통해 과정을 살펴보겠습니다.
간단한 Node.js 애플리케이션이 있고, 이 앱은 ConfigMap에서 환경 변수(GREETING) 값을 가져와 인사 메시지를 반환합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ mkdir greetings
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ mkdir greetings/templates
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ cd greetings/
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$
🧱 1. Deployment 템플릿 작성
- Deployment 템플릿에서 ConfigMap을 환경 변수로 주입합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ cat << EOF > templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
spec:
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
name: {{ .Chart.Name }}
ports:
- containerPort: {{ .Values.image.containerPort }}
env:
- name: GREETING
valueFrom:
configMapKeyRef:
name: {{ .Values.configmap.name }}
key: greeting
EOF
"Deployment는 ConfigMap의 key-value를 환경 변수로 주입받는다."
🧾 2. ConfigMap 생성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ cat << EOF > templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: greeting-config
data:
greeting: Aloha
EOF
"ConfigMap은 greeting이라는 key에 인사 메시지를 저장한다."
🌉 3. Service 생성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ cat << EOF > templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
name: {{ .Chart.Name }}
spec:
ports:
- name: http
port: {{ .Values.image.containerPort }}
targetPort: {{ .Values.image.containerPort }}
selector:
app.kubernetes.io/name: {{ .Chart.Name }}
EOF
"Service는 Deployment의 Pod에 접근할 수 있도록 포트를 노출한다."
⚙️ 4. values.yaml 설정
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ cat << EOF > values.yaml
image:
repository: quay.io/gitops-cookbook/greetings
tag: "1.0.0"
pullPolicy: Always
containerPort: 8080
replicaCount: 1
configmap:
name: greeting-config
EOF
"values.yaml은 이미지 정보와 ConfigMap 이름을 지정한다."
🧩 5. Chart 설치 및 테스트
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ cat << EOF > Chart.yaml
apiVersion: v2
name: greeting
description: A Helm chart for greeting
type: application
version: 0.1.0 # 차트 버전, 차트 정의가 바뀌면 업데이트한다
appVersion: "1.0.0" # 애플리케이션 버전
EOF
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ tree
.
├── Chart.yaml
├── templates
│ ├── configmap.yaml
│ ├── deployment.yaml
│ └── service.yaml
└── values.yaml
2 directories, 5 files
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ helm install greetings .
NAME: greetings
LAST DEPLOYED: Sat Oct 25 16:17:50 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ kubectl port-forward service/greetings 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
C:\Users\kscho>curl localhost:8080
Aloha Ada
"처음 배포된 앱은 ConfigMap의 greeting 값(Aloha)을 정상적으로 사용한다."
⚠️ 문제 발생: ConfigMap 변경 후에도 반영되지 않음

- ConfigMap을 아래처럼 수정해봅시다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ sed -i 's/Aloha/Hola/' templates/configmap.yaml
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ cat templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: greeting-config
data:
greeting: Hola
- 이후 Helm 차트의 버전을 올려 재배포합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ helm upgrade greetings .
Release "greetings" has been upgraded. Happy Helming!
NAME: greetings
LAST DEPLOYED: Sat Oct 25 16:34:22 2025
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
다시 curl로 테스트하면?
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ kubectl port-forward service/greetings 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
C:\Users\kscho>curl localhost:8080
Aloha Alexandra
- 여전히 이전 값이 출력됩니다.
ConfigMap은 업데이트되었지만 Deployment에는 아무런 변화가 없기 때문입니다.
즉, Pod 재시작이 발생하지 않아 새로운 값이 반영되지 않은 것입니다.
"ConfigMap이 변경되어도 Deployment가 갱신되지 않으면 Pod가 재시작되지 않는다."
🔐 해결 방법: sha256sum으로 체크섬 추가
이 문제를 해결하기 위해 Deployment 템플릿에 아래 코드를 추가합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ sed -i '/ spec:/i \ annotations:\
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}' templates/deployment.yaml
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ cat templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
spec:
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
name: {{ .Chart.Name }}
ports:
- containerPort: {{ .Values.image.containerPort }}
env:
- name: GREETING
valueFrom:
configMapKeyRef:
name: {{ .Values.configmap.name }}
key: greeting
이 코드는 다음을 수행합니다.
- configmap.yaml 파일의 내용을 읽습니다.
- 그 내용을 SHA-256 해시로 변환합니다.
- 해당 해시 값을 Deployment의 annotation(checksum/config)에 추가합니다.
ConfigMap 내용이 바뀌면 해시값도 바뀌기 때문에, Deployment 템플릿이 변경된 것으로 인식되어 Rolling Update가 자동으로 발생합니다.
"ConfigMap의 해시값을 annotation으로 추가하면 내용 변경 시 자동으로 Pod가 재배포된다."

🔁 6. 다시 ConfigMap 수정 및 배포
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ sed -i 's/Hola/Namaste/' templates/configmap.yaml
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ cat templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: greeting-config
data:
greeting: Namaste
- Helm 차트를 다시 업그레이드합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ helm upgrade greetings .
Release "greetings" has been upgraded. Happy Helming!
NAME: greetings
LAST DEPLOYED: Sat Oct 25 16:40:15 2025
NAMESPACE: default
STATUS: deployed
REVISION: 3
TEST SUITE: None
- 이제 다시 curl로 테스트해봅시다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ kubectl port-forward service/greetings 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
C:\Users\kscho>curl localhost:8080
Namaste Ada
- 새로운 설정이 반영되었음을 확인할 수 있습니다.
"sha256sum annotation을 추가하면 ConfigMap 변경 시 Rolling Update가 자동으로 트리거된다."
📸 Figure: Pod annotation 예시
- Pod Annotation 출력 예시
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/greetings$ k describe pod greetings-67cc7d89c7-5cq65
Name: greetings-67cc7d89c7-5cq65
Namespace: default
Priority: 0
Service Account: default
Node: myk8s-control-plane/172.19.0.2
Start Time: Sat, 25 Oct 2025 16:40:15 +0900
Labels: app.kubernetes.io/name=greetings
pod-template-hash=67cc7d89c7
Annotations: checksum/config: 38f96b801b3a9f43e67bf729e33729fd0576ebc15332a6fcbea5c05c679238de
Status: Running
IP: 10.244.0.45
...
| checksum/config: 38f96b801b3a9f43e67bf729e33729fd0576ebc15332a6fcbea5c05c679238de |
📌 핵심 요약
- 문제: ConfigMap이 변경되어도 Deployment가 갱신되지 않으면 Pod는 재시작되지 않는다.
- Kustomize: ConfigMap 이름에 해시를 자동 추가해 Rolling Update를 유도한다.
- Helm: sha256sum 함수를 활용해 ConfigMap의 해시값을 annotation에 추가하여 동일한 효과를 낼 수 있다.
- 결과: ConfigMap 변경 시 자동으로 Deployment가 업데이트되어 Pod가 재배포된다.
- 핵심 코드:
- annotations: checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
"Helm 차트에서 sha256sum을 활용하면 ConfigMap 변경 시 자동 Rolling Update를 구현할 수 있다."
'CICD Study [1기]' 카테고리의 다른 글
| Cloud Native CI/CD : 6.2 Create a Hello World Task (0) | 2025.10.19 |
|---|---|
| Cloud Native CI/CD : 6.1 Install Tekton (0) | 2025.10.19 |
| Helm : 5.6 Deploying a Chart with a Dependency (0) | 2025.10.19 |
| Helm : 5.5 Deploying a Chart from a Repository (0) | 2025.10.19 |
| Helm : 5.4 - Helm 차트 패키징 및 배포 (0) | 2025.10.19 |