Ssoon

Helm : 5.6 Deploying a Chart with a Dependency 본문

CICD Study [1기]

Helm : 5.6 Deploying a Chart with a Dependency

구구달스 2025. 10. 19. 14:44

 

🎵 Helm Chart로 Dependency 포함 서비스 배포하기 (Deploying a Chart with a Dependency)

  • Helm을 사용하다 보면 단순한 서비스만 배포하는 경우보다는, Database나 Cache, Mail Server 등 다른 서비스에 의존하는 Application을 함께 배포해야 하는 경우가 많습니다.
  • Helm Chart의 dependencies 기능을 활용해, Java 기반의 Music Service와 PostgreSQL Database를 함께 배포하는 방법


🧱 1. 프로젝트 구조 만들기

  • 먼저 music이라는 새로운 Chart 디렉터리를 생성합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ mkdir music
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ mkdir music/templates
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ cd music
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$
  • 이 music Chart는 Java Music Service를 Kubernetes 클러스터에 배포하는 역할을 합니다.
  • 이제 서비스 배포에 필요한 Deployment와 Service 템플릿 파일을 만들어보겠습니다.

"Helm Chart는 templates 폴더 내의 YAML 파일들을 통해 Kubernetes 리소스를 정의합니다."


🚀 2. Deployment 템플릿 작성하기

  • templates/deployment.yaml 파일을 생성하고 아래 내용을 입력합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ 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 }}
              name: http
              protocol: TCP
          env:
            - name: QUARKUS_DATASOURCE_JDBC_URL
              value: {{ .Values.postgresql.server | default (printf "%s-postgresql" ( .Release.Name )) | quote }}
            - name: QUARKUS_DATASOURCE_USERNAME
              value: {{ .Values.postgresql.postgresqlUsername | default (printf "postgres" ) | quote }}
            - name: QUARKUS_DATASOURCE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: {{ .Values.postgresql.secretName | default (printf "%s-postgresql" ( .Release.Name )) | quote }}
                  key: {{ .Values.postgresql.secretKey }}
EOF
  • 이 Deployment는 환경 변수를 통해 PostgreSQL의 연결 정보를 주입받습니다.
    즉, Helm Values 파일 또는 CLI 설정을 통해 PostgreSQL 정보를 전달할 수 있습니다.

"Deployment 템플릿에서는 PostgreSQL과 연결하기 위한 JDBC URL, 사용자명, 비밀번호를 환경 변수로 설정합니다."


🌐 3. Service 템플릿 작성하기

  • 다음으로 templates/service.yaml 파일을 생성합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ 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는 Music Application의 외부 접근 포트를 노출합니다.
    containerPort는 Values.yaml에서 정의한 포트 번호를 참조합니다.

"Service 템플릿은 Deployment의 Pod와 연결되어 클러스터 내부에서 트래픽을 라우팅합니다."


📄 4. Chart.yaml – 의존성(Dependency) 정의하기

  • 이제 Chart.yaml을 작성하여 PostgreSQL Chart를 Dependency로 추가합니다.
  • 책버전으로는 되지 않습니다. 최신버전으로 설치합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ cat << EOF > Chart.yaml
apiVersion: v2
name: music
description: A Helm chart for Music service
type: application
version: 0.1.0
appVersion: "1.0.0"
dependencies:
  - name: postgresql
    version: 18.0.17 # book 10.16.2
    repository: "https://charts.bitnami.com/bitnami"
EOF
  • 여기서 중요한 포인트는 dependencies 섹션입니다.
    이 항목을 통해 bitnami/postgresql Chart를 자동으로 가져오고 함께 배포할 수 있습니다.

"Chart.yaml의 dependencies 섹션은 다른 Helm Chart를 함께 설치할 수 있도록 정의하는 핵심 부분입니다."


⚙️ 5. Values.yaml – 기본 설정값 정의하기

  • 이제 Values.yaml 파일을 작성합니다.
    Music 서비스와 PostgreSQL 인스턴스 설정을 함께 포함합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ cat << EOF > values.yaml
image:
  repository: quay.io/gitops-cookbook/music
  tag: "1.0.0"
  pullPolicy: Always
  containerPort: 8080

replicaCount: 1

postgresql:
  server: jdbc:postgresql://music-db-postgresql:5432/mydb
  postgresqlUsername: my-default
  postgresqlPassword: postgres
  postgresqlDatabase: mydb
  secretName: music-db-postgresql
  secretKey: postgresql-password
EOF

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ tree
.
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   └── service.yaml
└── values.yaml

2 directories, 4 files
  • 이 설정을 통해 Music 서비스는 PostgreSQL과 연결할 수 있으며,
    PostgreSQL의 비밀번호나 사용자명은 Helm 설치 시 --set 옵션으로 재정의할 수 있습니다.

"Values.yaml은 Helm Chart의 설정값을 모아둔 파일로, 환경에 맞게 유연하게 오버라이드할 수 있습니다."


🔄 6. Dependency Chart 다운로드

  • 모든 파일 구성이 끝났다면, PostgreSQL Chart를 charts 디렉터리에 자동으로 다운로드합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ helm dependency update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading postgresql from repo https://charts.bitnami.com/bitnami
Pulled: registry-1.docker.io/bitnamicharts/postgresql:18.0.17
Digest: sha256:84b63af46f41ac35e3cbcf098e8cf124211c250807cfed43f7983c39c6e30b72
Deleting outdated charts
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ tree
.
├── Chart.lock
├── Chart.yaml
├── charts
│   └── postgresql-18.0.17.tgz
├── templates
│   ├── deployment.yaml
│   └── service.yaml
└── values.yaml

3 directories, 6 files

"Helm dependency update 명령은 정의된 Chart들을 자동으로 다운로드하여 charts 폴더에 저장합니다."


🚢 7. Chart 배포하기 (Deploy)

  • 이제 Helm Chart를 클러스터에 설치합니다.
  • PostgreSQL의 비밀번호와 Database 이름을 직접 지정하면서 설치합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ helm install music-db .
NAME: music-db
LAST DEPLOYED: Sat Oct 25 15:37:51 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

 


(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ kubectl edit secret music-db-postgresql
apiVersion: v1
data:
...
  postgresql-password: cG9zdGdyZXMK
kind: Secret
...


(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ kubectl logs -l app.kubernetes.io/name=music -f
__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2025-10-25 06:44:44,215 WARN  [io.agr.pool] (agroal-11) Datasource '<default>': Something unusual has occurred to cause the driver to fail. Please report this exception.
2025-10-25 06:44:44,235 WARN  [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: <default>) HHH000342: Could not obtain connection to query metadata: org.postgresql.util.PSQLException: Something unusual has occurred to cause the driver to fail. Please report this exception.
        at org.postgresql.Driver.connect(Driver.java:286)
        at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:210)
        at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:513)
        at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:494)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:75)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1126)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalArgumentException: Prohibited character

        at org.postgresql.shaded.com.ongres.saslprep.SaslPrep.saslPrep(SaslPrep.java:105)
        at org.postgresql.shaded.com.ongres.scram.common.stringprep.StringPreparations$2.doNormalize(StringPreparations.java:55)

🔍 8. 리소스 확인하기

  • 배포된 리소스를 확인합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ kubectl get sts,pod,svc,ep,secret,pv,pvc
NAME                                   READY   AGE
statefulset.apps/music-db-postgresql   1/1     10m
statefulset.apps/my-db-postgresql      1/1     33m

NAME                          READY   STATUS      RESTARTS      AGE
pod/music-6c45d566f4-kzrl7    1/1     Running     5 (93s ago)   10m
pod/music-db-postgresql-0     1/1     Running     0             10m
pod/my-db-postgresql-0        1/1     Running     0             33m
pod/my-db-postgresql-client   0/1     Completed   0             33m
pod/pacman-576769bb86-w2vsc   1/1     Running     1 (79m ago)   3d16h

NAME                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/kubernetes               ClusterIP   10.96.0.1       <none>        443/TCP    3d17h
service/music                    ClusterIP   10.96.149.81    <none>        8080/TCP   10m
service/music-db-postgresql      ClusterIP   10.96.233.90    <none>        5432/TCP   10m
service/music-db-postgresql-hl   ClusterIP   None            <none>        5432/TCP   10m
service/my-db-postgresql         ClusterIP   10.96.217.49    <none>        5432/TCP   33m
service/my-db-postgresql-hl      ClusterIP   None            <none>        5432/TCP   33m
service/pacman                   ClusterIP   10.96.156.153   <none>        8080/TCP   3d16h

NAME                               ENDPOINTS          AGE
endpoints/kubernetes               172.19.0.2:6443    3d17h
endpoints/music                    10.244.0.33:8080   10m
endpoints/music-db-postgresql      10.244.0.35:5432   10m
endpoints/music-db-postgresql-hl   10.244.0.35:5432   10m
endpoints/my-db-postgresql         10.244.0.30:5432   33m
endpoints/my-db-postgresql-hl      10.244.0.30:5432   33m
endpoints/pacman                   10.244.0.5:8080    3d16h

NAME                                    TYPE                 DATA   AGE
secret/music-db-postgresql              Opaque               2      10m
secret/my-db-postgresql                 Opaque               2      33m
secret/sh.helm.release.v1.music-db.v1   helm.sh/release.v1   1      10m
secret/sh.helm.release.v1.my-db.v1      helm.sh/release.v1   1      33m

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
persistentvolume/pvc-5094fee3-ccc2-47bd-b093-4e71d4316f71   8Gi        RWO            Delete           Bound    default/data-my-db-postgresql-0      standard       <unset>                          72m
persistentvolume/pvc-57cdd440-8ae5-4684-a8b5-1ddffbb2c160   8Gi        RWO            Delete           Bound    default/data-music-db-postgresql-0   standard       <unset>                          10m

NAME                                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
persistentvolumeclaim/data-music-db-postgresql-0   Bound    pvc-57cdd440-8ae5-4684-a8b5-1ddffbb2c160   8Gi        RWO            standard       <unset>                 10m
persistentvolumeclaim/data-my-db-postgresql-0      Bound    pvc-5094fee3-ccc2-47bd-b093-4e71d4316f71   8Gi        RWO            standard       <unset>                 72m

"모든 리소스가 정상적으로 Running 상태라면 Chart 배포가 성공적으로 완료된 것입니다."


🌍 9. Service 접근하기 (Port Forwarding)

  • 로컬 환경에서 Music 서비스를 테스트하기 위해 port-forward 명령을 사용합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/music$ kubectl port-forward service/music 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

 

 


🎧 10. 서비스 검증하기 (API 호출)

  • 다른 터미널에서 다음 명령을 실행합니다.
curl localhost:8080/song

결과:

[
  { "id": 1, "artist": "DT", "name": "Quiero Munchies" },
  { "id": 2, "artist": "Lin-Manuel Miranda", "name": "We Don't Talk About Bruno" },
  { "id": 3, "artist": "Imagination", "name": "Just An Illusion" },
  { "id": 4, "artist": "Txarango", "name": "Tanca Els Ulls" },
  { "id": 5, "artist": "Halsey", "name": "Could Have Been Me" }
]
  • 서비스가 정상적으로 PostgreSQL과 연동되어 데이터를 반환하고 있음을 확인할 수 있습니다.

"Helm Chart를 통해 애플리케이션과 Database를 함께 배포하면, 서비스 간 의존성을 자동으로 관리할 수 있습니다."


📘 Figure: Music Application Overview

Music Application 구조

Java 기반 Music Service

PostgreSQL Database 의존성

Helm Chart의 Dependency 기능을 통해 통합 배포


📌 핵심 요약

  • Helm의 dependencies 기능을 사용하면 다른 Chart(PostgreSQL 등) 를 함께 설치할 수 있습니다.
  • Chart.yaml에 dependencies를 정의하고 helm dependency update로 Chart를 다운로드합니다.
  • Deployment 템플릿에서 Database 정보를 환경 변수로 설정해 연결을 구성합니다.
  • Values.yaml을 통해 기본 설정값을 관리하고 CLI에서 쉽게 오버라이드할 수 있습니다.
  • helm install 명령으로 모든 구성요소가 함께 배포됩니다.
  • kubectl port-forward로 로컬에서 서비스 접근을 테스트할 수 있습니다.

"Helm Chart의 Dependency 기능은 복잡한 멀티 서비스 배포를
단일 명령으로 관리할 수 있게 해주는 강력한 도구입니다."

Comments