본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 22. · 3 Views
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
목차
1. Chart 생성하기
어느 날 김개발 씨는 팀장님으로부터 새로운 미션을 받았습니다. "우리 마이크로서비스를 Helm으로 패키징해서 배포 자동화를 구축해보세요." Kubernetes YAML 파일만 수십 개를 관리하던 김개발 씨는 막막했습니다.
Helm Chart는 Kubernetes 애플리케이션을 패키징하는 표준 방식입니다. 마치 npm 패키지나 Python의 pip 패키지처럼, 애플리케이션의 모든 리소스를 하나의 번들로 묶어서 관리합니다.
Chart를 생성하면 배포에 필요한 모든 설정이 체계적으로 정리됩니다.
다음 코드를 살펴봅시다.
# Helm Chart 생성 명령어
helm create my-microservice
# 생성된 디렉토리 구조
# my-microservice/
# Chart.yaml # Chart 메타데이터
# values.yaml # 기본 설정값
# templates/ # Kubernetes 리소스 템플릿
# deployment.yaml
# service.yaml
# ingress.yaml
# charts/ # 의존성 Chart들
김개발 씨는 팀장님의 미션을 받고 선배 박시니어 씨를 찾아갔습니다. "시니어님, Helm이 정확히 뭔가요?" 박시니어 씨는 웃으며 대답했습니다.
"쉽게 말하면 Kubernetes용 패키지 매니저예요." Helm이란 무엇일까요? 쉽게 비유하자면, Helm은 마치 앱스토어와 같습니다.
스마트폰에서 앱을 설치할 때 복잡한 파일들을 하나하나 다운로드하지 않고 앱스토어에서 버튼 하나로 설치하죠. Helm도 마찬가지로 복잡한 Kubernetes 리소스들을 패키징해서 간단하게 배포할 수 있게 해줍니다.
Helm이 없던 시절에는 어땠을까요? 개발자들은 Deployment, Service, Ingress, ConfigMap 등 수십 개의 YAML 파일을 직접 관리해야 했습니다.
환경마다 설정이 달라서 dev용, staging용, production용 파일을 따로 만들었습니다. 더 큰 문제는 버전 관리였습니다.
배포한 내용을 롤백하려면 이전 YAML 파일을 Git에서 찾아서 다시 적용해야 했습니다. 바로 이런 문제를 해결하기 위해 Helm Chart가 등장했습니다.
Chart를 사용하면 템플릿 방식으로 YAML 파일을 관리할 수 있습니다. 하나의 템플릿으로 여러 환경에 대응하고, values.yaml 파일로 환경별 설정을 분리합니다.
또한 버전 관리도 자동으로 됩니다. 배포할 때마다 릴리스 번호가 붙고, 문제가 생기면 이전 버전으로 즉시 롤백할 수 있습니다.
Chart 생성 명령어를 실행하면 어떤 일이 일어날까요? helm create 명령어를 실행하면 Helm이 표준 디렉토리 구조를 자동으로 만들어줍니다.
Chart.yaml 파일에는 Chart의 이름, 버전, 설명 같은 메타데이터가 들어갑니다. values.yaml에는 기본 설정값이 정의되어 있습니다.
templates 디렉토리에는 실제 Kubernetes 리소스 템플릿 파일들이 배치됩니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 쇼핑몰 백엔드 API 서비스를 배포한다고 가정해봅시다. 이 서비스는 Deployment, Service, HPA, Ingress가 필요합니다.
Chart를 만들면 이 모든 리소스를 하나로 묶어서 관리할 수 있습니다. 신입 개발자가 로컬에서 테스트할 때도, 프로덕션에 배포할 때도 같은 Chart를 사용합니다.
차이는 values.yaml 파일의 설정값뿐입니다. Chart.yaml 파일을 살펴보면 핵심 정보들이 담겨 있습니다.
apiVersion은 Helm Chart API 버전을 나타냅니다. name은 Chart 이름이고, version은 Chart 자체의 버전입니다.
appVersion은 패키징되는 애플리케이션의 버전을 의미합니다. 이 두 버전을 분리한 이유는 Chart 구조는 그대로인데 애플리케이션만 업데이트되는 경우가 많기 때문입니다.
templates 디렉토리가 Chart의 핵심입니다. 여기에는 Kubernetes 리소스 정의가 Go 템플릿 형식으로 작성되어 있습니다.
하드코딩된 값 대신 변수를 사용하기 때문에 유연하게 설정을 바꿀 수 있습니다. deployment.yaml을 열어보면 이미지 이름, 레플리카 수, 리소스 제한 등이 모두 변수로 되어 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 기본 생성된 템플릿을 그대로 사용하는 것입니다.
Helm이 만들어주는 기본 템플릿은 범용적이라서 실제 프로젝트에는 맞지 않을 수 있습니다. 따라서 팀의 요구사항에 맞게 커스터마이징해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 helm create 명령어를 실행했습니다.
"와, 정말 자동으로 만들어지네요!" Chart 생성은 Helm 여정의 첫 걸음입니다. 이제 이 구조를 이해하고 우리 서비스에 맞게 수정해 나가면 됩니다.
여러분도 직접 Chart를 만들어보면서 구조를 익혀보세요.
실전 팁
💡 - helm create 후에는 templates 디렉토리의 파일들을 반드시 검토하고 불필요한 파일은 삭제하세요
- Chart.yaml의 version과 appVersion을 구분해서 관리하면 Chart 업데이트와 앱 업데이트를 독립적으로 할 수 있습니다
2. values.yaml 설계
Chart 구조를 파악한 김개발 씨는 이제 values.yaml 파일을 열어봤습니다. 수많은 설정값들이 나열되어 있었습니다.
"이걸 어떻게 설계해야 나중에 관리하기 편할까?" 고민이 깊어졌습니다.
values.yaml은 Chart의 모든 설정값을 중앙에서 관리하는 파일입니다. 마치 애플리케이션의 환경설정 파일처럼, 배포 시 바뀔 수 있는 모든 값을 여기에 정의합니다.
템플릿과 설정을 분리함으로써 하나의 Chart로 여러 환경에 대응할 수 있습니다.
다음 코드를 살펴봅시다.
# values.yaml 설계 예시
replicaCount: 3
image:
repository: mycompany/my-microservice
tag: "1.2.3"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 8080
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
env:
DATABASE_URL: "postgresql://db:5432/mydb"
LOG_LEVEL: "info"
김개발 씨는 values.yaml 파일을 처음 열고 당황했습니다. 설정값이 너무 많았기 때문입니다.
박시니어 씨가 다가와 조언했습니다. "values.yaml은 설계가 중요해요.
체계적으로 구조화하지 않으면 나중에 관리가 어려워집니다." values.yaml이란 정확히 무엇일까요? 쉽게 비유하자면, values.yaml은 마치 리모컨과 같습니다.
TV를 볼 때 매번 TV 뒤에 가서 버튼을 누르지 않고 리모컨으로 조작하죠. values.yaml도 마찬가지로 복잡한 템플릿 파일을 직접 수정하지 않고, 설정값만 바꿔서 배포 동작을 제어합니다.
리모컨이 체계적으로 버튼이 배치되어 있듯이, values.yaml도 논리적으로 구조화되어야 합니다. values.yaml이 없다면 어떻게 될까요?
모든 설정을 템플릿 파일에 하드코딩해야 합니다. 개발 환경에 배포할 때와 프로덕션에 배포할 때 템플릿 파일 자체를 수정해야 하죠.
레플리카 수를 3개에서 5개로 늘리려면 deployment.yaml을 열어서 직접 수정해야 합니다. 환경이 늘어날수록 관리할 파일도 기하급수적으로 증가합니다.
바로 이런 문제를 해결하기 위해 values.yaml 패턴이 도입되었습니다. values.yaml을 사용하면 템플릿과 설정의 분리가 가능합니다.
템플릿은 한 번 작성하고, 설정만 바꿔가며 재사용합니다. 또한 계층적 구조로 관련된 설정을 그룹화할 수 있습니다.
image 관련 설정은 image 아래에, service 관련 설정은 service 아래에 모아두면 찾기도 쉽고 관리도 편합니다. values.yaml 설계의 핵심 원칙은 무엇일까요?
첫째, 논리적 그룹핑입니다. 관련된 설정은 같은 계층 아래 모아야 합니다.
image.repository, image.tag, image.pullPolicy처럼 이미지 관련 설정은 image 객체 안에 넣습니다. 둘째, 명확한 네이밍입니다.
누가 봐도 이해할 수 있는 키 이름을 사용해야 합니다. 셋째, 적절한 기본값입니다.
대부분의 경우에 적용할 수 있는 합리적인 기본값을 설정해야 합니다. 위의 예시 코드를 살펴보겠습니다.
replicaCount는 최상위에 위치합니다. 가장 자주 바뀌는 설정이기 때문입니다.
image 섹션에는 컨테이너 이미지 관련 모든 정보가 들어있습니다. repository는 이미지 저장소, tag는 버전, pullPolicy는 이미지를 가져오는 정책입니다.
service 섹션은 Kubernetes Service 리소스 설정입니다. type은 ClusterIP, NodePort, LoadBalancer 중 하나를 선택할 수 있습니다.
resources 섹션이 특히 중요합니다. Kubernetes에서는 리소스 제한을 명시하는 것이 모범 사례입니다.
limits는 Pod가 사용할 수 있는 최대 리소스를 정의합니다. requests는 보장받을 최소 리소스를 나타냅니다.
이 값들을 적절히 설정하지 않으면 한 Pod가 노드의 모든 리소스를 점유해서 다른 Pod에 영향을 줄 수 있습니다. 실제 현업에서는 환경별로 다른 values 파일을 사용합니다.
예를 들어 values-dev.yaml, values-staging.yaml, values-prod.yaml을 따로 만듭니다. 개발 환경에서는 replicaCount를 1로 설정하고 리소스도 작게 할당합니다.
프로덕션에서는 replicaCount를 5로 늘리고 리소스도 충분히 할당합니다. 배포할 때 -f 옵션으로 원하는 values 파일을 지정하면 됩니다.
env 섹션에는 환경변수를 정의합니다. 애플리케이션이 필요로 하는 데이터베이스 URL, API 키, 로그 레벨 같은 설정을 여기에 넣습니다.
템플릿에서는 이 값들을 읽어서 Pod의 환경변수로 주입합니다. 민감한 정보는 나중에 Secret으로 관리하도록 수정할 수 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수는 너무 많은 설정을 노출하는 것입니다.
바뀔 가능성이 거의 없는 값까지 values.yaml에 넣으면 오히려 복잡해집니다. 정말 환경별로 달라지거나 자주 바뀌는 값만 추출해야 합니다.
또 다른 실수는 중첩을 너무 깊게 만드는 것입니다. 3단계 이상 들어가면 접근하기 어려워집니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 조언대로 values.yaml을 체계적으로 재구성했습니다.
"이제 훨씬 보기 좋네요!" values.yaml을 잘 설계하면 Chart의 재사용성이 크게 높아집니다. 한 번 만든 Chart를 여러 프로젝트에서, 여러 환경에서 사용할 수 있습니다.
여러분도 설정값을 논리적으로 그룹화하는 연습을 해보세요.
실전 팁
💡 - 환경별 values 파일을 만들 때는 공통 설정은 values.yaml에 두고, 차이만 환경별 파일에 오버라이드하세요
- 민감한 정보(비밀번호, API 키)는 values.yaml에 직접 넣지 말고 Secret 참조로 처리하세요
3. 템플릿 변수 사용
values.yaml 설계를 마친 김개발 씨는 이제 템플릿 파일을 수정해야 했습니다. deployment.yaml을 열어보니 이상한 문법이 가득했습니다.
"{{ .Values.replicaCount }}"가 대체 뭘까요?
템플릿 변수는 Go 템플릿 엔진을 사용해서 동적으로 값을 주입하는 방식입니다. 이중 중괄호 안에 변수 경로를 작성하면, Helm이 배포 시점에 values.yaml의 값으로 치환합니다.
조건문과 반복문도 사용할 수 있어서 복잡한 로직도 표현 가능합니다.
다음 코드를 살펴봅시다.
# templates/deployment.yaml 예시
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
resources:
{{- toYaml .Values.resources | nindent 10 }}
{{- if .Values.env }}
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- end }}
김개발 씨는 deployment.yaml 파일을 열고 혼란스러웠습니다. 일반 YAML 파일과 달리 이상한 기호들이 가득했기 때문입니다.
박시니어 씨가 옆에서 설명했습니다. "이건 Go 템플릿 문법이에요.
Helm이 사용하는 템플릿 엔진이죠." 템플릿 변수란 무엇일까요? 쉽게 비유하자면, 템플릿 변수는 마치 워드프로세서의 메일 머지 기능과 같습니다.
편지 양식을 하나 만들어두고, 수신자 이름만 바꿔가며 여러 통의 편지를 만드는 것처럼, 하나의 템플릿으로 여러 가지 설정의 YAML을 생성할 수 있습니다. {{ .Values.replicaCount }}는 "여기에 values.yaml의 replicaCount 값을 넣어주세요"라는 의미입니다.
템플릿 변수가 없다면 어떻게 될까요? 모든 설정값을 하드코딩해야 합니다.
레플리카 수를 바꾸려면 deployment.yaml을 직접 수정해야 하고, 이미지 태그를 업데이트하려면 또 파일을 열어야 합니다. 환경이 10개라면 10개의 다른 deployment.yaml 파일을 관리해야 하죠.
하나를 수정하면 나머지도 일일이 수정해야 해서 실수하기 쉽습니다. 바로 이런 문제를 해결하기 위해 템플릿 시스템이 도입되었습니다.
템플릿을 사용하면 DRY 원칙(Don't Repeat Yourself)을 지킬 수 있습니다. 한 번 작성한 템플릿을 재사용하고, 값만 바꿔가며 다양한 배포를 생성합니다.
또한 조건부 렌더링도 가능합니다. 특정 조건에서만 리소스를 생성하거나 설정을 추가할 수 있습니다.
Helm에서 사용할 수 있는 내장 객체는 무엇이 있을까요? .Values는 가장 많이 사용하는 객체로, values.yaml의 값에 접근합니다.
.Release는 현재 릴리스 정보를 담고 있습니다. Release.Name은 helm install 시 지정한 릴리스 이름입니다.
.Chart는 Chart.yaml의 메타데이터에 접근합니다. Chart.Name, Chart.Version 같은 값을 사용할 수 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 첫 번째 줄의 {{ .Release.Name }}-{{ .Chart.Name }}은 릴리스 이름과 Chart 이름을 조합해서 고유한 리소스 이름을 만듭니다.
replicas 필드에는 {{ .Values.replicaCount }}를 넣어서 values.yaml의 값을 사용합니다. image 필드는 두 개의 변수를 조합합니다.
repository와 tag를 콜론으로 연결해서 완전한 이미지 경로를 만듭니다. 파이프라인과 함수를 사용할 수도 있습니다.
toYaml 함수는 객체를 YAML 형식으로 변환합니다. .Values.resources는 중첩된 객체인데, 이걸 그대로 YAML로 변환해서 삽입합니다.
nindent 함수는 들여쓰기를 추가합니다. 숫자 10은 10칸 들여쓰기를 의미합니다.
파이프 기호(|)로 함수들을 연결할 수 있습니다. 조건문과 반복문은 어떻게 사용할까요?
{{ if .Values.env }}는 env 값이 존재할 때만 아래 블록을 렌더링합니다. 환경변수가 정의되지 않은 경우 이 섹션 전체를 건너뜁니다.
{{ range $key, $value := .Values.env }}는 env 맵을 순회합니다. 각 키-값 쌍에 대해 환경변수를 하나씩 생성합니다.
quote 함수는 값을 따옴표로 감쌉니다. 하이픈(-)의 역할이 중요합니다.
{{- 처럼 여는 중괄호 뒤에 하이픈을 붙이면 앞쪽 공백을 제거합니다. -}}처럼 닫는 중괄호 앞에 하이픈을 붙이면 뒤쪽 공백을 제거합니다.
이렇게 하지 않으면 생성된 YAML에 불필요한 빈 줄이 생겨서 가독성이 떨어집니다. 실제 현업에서는 더 복잡한 템플릿을 작성합니다.
예를 들어 Ingress 리소스를 조건부로 생성하는 경우가 있습니다. values.yaml에 ingress.enabled 값이 true일 때만 ingress.yaml 템플릿이 렌더링되도록 합니다.
또는 여러 개의 호스트를 반복문으로 처리해서 멀티 도메인 Ingress를 만들기도 합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수는 템플릿을 너무 복잡하게 만드는 것입니다. 조건문이 중첩되고 반복문이 여러 개 들어가면 디버깅이 어려워집니다.
템플릿은 가능한 단순하게 유지하고, 복잡한 로직은 헬퍼 템플릿으로 분리하는 것이 좋습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 템플릿 문법을 이해하기 시작했습니다. "이제 이 기호들이 뭔지 알겠어요!" 템플릿 변수를 제대로 활용하면 강력하고 유연한 Chart를 만들 수 있습니다.
한 번 작성한 템플릿으로 수십 가지 배포 시나리오를 커버할 수 있습니다. 여러분도 Go 템플릿 문법을 익혀서 재사용 가능한 Chart를 만들어보세요.
실전 팁
💡 - helm template 명령어로 템플릿 렌더링 결과를 미리 확인할 수 있습니다
- 복잡한 템플릿 로직은 _helpers.tpl 파일에 헬퍼 함수로 분리하면 재사용하기 좋습니다
4. helm install/upgrade
드디어 Chart 준비가 끝났습니다. 김개발 씨는 이제 실제로 배포를 해야 했습니다.
"어떻게 배포하죠?" 박시니어 씨가 터미널을 열며 말했습니다. "helm install 명령어를 사용하면 됩니다."
helm install은 Chart를 Kubernetes 클러스터에 배포하는 명령어입니다. 템플릿을 렌더링하고 생성된 리소스를 클러스터에 적용합니다.
helm upgrade는 이미 배포된 릴리스를 새 버전으로 업데이트합니다. 두 명령어 모두 values 파일을 지정해서 설정을 커스터마이징할 수 있습니다.
다음 코드를 살펴봅시다.
# Chart 설치 (신규 배포)
helm install my-app ./my-microservice \
-f values-prod.yaml \
--namespace production \
--create-namespace
# Chart 업그레이드 (기존 릴리스 업데이트)
helm upgrade my-app ./my-microservice \
-f values-prod.yaml \
--namespace production
# install과 upgrade를 자동 선택
helm upgrade --install my-app ./my-microservice \
-f values-prod.yaml \
--namespace production \
--atomic \
--timeout 5m
김개발 씨는 떨리는 마음으로 helm install 명령어를 입력했습니다. 과연 제대로 배포될까요?
박시니어 씨가 옆에서 조언합니다. "처음에는 --dry-run 옵션으로 테스트해보는 게 좋아요." helm install은 정확히 무엇을 할까요?
쉽게 비유하자면, helm install은 마치 집 짓기와 같습니다. 설계도(Chart)를 보고 실제로 집(Kubernetes 리소스)을 건설합니다.
values.yaml은 시공 옵션(창문 색깔, 벽지 패턴 등)을 지정하는 것이고, 명령어를 실행하면 실제 건물이 세워집니다. 한 번 지은 집에는 주소(릴리스 이름)가 부여되고, 나중에 리모델링(upgrade)할 수도 있습니다.
helm install이 없던 시절에는 어떻게 배포했을까요? kubectl apply 명령어로 YAML 파일을 하나씩 적용해야 했습니다.
파일이 10개면 명령어를 10번 실행하거나 스크립트를 작성했습니다. 배포 순서도 중요해서 Service를 먼저 만들고 Deployment를 나중에 만드는 식으로 신경 써야 했습니다.
롤백할 때는 이전 YAML 파일을 찾아서 다시 apply 해야 했고, 완전히 삭제하려면 각 리소스를 일일이 delete 했습니다. 바로 이런 문제를 해결하기 위해 helm install/upgrade가 제공됩니다.
helm install을 사용하면 원자적 배포가 가능합니다. Chart의 모든 리소스가 한 번에 배포되고, 하나라도 실패하면 전체가 롤백됩니다.
또한 릴리스 추적이 자동으로 됩니다. 배포할 때마다 Secret에 릴리스 정보가 저장되어서 나중에 히스토리를 확인하거나 롤백할 수 있습니다.
helm install 명령어의 구조를 살펴보겠습니다. 첫 번째 인자인 my-app은 릴리스 이름입니다.
같은 Chart를 여러 번 설치할 수 있는데, 각 설치를 구분하는 식별자입니다. 두 번째 인자인 ./my-microservice는 Chart 경로입니다.
로컬 디렉토리일 수도 있고, Chart 저장소의 이름일 수도 있습니다. -f 옵션으로 values 파일을 지정합니다.
여러 개의 values 파일을 지정할 수도 있습니다. -f values.yaml -f values-prod.yaml처럼 나열하면 뒤에 오는 파일이 앞의 값을 오버라이드합니다.
공통 설정은 values.yaml에 두고, 환경별 차이는 values-prod.yaml에 넣는 방식으로 활용합니다. --namespace 옵션이 중요합니다.
Kubernetes에서는 네임스페이스로 리소스를 논리적으로 분리합니다. 개발 환경과 프로덕션 환경을 다른 네임스페이스에 배포하면 격리됩니다.
--create-namespace 옵션을 함께 사용하면 네임스페이스가 없을 때 자동으로 생성해줍니다. helm upgrade는 언제 사용할까요?
이미 설치된 릴리스를 업데이트할 때 사용합니다. 애플리케이션 버전을 올리거나, 설정을 변경하거나, Chart 자체를 업데이트할 때 helm upgrade를 실행합니다.
Helm은 변경된 리소스만 감지해서 업데이트하므로 효율적입니다. upgrade --install 패턴이 실무에서 유용합니다.
이 옵션을 사용하면 Helm이 자동으로 판단합니다. 릴리스가 없으면 install하고, 이미 있으면 upgrade합니다.
CI/CD 파이프라인에서 특히 편리합니다. 매번 릴리스 존재 여부를 확인하는 스크립트를 작성할 필요가 없습니다.
--atomic 옵션은 안전장치 역할을 합니다. 배포 중 오류가 발생하면 자동으로 이전 버전으로 롤백합니다.
프로덕션 배포 시 필수적인 옵션입니다. --timeout과 함께 사용해서 최대 대기 시간을 지정할 수 있습니다.
5분 안에 모든 Pod가 Ready 상태가 되지 않으면 실패로 간주하고 롤백합니다. 실제 현업에서는 어떻게 활용할까요?
CI/CD 파이프라인에서 helm upgrade --install을 사용합니다. GitHub Actions나 GitLab CI에서 코드가 푸시되면 자동으로 빌드하고, 새 이미지 태그를 values에 주입해서 배포합니다.
카나리 배포를 하려면 먼저 적은 수의 레플리카로 배포하고, 문제가 없으면 전체를 업데이트합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수는 프로덕션에 바로 배포하는 것입니다. 반드시 개발 환경에서 먼저 테스트하고, helm template이나 --dry-run 옵션으로 렌더링 결과를 확인해야 합니다.
또 다른 실수는 네임스페이스를 혼동하는 것입니다. 잘못된 네임스페이스에 배포하면 기존 서비스에 영향을 줄 수 있습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. --dry-run으로 테스트한 김개발 씨는 실제 배포를 진행했습니다.
"배포 성공! Pod가 떴어요!" 첫 번째 Helm 배포에 성공한 순간이었습니다.
helm install과 upgrade를 마스터하면 안전하고 반복 가능한 배포를 할 수 있습니다. 한 번 작성한 배포 명령어를 스크립트나 CI/CD에 넣어두면 누구나 같은 방식으로 배포할 수 있습니다.
여러분도 다양한 옵션을 실험해보면서 배포 프로세스를 완성해보세요.
실전 팁
💡 - 프로덕션 배포 전에는 항상 helm diff 플러그인으로 변경사항을 확인하세요
- --atomic과 --timeout 옵션을 함께 사용해서 안전한 배포를 보장하세요
5. 릴리스 관리
배포에 성공한 김개발 씨는 뿌듯했습니다. 하지만 박시니어 씨가 물었습니다.
"만약 이 배포에 버그가 있다면 어떻게 하실 건가요?" 김개발 씨는 당황했습니다. "다시 배포하면 되지 않나요?"
릴리스 관리는 Helm의 강력한 기능 중 하나입니다. 모든 배포 히스토리가 자동으로 기록되고, 언제든지 이전 버전으로 롤백할 수 있습니다.
helm list로 현재 릴리스를 확인하고, helm history로 변경 이력을 추적하며, helm rollback으로 안전하게 되돌릴 수 있습니다.
다음 코드를 살펴봅시다.
# 현재 릴리스 목록 조회
helm list -n production
# 특정 릴리스의 히스토리 확인
helm history my-app -n production
# 이전 버전으로 롤백
helm rollback my-app 3 -n production
# 릴리스 삭제 (리소스는 유지)
helm uninstall my-app -n production
# 릴리스 상태 확인
helm status my-app -n production
# 릴리스의 values 확인
helm get values my-app -n production
김개발 씨는 박시니어 씨의 질문에 당황했습니다. "롤백이요?
어떻게 하는데요?" 박시니어 씨가 미소 지으며 대답했습니다. "바로 이게 Helm의 진가예요.
릴리스 관리 기능이 있거든요." 릴리스란 정확히 무엇일까요? 쉽게 비유하자면, 릴리스는 마치 게임의 세이브 포인트와 같습니다.
게임을 진행하다가 중요한 지점마다 저장하면, 나중에 실수했을 때 그 지점으로 돌아갈 수 있죠. Helm도 마찬가지로 배포할 때마다 릴리스를 생성하고, 문제가 생기면 이전 릴리스로 되돌릴 수 있습니다.
각 릴리스에는 번호가 매겨져서 순서대로 관리됩니다. 릴리스 관리가 없다면 어떻게 될까요?
kubectl로 직접 배포하면 히스토리가 남지 않습니다. 어떤 YAML을 언제 배포했는지 기억에 의존해야 합니다.
롤백하려면 Git 히스토리를 뒤져서 이전 버전을 찾아야 하고, 그마저도 누군가 Git에 커밋하지 않았다면 복구가 불가능합니다. 여러 리소스를 일일이 삭제하고 다시 만들어야 해서 시간도 오래 걸립니다.
바로 이런 문제를 해결하기 위해 Helm 릴리스 시스템이 제공됩니다. Helm은 배포할 때마다 Secret에 릴리스 정보를 저장합니다.
Chart의 버전, 사용한 values, 생성된 리소스 목록이 모두 기록됩니다. 이 정보를 바탕으로 언제든지 히스토리를 조회하거나 롤백할 수 있습니다.
또한 원자적 롤백이 가능합니다. 관련된 모든 리소스가 한 번에 이전 상태로 돌아갑니다.
helm list 명령어로 무엇을 확인할까요? 현재 네임스페이스에 설치된 모든 릴리스가 표시됩니다.
릴리스 이름, 네임스페이스, 리비전 번호, 업데이트 시간, 상태, Chart 버전 등을 한눈에 볼 수 있습니다. -A 옵션을 붙이면 모든 네임스페이스의 릴리스를 조회합니다.
helm history는 특정 릴리스의 변경 이력을 보여줍니다. 첫 번째 배포는 리비전 1입니다.
helm upgrade를 실행하면 리비전 2가 됩니다. 또 upgrade하면 리비전 3이 되는 식입니다.
각 리비전마다 언제 배포했는지, 어떤 상태인지, 설명(description)이 무엇인지 나옵니다. 롤백을 실행해도 새 리비전이 추가되므로 모든 변경이 추적됩니다.
helm rollback의 동작 원리는 무엇일까요? rollback 명령어에 리비전 번호를 지정하면, Helm이 해당 리비전의 Secret을 읽어서 그때의 상태를 복원합니다.
이미지 태그, 레플리카 수, 환경변수 등 모든 설정이 그때 그대로 돌아갑니다. 롤백 자체도 새로운 리비전으로 기록되므로, 롤백을 롤백하는 것도 가능합니다.
실제 현업에서는 어떻게 활용할까요? 프로덕션에 새 버전을 배포했는데 갑자기 에러율이 급증했다고 가정해봅시다.
디버깅하는 동안 서비스가 계속 장애 상태에 있을 수는 없습니다. helm rollback 명령어 한 줄이면 수 초 안에 이전 버전으로 돌아가서 서비스를 정상화할 수 있습니다.
나중에 천천히 원인을 파악하고 수정해서 재배포하면 됩니다. helm status는 현재 릴리스의 상태를 확인합니다.
배포한 리소스들이 제대로 실행 중인지, Pod가 몇 개나 떠 있는지, 마지막 배포 시간은 언제인지 등을 보여줍니다. Notes 섹션에는 Chart 작성자가 남긴 메시지가 표시됩니다.
보통 접속 방법이나 다음 단계 안내가 적혀 있습니다. helm get values는 실제 적용된 values를 확인합니다.
배포할 때 여러 values 파일을 오버라이드하거나 --set 옵션으로 값을 주입했을 수 있습니다. get values 명령어는 최종적으로 병합된 값을 보여줍니다.
예상과 다른 값이 적용되었는지 확인할 때 유용합니다. helm uninstall은 릴리스를 완전히 제거합니다.
관련된 모든 Kubernetes 리소스가 삭제됩니다. 기본적으로 릴리스 히스토리도 삭제되지만, --keep-history 옵션을 사용하면 히스토리를 보존할 수 있습니다.
나중에 같은 이름으로 다시 설치할 때 이전 히스토리를 이어갈 수 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수는 리비전 번호를 잘못 지정하는 것입니다. helm rollback my-app 1이라고 하면 첫 번째 배포로 돌아갑니다.
최근 배포가 아니라 아주 오래된 버전으로 롤백될 수 있으니 반드시 history를 확인해야 합니다. 또 다른 실수는 롤백 테스트를 안 하는 것입니다.
개발 환경에서 먼저 롤백을 연습해봐야 프로덕션에서 당황하지 않습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨가 일부러 버그가 있는 버전을 배포한 뒤 롤백을 시연했습니다. "와, 정말 순식간에 돌아가네요!" 김개발 씨는 릴리스 관리의 위력을 체감했습니다.
릴리스 관리를 제대로 활용하면 안심하고 배포할 수 있습니다. 언제든지 되돌릴 수 있다는 확신이 있으면 더 과감하게 실험하고 개선할 수 있습니다.
여러분도 롤백 연습을 해보면서 Helm의 강력함을 느껴보세요.
실전 팁
💡 - 프로덕션 환경에서는 --wait 옵션과 함께 배포해서 모든 리소스가 준비될 때까지 기다리세요
- helm history에서 각 리비전의 description을 확인하면 어떤 변경이었는지 알 수 있습니다
6. Chart 저장소
Chart를 잘 만든 김개발 씨는 다른 팀원들도 사용할 수 있게 공유하고 싶었습니다. "어떻게 배포하죠?" 박시니어 씨가 대답했습니다.
"Chart 저장소를 만들면 됩니다."
Chart 저장소는 Helm Chart를 저장하고 공유하는 중앙 집중식 저장소입니다. 마치 npm 레지스트리나 Docker Hub처럼, Chart를 패키징해서 업로드하면 다른 사람들이 helm install로 바로 설치할 수 있습니다.
공개 저장소와 비공개 저장소 모두 운영 가능합니다.
다음 코드를 살펴봅시다.
# Chart 패키징
helm package ./my-microservice
# 로컬 저장소 인덱스 생성
helm repo index . --url https://charts.mycompany.com
# Chart 저장소 추가
helm repo add mycompany https://charts.mycompany.com
# 저장소 업데이트
helm repo update
# 저장소에서 Chart 검색
helm search repo my-microservice
# 저장소의 Chart 설치
helm install my-app mycompany/my-microservice
김개발 씨는 완성한 Chart를 팀원들에게 공유하고 싶었습니다. "그냥 디렉토리를 복사하면 안 되나요?" 박시니어 씨가 고개를 저었습니다.
"그건 비효율적이에요. Chart 저장소를 만들어서 중앙 관리하는 게 좋습니다." Chart 저장소란 무엇일까요?
쉽게 비유하자면, Chart 저장소는 마치 앱스토어와 같습니다. 개발자가 앱을 만들면 앱스토어에 업로드하고, 사용자는 앱스토어에서 검색해서 설치합니다.
Chart 저장소도 마찬가지로 Chart를 업로드하면, 다른 개발자가 helm repo add로 저장소를 등록하고 helm install로 설치합니다. 버전 관리도 자동으로 되고, 업데이트도 쉽습니다.
Chart 저장소가 없다면 어떻게 될까요? Chart 디렉토리를 USB나 메신저로 공유해야 합니다.
버전이 업데이트되면 또 파일을 전달해야 하죠. 누가 최신 버전을 가지고 있는지 알 수 없고, 각자 다른 버전을 사용할 위험이 있습니다.
수십 개의 Chart를 관리한다면 혼돈이 가중됩니다. 바로 이런 문제를 해결하기 위해 Chart 저장소 시스템이 제공됩니다.
Chart 저장소를 사용하면 중앙 집중식 관리가 가능합니다. 모든 Chart가 한곳에 모여 있어서 찾기 쉽고, 버전도 체계적으로 관리됩니다.
또한 접근 제어도 할 수 있습니다. 공개 저장소로 만들면 누구나 사용할 수 있고, 비공개 저장소로 만들면 팀 내부에서만 사용할 수 있습니다.
helm package 명령어는 무엇을 할까요? Chart 디렉토리를 하나의 압축 파일(.tgz)로 묶습니다.
my-microservice-1.2.3.tgz 같은 형식으로 파일이 생성됩니다. 이 파일 하나에 Chart.yaml, values.yaml, 모든 템플릿이 포함되어 있습니다.
이 파일을 저장소에 업로드하면 됩니다. helm repo index 명령어의 역할은 무엇일까요?
저장소의 모든 Chart를 스캔해서 index.yaml 파일을 생성합니다. 이 파일에는 각 Chart의 메타데이터, 버전, 다운로드 URL이 담겨 있습니다.
helm repo update를 실행하면 이 index.yaml을 다운로드해서 로컬 캐시를 업데이트합니다. 마치 apt update나 brew update와 비슷합니다.
Chart 저장소는 어떻게 호스팅할까요? 가장 간단한 방법은 정적 웹 서버를 사용하는 것입니다.
GitHub Pages, AWS S3, Nginx 등 HTTP로 파일을 제공할 수 있는 곳이면 어디든 됩니다. .tgz 파일들과 index.yaml을 업로드하기만 하면 됩니다.
인증이 필요하면 웹 서버에 Basic Auth를 설정할 수 있습니다. 실제 현업에서는 어떻게 활용할까요?
많은 기업이 내부 Chart 저장소를 운영합니다. 회사의 표준 Chart들을 저장소에 올려두면, 개발팀마다 같은 패턴으로 배포할 수 있습니다.
예를 들어 Spring Boot 애플리케이션용 표준 Chart, React 프론트엔드용 표준 Chart를 만들어서 공유합니다. 새 프로젝트를 시작할 때 저장소에서 Chart를 가져다 쓰면 됩니다.
공개 Chart 저장소도 많이 있습니다. Artifact Hub는 공개 Helm Chart들을 모아놓은 곳입니다.
MySQL, Redis, Nginx, Prometheus 같은 유명 소프트웨어의 공식 Chart를 찾을 수 있습니다. helm search hub 명령어로 검색하면 수천 개의 Chart 중에서 원하는 것을 찾을 수 있습니다.
ChartMuseum이나 Harbor 같은 전문 Chart 저장소 소프트웨어도 있습니다. ChartMuseum은 경량 Chart 저장소 서버입니다.
REST API로 Chart를 업로드하고 삭제할 수 있어서 CI/CD 파이프라인과 통합하기 좋습니다. Harbor는 Docker 레지스트리와 Chart 저장소를 함께 제공하는 엔터프라이즈급 솔루션입니다.
보안 스캔, 복제, RBAC 같은 고급 기능을 지원합니다. helm repo add로 저장소를 등록하면 어떻게 될까요?
로컬에 저장소 정보가 추가됩니다. ~/.config/helm/repositories.yaml 파일에 저장소 이름과 URL이 기록됩니다.
이제 helm install할 때 저장소이름/Chart이름 형식으로 참조할 수 있습니다. 로컬 파일 시스템 경로가 아니라 저장소에서 자동으로 다운로드합니다.
버전 관리는 어떻게 될까요? Chart.yaml의 version 필드를 올려서 패키징하면 새 버전이 됩니다.
저장소에는 여러 버전이 공존할 수 있습니다. helm install 시 --version 옵션으로 특정 버전을 지정할 수 있고, 생략하면 최신 버전이 설치됩니다.
이전 버전으로 다운그레이드하는 것도 가능합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수는 index.yaml 업데이트를 잊는 것입니다. 새 Chart를 업로드했는데 index를 재생성하지 않으면 helm repo update를 해도 보이지 않습니다.
반드시 패키징 후에 index를 업데이트해야 합니다. 또 다른 실수는 버전을 안 올리는 것입니다.
같은 버전으로 덮어쓰면 캐시 때문에 예상치 못한 동작이 발생할 수 있습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨와 함께 Chart 저장소를 구축한 김개발 씨는 뿌듯했습니다. "이제 팀원들이 helm install 한 줄로 우리 서비스를 배포할 수 있어요!" Chart 저장소를 운영하면 팀 전체의 배포 효율이 크게 향상됩니다.
표준화된 Chart를 공유하면 누구나 같은 방식으로 배포하고, 모범 사례를 자연스럽게 따르게 됩니다. 여러분도 팀 내부 Chart 저장소를 만들어서 운영해보세요.
실전 팁
💡 - GitHub Pages를 사용하면 무료로 공개 Chart 저장소를 만들 수 있습니다
- CI/CD에서 Chart를 자동으로 패키징하고 저장소에 업로드하도록 자동화하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Istio 보안 완벽 가이드
마이크로서비스 환경에서 필수적인 Istio 보안 기능을 실무 중심으로 설명합니다. mTLS부터 인증, 인가까지 단계별로 학습하여 안전한 서비스 메시를 구축할 수 있습니다.
Istio 트래픽 관리 완벽 가이드
Istio의 트래픽 관리 기능을 마스터하는 완벽 가이드입니다. VirtualService와 DestinationRule을 활용한 라우팅부터 트래픽 분할, 헤더 기반 라우팅까지 실무에 필요한 모든 내용을 다룹니다.
Istio 설치와 구성 완벽 가이드
Kubernetes 환경에서 Istio 서비스 메시를 설치하고 구성하는 방법을 초급 개발자도 쉽게 이해할 수 있도록 실무 스토리와 비유로 풀어낸 가이드입니다. istioctl 설치부터 사이드카 주입까지 단계별로 학습합니다.
서비스 메시 완벽 가이드
마이크로서비스 간 통신을 안전하고 효율적으로 관리하는 서비스 메시의 핵심 개념부터 실전 도입까지, 초급 개발자를 위한 완벽한 입문서입니다. Istio와 Linkerd 비교, 사이드카 패턴, 실무 적용 노하우를 담았습니다.
Helm 차트 기초 완벽 가이드
쿠버네티스 패키지 매니저 Helm의 기본 개념부터 차트 구조까지 실무에서 바로 활용할 수 있도록 친절하게 설명합니다. 초급 개발자도 쉽게 따라할 수 있는 실전 예제와 함께 Helm 차트의 핵심을 마스터해보세요.