본문 바로가기
CNCF/Helm

Helm Chart를 이용한 Kubernetes배포/관리

Helm 특징 

  • 복잡한 애플리케이션 배포 관리
    • Kubernetes 오케스트레이션 된 응용프로그램의 배포는 매우 복잡할 수 있다. Kubernetes 환경에서 helm 차트는 복잡한 응용프로그램의 배포를 코드로 관리하여 자동으로 배포할 수 있도록 제공한다. 응용프로그램의 빠른 배포를 통하여 다양한 테스트 환경 배포 및 운영 환경 배포 시간을 줄여 개발에 집중하도록 한다.
  •  Hooks
    • Kubernetes 환경에서 helm 차트로 설치, 업그레이드,삭제 그리고 롤백과 같은 응용프로그램 생명주기의 개입할 수 있는 기능을 Hook을 통하여 제공한다.
  • 릴리즈 관리  
    •  Helm으로 배포된 응용프로그램은 하나의 릴리즈로 불립니다. 해당 릴리즈는 배포된 응용프로그램의 버전 관리를 가능하도록 한다

Helm 기본 구성 

  • Helm Chart : Kubernetes에서 리소스를 만들기 위한 템플릿 화 된 yaml 형식의 파일
  • Helm (Chart) Repository : Helm Repository는 해당 리포지토리에 있는 모든 차트의 모든 메타데이터를 포함하는 저장소. 상황에 따라서, Public Repository를 사용하거나 내부에 Private Repository를 구성할 수 있다
  • Helm Client(cli) : 외부의 저장소에서 Chart를  가져오거나, gRPC로 Helm Server와 통신하여 요청을 하는 역할을 한다
  • Helm Server(tiller) : Helm Client의 요청을 처리하기 위하여 대기하며, 요청이 있을 경우 Kuberernetes에 Chart를 설치하고 릴리즈를 관리한다.

Helm 설치 

Helm 바이너리 파일을 다운로드하여 등록되어 있는 PATH에 이동하여 실행한다.

Client 버전은 다운로드한 버전으로 출력되는 것을 확인할 수 있다. 아직 Helm Server가 없기 때문에 아래와 같은 에러를 확인할 수 있다.

$ wget https://get.helm.sh/helm-v2.16.1-linux-amd64.tar.gz

$ tar xvzf helm-v2.16.1-linux-amd64.tar.gz

$ mv  linux-amd64/helm  /usr/local/bin/helm

$ helm version

Client: &version.Version{SemVer:"v2.16.1", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}
Error: could not find tiller


아래와 같이 RBAC 기능을 위한 매니패스트 파일을 작성한다.
Helm Server인 Tiller는 일반적으로 Kubernetes 클러스터 내부에서 실행된다. 그렇기 때문에 설치하기 위해서는 Helm Server를 위한 Role을 설정 해야한다. RBAC기능을 사용하여 Role을 설정하는 경우, 올바른 역할과 권한을 사용하여 Tiller에 대한 서비스 계정을 생성하여 리소스에 액세스 해야 한다.

$  cat rbac-config.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
  
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system

앞에서 설정한 tiller service account 를 이용하여 helm을 초기화 환다. 초기화 과정에서 kubernetes에 tiller가 배포 된다. --history-max를 지정하지 않으면 history 제한없이 증가 하기 때문에 history-max 설정하여 진행 한다.

$   helm init --service-account tiller --history-max 200
Creating /root/.helm
Creating /root/.helm/repository
Creating /root/.helm/repository/cache
Creating /root/.helm/repository/local
Creating /root/.helm/plugins
Creating /root/.helm/starters
Creating /root/.helm/cache/archive
Creating /root/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding local repo with URL: http://127.0.0.1:8879/charts
$HELM_HOME has been configured at /root/.helm.
 
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
 
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation

Helm Repository 

“helm repo “ 명령을 사용하여 Helm Repository를 관리할 수 있다. 기본적으로 아래와 같이 stabl repository와 clien의 local repository를 확인할 수 있다.

$   helm repo list
NAME    URL
stable  https://kubernetes-charts.storage.googleapis.com
local   http://127.0.0.1:8879/charts

“helm repo update” 명령을 사용하여 외부 Helm Repository에 있는 정보와 동기화 한다.

$  helm repo update
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.

“helm repo add [REPOSITORY NAME] [REPOSITORY HOST]“ 명령을 사용하여  Helm Repository를 추가할 수 있다.

$ helm repo add dev https://example.com/dev-charts
 
$  helm repo list
NAME    URL
stable  https://kubernetes-charts.storage.googleapis.com
local   http://127.0.0.1:8879/charts
dev https://example.com/dev-charts

"helm search” 명령을 이용하여  Helm Repository를 통하여 배포 가능한 Helm Chart를 검색할 수 있다.

$  helm search mariadb
NAME                    CHART VERSION   APP VERSION DESCRIPTION
bitnami/mariadb         7.0.1           10.3.20     Fast, reliable, scalable, and easy to use open-source rel...
bitnami/mariadb-cluster 1.0.1           10.2.14     Chart to create a Highly available MariaDB cluster
bitnami/mariadb-galera  0.5.2           10.3.20     MariaDB Galera is a multi-master database cluster solutio...
stable/mariadb          7.0.1           10.3.20     Fast, reliable, scalable, and easy to use open-source rel...
…

”helm install [CHART NAME]” 명령을 이용하여 Helm Repository를 통하여 Helm Chart를 배포 한다. 배포가 되면 간단한 설명과 배포된 리소스들을 확인할 수 있다.

$    helm install stable/mariadb
NAME:   wishing-garfish
LAST DEPLOYED: Tue Nov 19 17:17:21 2019
NAMESPACE: default
STATUS: DEPLOYED
 
RESOURCES:
==> v1/ConfigMap
…
To connect to your database:
 
  1. Run a pod that you can use as a client:
 
      kubectl run wishing-garfish-mariadb-client --rm --tty -i --restart='Never' --image  docker.io/bitnami/mariadb:10.3.20-debian-9-r0 --namespace default --command -- bash
 
  2. To connect to master service (read/write):
 
      mysql -h wishing-garfish-mariadb.default.svc.cluster.local -uroot -p my_database
 
  3. To connect to slave service (read-only):
 
      mysql -h wishing-garfish-mariadb-slave.default.svc.cluster.local -uroot -p my_database
 
To upgrade this helm chart:
 
  1. Obtain the password as described on the 'Administrator credentials' section and set the 'rootUser.password' parameter as shown below:
 
      ROOT_PASSWORD=$(kubectl get secret --namespace default wishing-garfish-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 --decode)
      helm upgrade wishing-garfish stable/mariadb --set rootUser.password=$ROOT_PASSWORD

”helm ls”명령을 이용하여 배포된 Release를 확인할 수 있다.

$ helm ls
NAME            REVISION    UPDATED                     STATUS      CHART               APP VERSION NAMESPACE
wishing-garfish 1           Tue Nov 19 17:17:21 2019    DEPLOYED    mariadb-7.0.1       10.3.20     default√

Helm으로 배포된 응용프로그램의 Pod를 Kubernetes에서 확인할 수 있다.

이때, Helm의 이름은 지정하지 않으면 자동 생성되며, 생성된 Helm의 이름을 기반으로 Pod의 이름이 자동 생성 된다. 만약 이름을 지정하기 위해서는 " --name [ NAME ]" 형식의 옵션을 추가 하면 된다.

$ kubectl  get pod
NAME                                         READY   STATUS              RESTARTS   AGE
wishing-garfish-mariadb-master-0             1/1     Running             0          85s
wishing-garfish-mariadb-slave-0              0/1     Running             0          86s

”helm delete [HELM RELEASE NAME] “ 명령을 사용하여 배포된 응용프로그램을 삭제 한다.

$ helm delete  wishing-garfish

release "wishing-garfish" deleted

Create Helm Chart

앞서 Helm Repository에서 있는 Chart를 이용해서 Kubernetes환경에 어플리케이션을 배포 하였다. 하지만, 직접 Chart를 만들고 Custom한 설정을 관리할 수 있다.

helm create 명령어를 사용하여 custom한 helm chart를 생성할 수 있다. 아래와 같은 트리구조로 sample chart가 생성 된다.

$ helm create test-chart
Creating test-chart
$ tree test-chart
cy-test/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

생성하면 위와 같은 트리 구조로 파일이 생성되며, 각 파일과 디렉토리의 역할은 아래와 같다.

  • charts/ :  해당 디렉토리에 종속성을 가지고 있는 helm chart를 저장 한다. 만약에 웹서비스를 실행하는 helm chart에서 설치시 mysql helm chartr가 필요하다면 별도의 dependency설정을 진행하고 해당디렉토리의 helm chart를 호출 하게된다.
  • templates/ : 실제 배포에 필요한 yaml 파일이 저장되어 있다. 각 yaml 파일은 템플릿화 되어 지정한 변수에 따라서 release를 생성할수 있도록 재사용성을 제공 하고 있다.
    • deployment.yaml : kubernetes deployment 형태로 배포되기 위해 사용 되는 yaml 파일
    • ingress.yaml: kubernetes ingress 형태로 배포되기 위해 사용 되는 yaml파일
    • service.yaml: kubernetes service 형태로 배포되기 위해 사용 되는 yaml파일 
    • NOTES.txt: 배포후 사용자에게 제공되는 사용법이나, 구조등이 설명되어 있는 txt파일로 대부분 서버스 접속 방법이나, 로그인 정보등을 추가한다.
  • values.yaml : 템플릿화 되어있는 chart의 변수(기본값)를 정의 한다.
  • Chart.yaml : Chart에 대한 정보가 포함되어 있는 yaml파일 
  • README.md : 사람이 읽을수 있는 README 파일 

 

가장 먼저 Chart.yaml파일은 해당 Helm Chart의  기본적인 정보와 이름 버전등을 기록하고 있다. 명시된 version은 helm repository에서 버전별로 관리 되고 명시 된다.

version의 형식은 Semantic Versioning 2.0.0(https://semver.org) 의 형식을 따르고 있다.

apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: test-chart
version: 0.1.0

value.yaml에는 템플릿화된 templates/ 디렉토리 하위의 yaml파일들에 대하여 변수를 정의 한다.

만약 valeue.yaml파일에 replicaCount 이라는 변수로 선언이 되어 있다면 temlates/ 하위 yaml 파일에서 "{{ .Values.replicaCount }}" 형태로 호출하여 사용할 수 있다.

...
replicaCount: 1
 
image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent
 
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
 
serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name:
...

또한, 계층적 구조를 가진 변수에 대하여 계층적으로 호출할 수 있다. 아래와 같이 선언된 변수에 대하여 호출할때는 "{{ .Values.image.repository }}" 형식으로 호출할 수 있다.

...

image:

  repository: nginx

...

templates/deployment.yaml파일에는 실제 kubernetes에 deployment로 배포되는 yaml파일들이 정의 되어 있다. 

이때, 위에서 설정한 values.yaml파일에 정의된 변수들을 호출하여 재사용성 가능하도록 템플릿화 되어 있다.

...
image:
  repository: nginx
...

Install Helm Chart

이제 생성된 Chart 를 test-chart-release이름으로 설치 하여본다.

$ helm install ./test-chart --name test-chart-release
NAME:   test-chart-release
LAST DEPLOYED: Wed Nov 20 11:33:02 2019
NAMESPACE: default
STATUS: DEPLOYED
 
RESOURCES:
==> v1/Deployment
NAME                READY  UP-TO-DATE  AVAILABLE  AGE
test-chart-release  0/1    1           0          <invalid>
 
==> v1/Pod(related)
NAME                                 READY  STATUS             RESTARTS  AGE
test-chart-release-6d87f576d4-swgjm  0/1    ContainerCreating  0         <invalid>
 
==> v1/Service
NAME                TYPE       CLUSTER-IP   EXTERNAL-IP  PORT(S)  AGE
test-chart-release  ClusterIP  10.233.4.50  <none>       80/TCP   <invalid>
 
==> v1/ServiceAccount
NAME                SECRETS  AGE
test-chart-release  1        <invalid>
 
 
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=test-chart,app.kubernetes.io/instance=test-chart-release" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

"helm ls" 명령을 사용하여 배포된 Release정보를 확인 한다. 배포에 사용된 Chart의 버전과 이름 그리고 배포된 Revision을 확인할 수있다.

$ helm ls test-chart-release
NAME                REVISION    UPDATED                     STATUS      CHART               APP VERSION NAMESPACE
test-chart-release  1           Wed Nov 20 11:33:02 2019    DEPLOYED    test-chart-0.1.0    1.0         default

Helm Upgrad / Rollback

배포된 Release의 변경사항이 있거나, 문제가 생긴 버전에 대하여 이전 버전 혹은 지정한 버전으로 돌릴수 있다.

기본적으로 배포된 pod는 1개로 values.yaml에서 replicaCount가 1로 정의 되어 있기 때문에 1개의 Pod를 확인할 수 있다.

$ kubectl  get pod | grep test-chart-release
test-chart-release-6d87f576d4-8x4gc          1/1     Running   0          4m46s

replicaCount를 2로 수정하여 다시 배포시 2개의 Pod가 실행할 수 있도록 한다.

replicaCount: 2
...

그리고 Chart의 버전을 0.1.0에서 0.2.0으로 변경하여 본다.

apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: test-chart
version: 0.2.0

이제 변경 Chart를 가지고 upgrade를 진행 하여 본다. 의도한것 처럼 Pod의 개수가 증가된것을 확인할수 있다.

$ helm upgrade test-chart-release ./test-chart
$ kubectl  get pod | grep test-chart-release
test-chart-release-6d87f576d4-8x4gc          1/1     Running   0          56s
test-chart-release-6d87f576d4-b9sq4          1/1     Running   0          29s

그리고  "helm  ls" 명령을 사용하면 변경된  Chart의  버전과  Revision이 증가된것을 볼수 있다. "helm history " 명령을 사용하면 이전  Revision 번호에 따른 정보를 확인할 수있다.

$ helm ls test-chart-release
NAME                REVISION    UPDATED                     STATUS      CHART               APP VERSION NAMESPACE
test-chart-release  2           Sat Nov 23 15:15:18 2019    DEPLOYED    test-chart-0.2.0    1.0         default
 
$ helm history test-chart-release
REVISION    UPDATED                     STATUS      CHART               APP VERSION DESCRIPTION
1           Sat Nov 23 15:14:50 2019    SUPERSEDED  test-chart-0.1.0    1.0         Install complete
2           Sat Nov 23 15:15:18 2019    DEPLOYED    test-chart-0.2.0    1.0         Upgrade complete

만약, 새로 배포된 Release에 문제가 생겨서 이전버전으로 되돌아 간다면  rollback 명령을 실행하여 돌아갈 수 있다. 최초 배포 Revision인 1로 돌아갔기 때문에  Pod의 개수가 1개로 줄어 들었다.

그리고  history 에서  rollback 을 한것도 history 상으로 확인할 수 있다.

$ helm rollback test-chart-release 1
Rollback was a success.
$  kubectl  get pod | grep test-chart-release
test-chart-release-6d87f576d4-8x4gc          1/1     Running   0          5m3s
$ helm ls test-chart-release
NAME                REVISION    UPDATED                     STATUS      CHART               APP VERSION NAMESPACE
test-chart-release  3           Sat Nov 23 15:19:21 2019    DEPLOYED    test-chart-0.1.0    1.0         default
$ helm history test-chart-release
REVISION    UPDATED                     STATUS      CHART               APP VERSION DESCRIPTION
1           Sat Nov 23 15:14:50 2019    SUPERSEDED  test-chart-0.1.0    1.0         Install complete
2           Sat Nov 23 15:15:18 2019    SUPERSEDED  test-chart-0.2.0    1.0         Upgrade complete
3           Sat Nov 23 15:19:21 2019    DEPLOYED    test-chart-0.1.0    1.0         Rollback to 1

Chartmuseum을 이용한 Private Helm Chart Repository 

Chartmuseum은 다양한 플랫폼에서 제공되는 Helm Chart Repository로 쉽게 설치 조작이 가능하다.(https://chartmuseum.com)

간단하게 Docker Container를 이용하여 실행시킬 수 있다. 기본적으로 8080포트로 Listening되어 있다. 그리고, Chart가 실제로 저장될 Persistent Volumes Directory로 "/data" 디렉토리를 생성하여 사용한다.

$ mkdir -p /data/charts
$ chown 1000:1000 /data/charts
$ docker run -d -it  \
  --net host \
  -v  /data/charts:/charts \
  -e STORAGE=local \
  -e STORAGE_LOCAL_ROOTDIR=/charts \
  --name chartmuseum \
  docker.io/chartmuseum/chartmuseum

브라우저를 통하여 확인하면 메인 화면을 볼수 있다.(사실 별다른 것은 없다.)

차트의 정보는 api를 통하여 확인할 수 있다. 아래와 같이 처음에는 등록한 Chart가 없기 때문에 정보를 확인할 수 없다.

$ curl http://localhost:8080/api/charts
{}

간단하게  " test-chartmuseum" 이름의  Chart를 생성한다.

$ helm create test-chartmuseum
Creating test-chartmuseum

생성된 Helm Chart는 실제 Repository에는 gzip으로 Package된 형태로 저장된다. "helm package [ PACKAGE DIRECTORY]"  명령어를 사용 하여 Package한다. 

$ helm package  test-chartmuseum
Successfully packaged chart and saved it to: /root/cyyoon/test-chartmuseum-0.1.0.tgz
$ ls -al /root/cyyoon/test-chartmuseum-0.1.0.tgz
-rw-r--r-- 1 root root 3266 Nov 23 15:38 /root/cyyoon/test-chartmuseum-0.1.0.tgz

이제,curl 명령어를 이용하여 Package되어 있는 Chart Package를 Chartmuseum에 등록하여 보고, 다시 API를 호출하여 등록된  Chart를 확인할 수 있다.

API응답시 JSON으로 출력되기 때문에 Linux에서  JSON processor 인 jq를 설치 하여 list출력시 나오는 json을 좀더 깔끔하게 확인할 수 있다.

$ curl --data-binary "@test-chartmuseum-0.1.0.tgz" http://localhost:8080/api/charts
{"saved":true}
 
$ curl -s  http://localhost:8080/api/charts
{"test-chartmuseum":[{"name":"test-chartmuseum","version":"0.1.0","description":"A Helm chart for Kubernetes","apiVersion":"v1","appVersion":"1.0","urls":["charts/test-chartmuseum-0.1.0.tgz"],"created":"2019-11-23T08:47:41.733908808Z","digest":"52bc041c952e8dc7105cec8bab4acd0509a4c43bb995f1c18312b8308866b81b"}]}
 
$ yum install -y jq
 
$ curl -s  http://localhost:8080/api/charts | jq
{
  "test-chartmuseum": [
    {
      "name": "test-chartmuseum",
      "version": "0.1.0",
      "description": "A Helm chart for Kubernetes",
      "apiVersion": "v1",
      "appVersion": "1.0",
      "urls": [
        "charts/test-chartmuseum-0.1.0.tgz"
      ],
      "created": "2019-11-23T08:47:41.733908808Z",
      "digest": "52bc041c952e8dc7105cec8bab4acd0509a4c43bb995f1c18312b8308866b81b"
    }
  ]
}

Docker Container를 실행할때 지정 하였던 Persistent Volumes Directory를 확인 하면 아래와 같이 Package되어 있는 Chart가 저장된것을 확인할 수 있다.

$  ls -al /data/charts
total 8
drwxr-xr-x 2 centos centos   64 Nov 23 17:48 .
drwxr-xr-x 3 centos centos   54 Nov 23 17:44 ..
-rw-r--r-- 1 centos centos  398 Nov 23 17:48 index-cache.yaml
-rw-r--r-- 1 centos centos 3266 Nov 23 17:47 test-chartmuseum-0.1.0.tgz

Helm Client에 앞서 생성한 Chartmuseum 으로 Repository를 등록한다.

$ helm repo add chartmuseum http://localhost:8080/
"chartmuseum" has been added to your repositories
$ helm repo list
NAME        URL
stable      https://kubernetes-charts.storage.googleapis.com
local       http://127.0.0.1:8879/charts
chartmuseum http://localhost:8080/

Helm Chart Repository에 검색을 하면 등록된 Chart를 확인할 수 있으며, 설치도 Local환경에서 진행한것과 동일하게 진행된다.

$ helm search test-chartmuseum
NAME                            CHART VERSION   APP VERSION DESCRIPTION
chartmuseum/test-chartmuseum    0.1.0           1.0         A Helm chart for Kubernetes
 
$ helm install chartmuseum/test-chartmuseum --name test-chartmuseum-release
 
$ helm ls test-chartmuseum-release
NAME                        REVISION    UPDATED                     STATUS      CHART                   APP VERSION NAMESPACE
test-chartmuseum-release    1           Sat Nov 23 17:58:49 2019    DEPLOYED    test-chartmuseum-0.1.0  1.0         default

 

Ref

https://bcho.tistory.com/1335

https://helm.sh/docs/

https://arisu1000.tistory.com/27860

https://sktelecom-oslab.github.io/Virtualization-Software-Lab/Helm/

반응형