인프라/Docker&Kubernetes 2019. 11. 22. 00:01

 

보통 쿠버네티스를 사용하면 단일 클러스터 환경에서 운영하지 않는다. 보통 Phase 별로 클러스터를 구성하기도 하고, 각 Phase의 클러스터는 하나 이상의 노드를 갖는 클러스터 형태인 경우가 많다. 또한 쿠버네티스를 사용하면 하나의 애플리케이션 혹은 미들웨어를 디플로이먼트나 서비스, 컨피그맵 혹은 인그레스 등 여러 종류의 리소스를 조합하는 형태로 배포한다.

 

그런데 각 Phase마다 배포시 달라지는 정보들이 많다. 예를 들면 개발환경의 데이터베이스 주소와 프로덕환경의 데이터베이스 주소가 다른것처럼 말이다. 그렇다면 모든 환경마다 매니페스트를 작성해야하나? 만약 Phase가 많다면 관리가 쉽지 않을 것이다. 이렇게 배포 환경에 따라 달라지는 설정값만 정의해 둔 다음 이에 따라 배포하는 메커니즘이 필요하게 되었는데, 이런 문제를 해결한 것이 헬름(Helm)이다.

 

Helm is a tool for managing Kubernetes charts. Charts are packages of pre-configured Kubernetes resources.
헬름은 쿠버네티스 차트를 관리하기 위한 도구이다. 차트는 사전 구성된 쿠버네티스 리소스의 패키지다.

 

헬름은 패키지 관리 도구고, 차트가 리소스를 하나로 묶은 패키지에 해당한다. 헬름으로 차트를 관리하는 목적은 자칫 번잡해지기 쉬운 매니페스트 파일을 관리하기 쉽게 하기 위한 것이다.

 

실무에서는 로컬 및 운영 클러스터를 막론하고 여러 환경에 배포해야 하는 애플리케이션은 모두 차트로 패키징해 kubectl 대신 헬름으로 배포 및 업데이트를 수행한다. 그 대신 이미 배포된 리소스에 대해 kubectl로 수정한다.

 

헬름설치
> curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > get_helm.sh
> chmod 700 get_helm.sh
> ./get_helm.sh

 

필요한 것을 다운로드 받는다.

 

> helm init
Creating /Users/yun-yeoseong/.helm 
Creating /Users/yun-yeoseong/.helm/repository 
Creating /Users/yun-yeoseong/.helm/repository/cache 
Creating /Users/yun-yeoseong/.helm/repository/local 
Creating /Users/yun-yeoseong/.helm/plugins 
Creating /Users/yun-yeoseong/.helm/starters 
Creating /Users/yun-yeoseong/.helm/cache/archive 
Creating /Users/yun-yeoseong/.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 /Users/yun-yeoseong/.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



> kubectl get service,deployment,pod -n kube-system
NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)     AGE
service/tiller-deploy   ClusterIP   10.96.113.96   <none>        44134/TCP   39s

NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/tiller-deploy   1/1     1            1           39s

NAME                                READY   STATUS    RESTARTS   AGE
pod/tiller-deploy-dc4f6cccd-zgvhp   1/1     Running   0          39s

 

여기까지 잘 따라왔다면 설치는 완료된 것이다. 실제로 helm init 명령을 실행하면 틸러라는 서버 애플리케이션이 kube-system 네임스페이스에 배포되고, 틸러는 helm 명령에 따라 설치 등의 작업을 담당하게 된다.

 

현재 사용하고 있는 헬름 버전이 낮다면 아래 명령으로 업그레이드하면 된다.

 

> helm version
> helm init --upgrade //최신버전으로 업그레이드

//특정 버전 헬름 사용
> export TLLER_TAG=2.9.0
> kubectl --namespace=kube-system set image deployments/tiller-deploy tiller=gcr.io/kubernetes-helm/tiller:$TILLER_TAG

 

헬름의 주요 개념

 

헬름은 클라이언트(cli)와 서버(쿠버네티스 클러스터에 설치되는 틸러)로 구성된다. 클라이언트는 서버를 대상으로 명령을 지시하는 역할을 한다. 서버는 클라이언트에서 전달받은 명령에 따라 쿠버네티스 클러스터에 패키지 설치, 업데이트, 삭제 등의 작업을 수행한다.

 

쿠버네티스는 서비스나 디플로이먼트, 인그레스 같은 리소스를 생성하고 매니페스트 파일을 적용하는 방식으로 애플리케이션을 배포한다. 이 매니페스트 파일을 생성하는 템플릿을 여러 개 패키징한 것이 차트다. 차트는 헬름 리포지토리에 tgz 파일로 저장되며, 틸러가 매니페스트를 생성하는 데 사용한다.

 

리포지토리
종류 내용
local 헬름 클라이언트가 설치된 로컬 리포지토리로, 로컬에서 생성한 패키지가 존재한다.
stable 안정 버전에 이른 차트가 존재하는 리포지토리다. 안정된 보안 수준과 기본 설정값을 포함하는 등 일정한 요건을 만족하는 차트만 제공될 수 있다.
incubator stable 요건을 만족하지 못하는 차트가 제공되는 리포지토리다. stable로 넘어갈 예정인 차트가 제공된다.

 

stable 리포지토리는 기본값으로 사용되는 리포지토리로, 깃헙 helm/charts 리포지토리에 저장된 차트를 사용할 수 있다. incubator 리포지토리는 기본값으로 사용되지는 않으나, 다음과 같이 리포지토리를 추가할 수 있다.

 

> helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/

 

리포지토리에서 다음과 같이 차트를 검색할 수 있다. helm search 명령에 지정한 키워드로 검색도 가능하다.

 

> helm search

 

차트의 구성

차트는 다음과 같은 디렉터리 구성을 갖는다.

 

chart_name
->templates
  ->xxxxx.yaml 각종 쿠버네티스 리소스의 매니페스트 템플릿
  ->_helper.tpl 매니페스트 랜더링에 사용되는 템플릿 헬퍼
  ->NOTE.txt 차트 사용법 등의 참조 문서 템플릿
  ->charts/ 이 차트가 의존하는 차트의 디렉터리
  ->Chart.yaml 차트 정보가 정의된 파일
  ->values.yaml 차트 기본값 value 파일
			

 

차트 설치하기

차트를 이용해 애플리케이션을 설치하려면 helm install 명령을 사용한다. 설치했던 애플리케이션을 업데이트하거나 삭제하려면 릴리스 네임이 필요하므로 --name 옵션으로 릴리스 네임을 붙여준다. 이 릴리스 네임은 해당 클러스터 안에서 유일한 값이어야 한다.

 

> helm install [--name 릴리스_네임] 차트_리포지토리/차트명

 

helm install 명령을 실행하면 차트에 포함된 기본값 value 파일에 정의된 설정값으로 애플리케이션이 설치된다. 그러나 기본값 value 파일을 있는 그대로 사용하는 경우는 드물며, 일부 기본값을 수정한 커스터 value 파일을 주로 사용한다. helm install 예제로 프로젝트 관리 도구인 레드마인의 차트를 이용한다.

 

예제에서는 사용하지 않을 명령 이것은 기본값을 사용하는 일반적인 설치법이다.

> helm install --name redmine-exam stable/redmine
NAME:   redmine-exam
LAST DEPLOYED: Sun Nov 24 17:54:39 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                        AGE
redmine-exam-mariadb        0s
redmine-exam-mariadb-tests  0s

==> v1/Deployment
NAME          AGE
redmine-exam  0s

==> v1/PersistentVolumeClaim
NAME          AGE
redmine-exam  0s

==> v1/Pod(related)
NAME                           AGE
redmine-exam-748d45d8f8-8js7k  0s
redmine-exam-mariadb-0         0s

==> v1/Secret
NAME                  AGE
redmine-exam          0s
redmine-exam-mariadb  0s

==> v1/Service
NAME                  AGE
redmine-exam          0s
redmine-exam-mariadb  0s

==> v1/StatefulSet
NAME                  AGE
redmine-exam-mariadb  0s


NOTES:


1. Get the Redmine URL:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace default -w redmine-exam'


  export SERVICE_IP=$(kubectl get svc --namespace default redmine-exam --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
  echo "Redmine URL: http://$SERVICE_IP/"

2. Login with the following credentials

  echo Username: user
  echo Password: $(kubectl get secret --namespace default redmine-exam -o jsonpath="{.data.redmine-password}" | base64 --decode)

 

레드마인 로그인 사용자명과 패스워드를 새로 설정하는 예제를 수행할 것이다. 문서에 규정된 설정값을 따라 커스텀 value 파일을 작성한다. 그리고 다음과 같이 인증정보 설정을 담은 redmine.yaml 파일을 작성한다. 또 인그레스 대신 NodePort 서비스를 사용해 서비스를 노출할 것이므로 serviceType 필드의 값을 NodePort로 수정한다.

 

#redmine.yaml
redmineUsername: yeoseong_gae
redminePassword: yeoseong_gae
redmineLanguage: ja

serviceType: NodePort

 

위 파일을 작성해준다.

 

helm install -f redmine.yaml --name redmine-sample stable/redmine --version 4.0.0
NAME:   redmine-sample
LAST DEPLOYED: Sun Nov 24 18:01:42 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                          AGE
redmine-sample-mariadb        1s
redmine-sample-mariadb-tests  1s

==> v1/PersistentVolumeClaim
NAME                    AGE
redmine-sample-redmine  1s

==> v1/Pod(related)
NAME                                     AGE
redmine-sample-mariadb-0                 1s
redmine-sample-redmine-769df7c8b5-wdgx9  1s

==> v1/Secret
NAME                    AGE
redmine-sample-mariadb  1s
redmine-sample-redmine  1s

==> v1/Service
NAME                    AGE
redmine-sample-mariadb  1s
redmine-sample-redmine  1s

==> v1beta1/Deployment
NAME                    AGE
redmine-sample-redmine  1s

==> v1beta1/StatefulSet
NAME                    AGE
redmine-sample-mariadb  1s


NOTES:
1. Get the Redmine URL:

  export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services redmine-sample-redmine)
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT/

2. Login with the following credentials

  echo Username: yeoseong_gae
  echo Password: $(kubectl get secret --namespace default redmine-sample-redmine -o jsonpath="{.data.redmine-password}" | base64 --decode)

 

위와 같이 작성한 redmine.yaml 파일을 인자로 포함시켜 레드만을 차트를 설치하였다. 설치가 끝나면 다음과 같이 릴리스 네임의 목록을 확인할 수 있다.

 

> helm ls
NAME          	REVISION	UPDATED                 	STATUS  	CHART        	APP VERSION	NAMESPACE
redmine-sample	1       	Sun Nov 24 18:01:42 2019	DEPLOYED	redmine-4.0.0	3.4.6      	default

 

레드마인 리소스가 생성됐는지 확인한다.

 

> kubectl get service,deployment --selector release=redmine-sample
NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/redmine-sample-mariadb   ClusterIP   10.99.90.57    <none>        3306/TCP       3m1s
service/redmine-sample-redmine   NodePort    10.96.215.91   <none>        80:30441/TCP   3m1s

NAME                                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/redmine-sample-redmine   0/1     1            0           3m1s

 

노출하려는 서비스 redmine-sample-redmine이 차트의 기본값 value 파일의 내용대로 LoadBalancer가 아닌 NodePort로 생성되었다. NodePortsms 30441 포트를 개방하고 있으므로 웹브라우저에서 바로 접근가능하다. 그리고 우리가 파일에 작성한 로그인정보로 로그인이 가능하다.

 

헬름으로 설치된 릴리스를 업데이트하려면 다음과 같이 helm upgrade 명령을 사용한다.

 

> helm upgrade -f redmine.yaml redmine stable/redmine --version 4.0.0

 

차트로 설치한 애플리케이션을 제거하고 싶다면 아래 명령을 이용한다,

 

> helm delete 릴리스_네임

 

애플리케이션을 제거해도 헬름에는 롤백 기능이 있기 때문에 원하는 리비전으로 돌아갈 수 있다.

 

> helm ls --all
NAME          	REVISION	UPDATED                 	STATUS  	CHART         	APP VERSION	NAMESPACE
redmine-exam  	1       	Sun Nov 24 17:54:39 2019	DELETED 	redmine-13.5.0	4.0.5      	default

> helm rollback redmine-exam 1

 

만약 리비전 기록을 남기지 않고 애플리케이션을 완전히 제거하려면 다음과 같이 한다.

 

> helm del --purge redmine(릴리즈_네임)

 

사용자 차트 생성하기

사용자 차트를 만들고 이 차트를 사용해 애플리케이션을 설치해본다. 쿠버네티스에서 동작하는 대부분의 애플리케이션은 서비스나 인그레스, 디플로이먼트 같은 쿠버네티스 리소스로 구성된다. 차트는 이 구성을 추상화하고 패키징해 배포하기 위한 것으로, 매니페스트 파일을 복사해 하나 이상의 환경에 배포하는 방식보다 유지 보수성이 좋다.

 

로컬 리포지토리 활성화하기

밑의 명령으로 헬름에서 사용할 수 있는 리포지토리를 확인할 수 있다. 기본 원격 리포지토리와 로컬 리포지토리 정보가 출력될 것이며, 로컬 리포지토리는 헬름이 실행되는 호스트 머신에 위치한다.

 

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

 

하지만 이 로컬 리포지토리는 바로 사용할 수 없다. 이 URL에 http 프로토콜로 접근할 수 있어야 우리가 만든 차트를 사용할 수 있으므로 이 웹서버를 실행한다. 로컬 리포지토리에 항상 접근할 수 있도록 서버를 백그라운드로 실행한다.

 

> helm serve &

 

해당 URL을 접근해보면 "Helm Chart Repository"라는 문구가 보일 것이다.

 

차트 템플릿 작성하기

차트를 생성하려면 먼저 차트의 디렉터리 구조를 만들어야 한다. 헬름에 이 템플릿을 만들어주는 기능이 있다.

 

> helm create springboot-web
Creating springboot-web

 

명령 수행후에 명령을 수행한 디렉토리에 밑의 디렉토리 및 파일들이 생성된다.

 

 

posted by 여성게
: