블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

쿠버네티스 패키지 매니저 Helm

#2-5 Helm Chart 배포

조대협 (http://bcho.tistory.com)


Helm 차트를 작성했으면, 다른 사용자들이 사용하기 쉽게 차트를 차트 리포지토리 (Chart repository)에 배포할 수 있다. 

Helm 파일 패키징

파일을 배포하기 위해서는 먼저 차트 파일들을 *.tgz 파일 형태로 패키징해야 하는데, helm package 명령을 사용하면 된다. 

%helm package [차트 디렉토리] 

형태로 사용하면 된다. 앞의 예제인 helloworld 차트를 패키징 하려면 아래와 같은 명령을 사용하면 된다.

%helm package ./helloworld

Successfully packaged chart and saved it to: /home/terrychol/31.helm/helloworld-0.1.0.tgz


만약에 패키지된 파일에 대한 무결성을 보장하기 위해서(패키지된 파일이 변조되지 않음을 보장하는 방법) 패키지파일에 키로 사이닝을 하는 방법이 있다. helm package --sign … 옵션을 이용해서 사이닝을 한다. 패키지에 사이닝을 하면 *.prov 파일 (provenance file) 이 생성되고, 차트 패키지를 설치할때 helm install --verify 옵션을 이용하면 이 provenance 파일을 이용해서 파캐지의 무결성 (변조가 되었는지)을 확인한 후, 변조되지 않은 경우에만 설치를 한다. 

원리 자체는 PKI(비대칭키) 알고리즘을 이용해서 패키지에 사이닝 한후에, 차트를 인스톨할때 사이닝을 확인하여 패키지 변조 여부를 파악하는 방식이다. 

자세한 설정 방법은  https://helm.sh/docs/developing_charts/#helm-provenance-and-integrity

문서를 참고하기 바란다. 

Helm Chart repository server

패키징된 차트패키지 파일을 서버에 배포해야하는데, 서버는 일반적은 HTTP 서버면 모두 사용이 가능하다. github,일반 웹서버, AWS S3, Google Cloud Storage(aka GCS)등이 모두 가능한데, 디렉토리 구조면 repository server 구조에 맞춰서 저장해놓으면 된다.


리포지토리 서버의 디렉토리 구조는 다음과 같다.


charts/

  

  |- index.yaml

  

  |- alpine-0.1.2.tgz

  

  |- alpine-0.1.2.tgz.prov


  • *.tgz 파일은 차트 패키지 파일이고

  • *.prov 파일은 차트 패키지에 대한 provenance 파일이다.

  • 그리고 index.yaml에 리파지토리에 있는 패키지들에 대한 정보를 저장한다.


아래는 index.yaml 파일 샘플이다.


apiVersion: v1

entries:

  helloworld:

  - apiVersion: v1

    appVersion: "1.0"

    created: 2019-06-19T15:37:08.158097657+09:00

    description: A Helm chart for Kubernetes

    digest: f7fcd1078546939bd04b4f94282fb15b3d8d4c422e61b5b03b7e4061c1b61037

    name: helloworld

    urls:

    - http://127.0.0.1:8879/helloworld-0.1.0.tgz

    version: 0.1.0

  helloworld2:

  - apiVersion: v1

    appVersion: "1.0"

    created: 2019-06-19T15:37:08.158803299+09:00

    description: A Helm chart for Kubernetes

    digest: 69510159a58a1c5c228b6870546b67d852b09d299b36d4617bf9e9b971be01fd

    name: helloworld2

    urls:

    - http://127.0.0.1:8879/helloworld2-0.1.0.tgz

    version: 0.1.0

generated: 2019-06-19T15:37:08.15656402+09:00


helloworld와 helloworld2 가 포함되어 있고, 패키지 URL은 http://127.0.0.1:8879/ 이다.

간단하게 Helm 차트 리파지토리를 띄우는 방법은 패키지 (*.tgz)이 있는 디렉토리에서 helm serve 명령을 이용하면 디폴트로 현재 디렉토리에 있는 패키지들을 이용하여 index.yaml 파일을 자동으로 생성하고, 이를 8879 포트를 이용해서 서빙한다.

아래는 helm serve 명령을 이용해서 현재 디렉토리 “.”를 패키지 디렉토리로 해서 차트 리파지토리 서버를 기동한 결과이다.


%helm serve --repo-path .

Regenerating index. This may take a moment.

Now serving you on 127.0.0.1:8879



위의 명령을 사용하면 자동으로 현재 디렉토리에 있는 패키지 파일 (*.tgz)을 읽어서 index.yaml을 자동으로 생성해서 repository 서비스를 제공한다.

helm serve를 이용하는 것이 아니라 웹서버등을 이용할 경우에는 index.yaml을 별도로 생성해줘야 하는데, helm repo index 라는 명령을 이용하면 된다.


%helm repo index [디렉토리명]


을 실행하면, [디렉토리명]에 있는 helm 패키지 파일들에 대한 index.yaml을 생성한다. 이때 웹서버의 URL을 정해줄 수 있는데, 


%helm repo index [디렉토리명] --url [http or https URL for repository]


--url 옵션으로 웹서버의 URL을 주면, index.yaml에서 패키지 경로에 웹서버의 경로를 붙여준다.


%helm repo index . --url https://bwcho75.github.io/my-repo

apiVersion: v1

entries:

  helloworld:

  - apiVersion: v1

    appVersion: "1.0"

    created: 2019-06-19T18:16:29.31329401+09:00

    description: A Helm chart for Kubernetes

    digest: f7fcd1078546939bd04b4f94282fb15b3d8d4c422e61b5b03b7e4061c1b61037

    name: helloworld

    urls:

     https://bwcho75.github.io/my-repo/helloworld-0.1.0.tgz

    version: 0.1.0

  helloworld2:

  - apiVersion: v1

    appVersion: "1.0"

    created: 2019-06-19T18:16:29.314605303+09:00

    description: A Helm chart for Kubernetes

    digest: 69510159a58a1c5c228b6870546b67d852b09d299b36d4617bf9e9b971be01fd

    name: helloworld2

    urls:

     https://bwcho75.github.io/my-repo/helloworld2-0.1.0.tgz

    version: 0.1.0

generated: 2019-06-19T18:16:29.311471188+09:00


다음에 helm 클라이언트에서 이 repository를 사용하도록 하려면,이 repository를  리스트에 추가해야 한다. 

명령을 helm repo add [리파지토리 이름] [URL] 식으로 지정하면 된다.

리파지토리 이름은 사용자가 임의적으로 정하는 이름이고 URL은 Helm 리자지토리의 http URL 이다. 

아래는 myrepo라는 이름으로, http://localhost:8879 서버를 등록하는 방법이다. 

helm repo add myrepo http://localhost:8879

"myrepo" has been added to your repositories


팀내나 아니면 작은 시스템을 위한 Helm repository 라면, helm serv,git (or github) 또는 간단한 웹서버 정도로도 repository 운영이 가능하다. 새로운 차트의 등록은 위에 처럼  그러나 큰 규모로 운영을 하거나 외부에 까지 repository를 오픈할 경우에는 사용자 인증등 별도의 보안 기능이 있고, 매번 index.yaml을 재생성하는게 아니라, 추가 삭제할 수 있는 repository를 사용하는 것을 권장한다. 

ChartMuseum

Charmusem (https://chartmuseum.com) 은 오픈소스 Helm Chart Repository 서버이다. 인증 기능을 제공할 뿐만 아니라 파일 스토리지를 AWS S3, 구글 GCS등을 백앤드로 사용할 수 있다. 


기본 설치 및 사용은 도커로 패키징 되어있는 이미지를 사용하면 된다.

docker run --rm -it \

  -p 8080:8080 \

  -v $(pwd)/charts:/charts \

  -e DEBUG=true \

  -e STORAGE=local \

  -e STORAGE_LOCAL_ROOTDIR=/charts \

  chartmuseum/chartmuseum:v0.8.1


Helm repository 서버이외에도, Chartmuseum은 추가적으로 필요한 기능에 대해서 오픈소스로 제공하고 있다. 

이중에서 주의 깊게 볼만한것은 chartmuseum/ui 와 chartmuseum/helm-push 인데, ui는 chartmuseum 에 대한 웹 인터페이스를 제공한다.

<그림. Chartmuseum ui 웹 화면 >

Chartmuseum push는 CLI도구로, 로컬에 있는 Helm 차트 패키지를 Chartmuseum 에 설치할 수 있는 기능이다. Helm 클라이언트가 깔려 있는 로컬 환경(PC나 노트북)에 인스톨 해서 사용한다.

로컬환경에 설치를 한후에, 차트를 Chartmuseum repository에 차트를 저장하려면 

%helm push [차트디렉토리] [repository 서버명]

으로 실행하면 된다. [차트 디렉토리]는 차트 파일이 들어있는 디렉토리이고 [repository 서버명] 은 helm repo add로 등록한 repository 이다.  

%helm push ./helloworld chartmuseum

지금까지, Helm에 대해서 알아보았다. Helm 은 쿠버네티스를 사용할때, 같이 많이 사용되는 솔루션이고 특히 쿠버네티스에 애플리케이션 설정 및 배포 관점에서 매우 유용하다. 물론 전체 CI/CD 파이프라인을 모두 만들 수 는 없지만, Spinnaker나 Jenkins X 등의 툴과 함께 전체 CI/CD 파이프라인의 중요한 요소로서 사용된다. 



본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

쿠버네티스 패키지 매니저 Helm

#2-4 Helm Chart Hook


조대협 (http://bcho.tistory.com)

Hook은 차트 설치나, 삭제와 같이 차트의 라이프 사이클 중에, 차크 개발자가 동작을 추가해줄 수 있도록 해주는 기능이다. mySQL을 차트로 설치한 후에, mySQL에 테이블을 생성하고 데이타를 로딩하거나, 차트로 Pod를 설치하기전에 Configmap이나 Secret 의 값을 세팅해놓는 것과 같은 작업을 예를 들 수 있다. 

등을 들 수 있다.


Hook 으로 실행되는 리소스는 따로 있는 것이 아니라, 기존의 쿠버네티스 리소스 (Job, Cron Job 등)에 metadata.annotations.”helm.sh/hook”  으로 태그를 달아주면, 이 리소스들은 Hook으로 정의되어 차트 인스톨 전후에 정해진 시점에 실행된다. 

아래는 차트 인스톨 전에  작업을 처리하도록 Hook을 정의한 예제이다. 


apiVersion: ...

kind: ....

metadata:

  annotations:

    "helm.sh/hook": "pre-install"

# ...


예를 들어 아래 그림과 같이 차트에, Deployment,Service,Job 등의 리소스를 차트에 정의해서 배포하고자 한다. 그중에, 인스톨 전과 후에 특정 작업을 Job을 이용해서 처리하고자 한다면, 그 Job들에 annotation으로, Helm Hook임을 명시해줘야 한다. 


<그림. Helm 차트내의 리소스와 Hook으로 정의된 리소스들>


이 차트를 실행하게 되면 다음과 같은 순서로 실행이 된다. 먼저 차트에 정의되어 있는 리소스 중에서 Hook 으로 정의된 리소스중, pre-install 로 정의된 리소스가 먼저 실행이 되고, 그 다음에 다른 리소스가 인스톨이 된다. 인스톨이 완료되고 나면 그후에 post-install 로 정의된 Hook이 실행되는 형태이다. 



<그림. Helm 차트에서 리소스들의 배포 순서>


Hook 종류

Hook 은 인스톨 전과 후 뿐만 아니라, 릴리즈를 삭제하거나 업그레이드 할때 등 다양한 시점에 Hook을 삽입할 수 있도록 정의되어 있다.  자세한 Hook 의 종류는 https://github.com/helm/helm/blob/master/docs/charts_hooks.md 문서를 참고하기 바란다. 정의된 Hook 중 몇가지를 보면 다음과 같다. 


  • pre-install: 리소스를 설치하기전에 실행된다. (정확히 이야기 하면 리소스를 설치하기 위한 템플릿이 렌더링 된 후에, 렌더링된 템플릿으로 리소스를 설치하기 전에 실행된다. )

  • post-install: Helm 차트에 의해서 리소스들이 모두 설치 된 후에 실행된다. 

  • pre-delete: 릴리즈의 리소스를 삭제할때, 삭제 전에 실행된다.

  • post-delete:릴리즈의 리소스를 삭제한 후에, 실행된다.  

  • pre-upgrade: 릴리즈를 업그레이드 하기 전,  ( 템플릿이 렌더링 된 후에) 리소스가 생성되기 바로 전에 실행된다.

  • post-upgrade: 릴리즈 업그레이드가 끝난 후에, 실행된다. 

  • pre-rollback: 릴리즈를 기존 버전으로 롤백 할때 실행된다. (템플릿이 렌더링 된 후에 )

  • post-rollback: 릴리즈에 대한 롤백이 완료된 후에 실행된다. 

  • crd-install:  CRD 리소스를 인스톨하는데, 다른 Hook이나 기타 모든 다른 태스크 보다 우선적으로 실행된다. 이 Hook은 다른 리소스에서 이 CRD를  참조하여사용할때 주로 사용된다. 

  • test-success: “helm test” 명령을 실행할때 수행되는데, 그 결과가 성공 (return code == 0)일때만 실행된다. 

  • test-failure: “helm test” 명령을 실행할때 수행되는데, 그 결과가 실패 (return code != 0)일때만 실행된다. 

Hook weight & policy

Hook에는 실행 시점을 정의하는 기능 뿐만 아니라, 여러개의 Hook이 정의되었을때 실행 순서를 정하거나 또는 Hook 실행이 끝났을때 Hook 리소스를 지울지 나둘지등의 정책을 결정하는 기능이 있다. 

Hook weight

Hook weight는 여러개의 Hook 이 있을때, Hook 들의 실행 순서를 정의하기 위해서 사용한다. 음/양수 모두를 사용할 수 있으며, 작은 수를 가지고 있는 Hook 부터 우선 실행된다.

Hook weight는 아래 그림과 같이 annotations 부분에 “helm.sh/hook-weight” 항목으로 지정할 수 있다. 

 annotations:

    "helm.sh/hook-weight": "5"

Hook delete policy

Hook 이 실행된 후에, Hook 리소스들을 지울지 말지를 설정할 수 있는데, Hook이 실행된 후에, Hook 리소스는 일반적으로는 남아 있다. 만약에 Hook 이 실행된 후에, Hook을 삭제 하고 싶으면 annotation에 “helm.sh/hook-delete-policy”에 아래와 같이 삭제 정책을 정하면 된다. 


annotations:

    "helm.sh/hook-delete-policy": hook-succeeded 

삭제 정책으로 사용할 수 있는 정책은 다음과 같다. 

  • "hook-succeeded" : Hook 이 성공적으로 실행이 되고 나면, 삭제하도록 한다. 

  • "hook-failed" : Hook 실행이 실패하였을 경우 삭제 한다. 

  • "before-hook-creation" : Hook 을 실행하기 전에, 기존의 Hook을 삭제하고 실행하도록 한다. 


본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

쿠버네티스 패키지 매니저 Helm

#2-3. Charts (디렉토리 구조)

조대협 (http://bcho.tistory.com)

디렉토리 구조

Helm 차트의 디렉토리 구조는 다음과 같다. 직접 아래와 같은 디렉토리 구조에 파일을 각각 생성해도 되지만, 기본 템플릿을 helm create [차트명] 으로 생성할 수 있다.

아래는

%helm create mychart

명령으로 생성한 디렉토리의 구조이다.


mychart/

 Chart.yaml          # A YAML file containing information about the chart

 LICENSE             # OPTIONAL: A plain text file containing the license for the chart

 README.md           # OPTIONAL: A human-readable README file

 requirements.yaml   # OPTIONAL: A YAML file listing dependencies for the chart

 values.yaml         # The default configuration values for this chart

 charts/             # A directory containing any charts upon which this chart depends.

 templates/          # A directory of templates that, when combined with values,

                     # will generate valid Kubernetes manifest files.

 templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes

Chart.yaml 파일

Chart.yaml은 차트에 대한 기본적인 메타 정보를 정의 한다.

apiVersion: The chart API version, always "v1" (required)

name: The name of the chart (required)

version: A SemVer 2 version (required)

kubeVersion: A SemVer range of compatible Kubernetes versions (optional)

description: A single-sentence description of this project (optional)

keywords:

 - A list of keywords about this project (optional)

home: The URL of this project's home page (optional)

sources:

 - A list of URLs to source code for this project (optional)

maintainers: # (optional)

 - name: The maintainer's name (required for each maintainer)

   email: The maintainer's email (optional for each maintainer)

   url: A URL for the maintainer (optional for each maintainer)

engine: gotpl # The name of the template engine (optional, defaults to gotpl)

icon: A URL to an SVG or PNG image to be used as an icon (optional).

appVersion: The version of the app that this contains (optional). This needn't be SemVer.

deprecated: Whether this chart is deprecated (optional, boolean)

tillerVersion: The version of Tiller that this chart requires. This should be expressed as a SemVer range: ">2.0.0" (optional)

차트의 이름이나 제작자등이 들어가는데, 몇가지 중요한 필드들을 살펴보자.

  • name은 Helm 차트의 이름을 정의한다.

  • version을 정의하는 것은 두가지 필드가 있는데, version 필드가 있고, appversion 이라는 필드가 따로 있다. version 필드는 helm 차트 자체의 버전을 정의하고, appversion은 이 차트를 통해서 배포 되는 애플리케이션의 버전을 정의한다. 예를 들어 helm 차트를 처음 만들었으면, helm 차트 버전은 1.0.0이 되고, helm chart를 통해서 채팅 애플리케이션 1.2를 배포한다면 appVersion은 1.2가 된다. 버전에 대한 네이밍은 semver (https://semver.org/lang/ko/)을 따르도록 한다.

License 및 README 파일

License 파일에는 이 Helm 차트의 라이센스 그리고,README에는 간략한 설명들을 적어 놓는다.

requirement.yaml 파일

Requirement.yaml에는 이 helm 패키지를 설치하기 위해서 필요한 다른 차트들의 목록을 기술한다. 이렇게 기술된 차트들은 이 차트가 설치되기 전에 자동으로 설치된다.

requirement.yaml 파일의 구조는 다음과 같다.


dependencies:

 - name: apache

   version: 1.2.3

   repository: http://example.com/charts

 - name: mysql

   version: 3.2.1

   repository: http://another.example.com/charts


Requirement.yaml에는 이 차트에 대한 의존성을 정의하는데, 필요한 차트의 이름과 버전 그리고, 그 차트가 저장된 리파지토리 경로를 정의한다.

위의 예제를 보면 apache의 1.2.3 버전의 차트가 필요하고, 이 차트는 http://example.com/charts에 저장되어 있음을 알 수 있다. 리파지토리에 대해서는 뒤에서 다시 한번 자세히 설명하도록 한다.


참고로 의존성에 정의된 차트들을 모두 설치하게할 수 도 있지만, tag나 condition을 사용하여, 조건에 따라 설치를 조정할 수 있다. 예를 들어 node.js API서버와 MySQL로 되어 있는 2-tier 애플리케이션이 있을때, MySQL을 같이 설치하도록 의존성을 정해놓을 수 있지만, 이미 MySQL이 쿠버네티스 클러스터내에 설치되어 있을 경우에는 그것을 재활용하면 되기 때문에, 옵션에 따라서 MySQL을 설치하거나 설치하지 않도록 할 수 있다.

charts/ 디렉토리

의존성이 필요한 차트들을 requirement.yaml 에 정의해놓는 경우, requirement.yaml에 있는 경로에서 다운로드 받아서 설치하는데, 다운로드를 받게하지 않고,차트를 배포할때 아예 같이 묶어서 배포하고 싶을 경우에는  charts 디렉토리에 차트들의 파일을 저장해놓으면, 차트를 배포할때 charts 디렉토리에 있는 차트를 먼저 배포하게 된다.

templates/ 디렉토리

Template는 앞의 예제를 통해서  설명했듯이, Helm 차트의 탬플릿을 정의한다.  

values.yaml 파일

values.yaml에는 템플릿에 사용될 value 값들을 저장한다



본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

쿠버네티스 패키지 매니저 HELM

#2-1 .Chart
조대협 http://bcho.tistory.com

Helm Chart

차트는 helm의 패키지 포맷으로, 하나의 애플리케이션을 설치하기 위한 파일들로 구성되어 있다. 예를 들어 tomcat을 설치하기 위한 쿠버네티스의 pod,service,deployment를 위한 YAML 파일등을 포함한다.

템플릿과 밸류

Helm 은 기본적으로 템플릿의 개념을 사용한다. 템플릿 파일을 만들어놓은 후에, 밸류 값을 채워 넣어서 쿠버네티스 리소스를 정의한 YAML 파일을 생성한다. 예제를 살펴보자

Helm 은 기본적으로 템플릿의 개념을 사용한다. 템플릿 파일을 만들어놓은 후에, 밸류 값을 채워 넣어서 쿠버네티스 리소스를 정의한 YAML 파일을 생성한다. 예제를 살펴보자.


먼저 templates/helloworld.yaml 파일을 정의한다.

apiVersion: apps/v1beta2

kind: Deployment

metadata:

 name: {{ .Values.name }}-deployment

spec:

 replicas: {{ .Values.replicaCount }}

 minReadySeconds: 5

 selector:

   matchLabels:

     app: {{ .Values.name }}

 template:

   metadata:

     name: {{ .Values.name }}-pod

     labels:

       app: {{ .Values.name }}

   spec:

     containers:

     - name: {{ .Values.name }}

       image: gcr.io/terrycho-sandbox/helloworlds:v1

       imagePullPolicy: Always

       ports:

       - containerPort: 8080

---

apiVersion: v1

kind: Service

metadata:

 name: {{ .Values.name }}-svc

spec:

 selector:

   app: {{ .Values.name }}

 ports:

   - name: http

     port: 80

     protocol: TCP

     targetPort: 8080

 type: LoadBalancer


그리고 ./values.yaml 파일을 아래와 같이 정의한다.


name: "helloworld"

replicaCount: 3


템플릿은 값을 채울 수 있는 말 그대로 템플릿이고, Value의 값을 이용해서 값을 채운다.

이를 개념적으로 표현해보면 다음과 같은 형태가 된다.



좌측은 템플릿 파일이고, 템플릿에서 밸류값은 별도의 파일에 정의한다.

정의한 키/밸류 형식으로 name:”helloworld”로 정의하였고, replicaCount: 2로 정의하였다

그리고 이 밸류값을 불러들이기 위해서는 {{.Value.키이름}} 식으로 템플릿내에 정의한다.

위의 예제에서 보면 name등에 {{.Value.name}} 으로 정의하였고, replicas 수는 {{ .Value.replicaCount }} 로 정의한다.

이렇게 정의된 템플릿에 밸류 내용을 정의하면 오른쪽 처럼 YAML 파일을 생성할 수 있다.


외부에서 Value를 받는 방법

Value값을 values,yaml에 지정해놨지만, 설치에 따라서 각 값을 변경하고 싶은 경우가 있다. 예를 들어 replicaCount를 3이 아니라 10으로 변경하고 싶을 경우에는 values.yaml 파일을 일일이 에디트 해야 한다. 나중에, 차트를 차트 리파지토리에 등록하기 위해서는 압축된 파일 형태를 사용하는데, 이 경우에는 그러면 차트 압축 파일을 다운로드 받은 후에 압축을 풀고나서, 내용을 수정하고 설치에 사용해야 하는 불편함이 있다.

이렇게 일일이 수정하지 않고 CLI에서 변경하고 싶은 인자만 간단하게 지정할 수 있는 방법이 없을까?

helm install 이나 upgrade시에  --set 옵션을 사용하면 된다. 예를 들어 values.yaml에 정의된 replicaCount를 10으로 변경하고자 하면 다음과 같이 하면 된다. %helm template --name myrelease --set replicaCount=10 ./helloworld


아래는 template 명령을 이용해서 테스트한 결과이다.   replicas가 10으로 변경된것을 볼 수 있다.

---

# Source: helloworld/templates/helloworld.yaml

apiVersion: apps/v1beta2

kind: Deployment


만약 설정값이 많아서 --set 을 이용해서 parameter로 넘기기가 어렵다면, 필요한 변수만 파일로 만들어서 넘길 수 있다.

예를 들어 myvalue.yaml 에 아래와 같이 name만 “fromValuefile” 로 정의를 한후에,


name: "fromValuefile"


helm install에서 -f 옵션으로 value 파일을 지정할 수 있다.

%helm install -f myvalues.yaml --name newrelease --dry-run --debug ./helloworld


결과를 보면 다음과 같다.

# Source: helloworld/templates/helloworld.yaml

apiVersion: apps/v1beta2

kind: Deployment

metadata:

 name: fromValuefile-deployment

spec:

 replicas: 3

:

myvalues.yaml에 지정한 name에 의해서 Deployment name이  fromValuefile-deployment로 변경되고, replica 수는 원래 values.yaml에 지정한대로 3을 사용한 것을 확인할 수 있다.


디렉토리 구조

개념을 이해 하였으면, 파일을 어디에 저장하는지 디렉토리 구조를 살펴보자, helloworld라는 차트를 만들 것인데, helloworld라는 디렉토리를 만든다.

그리고 그 아래 템플릿들은 templates 라는 디렉토리에 yaml 로 정의한다. 여기에 채울 value들은 helloworld/values.yaml 파일내에 저장한다.



그리고 helloworlds/Chart.yaml 이라는 파일을 생성해야 하는데, 이 파일에는 이 헬름 차트에 대한 버전이나 작성자, 차트 이름과 같은 메타 정보를 정의한다.


다음은 Chart.yaml 의 내용이다.

apiVersion: v1

appVersion: "1.0"

description: A Helm chart for Kubernetes

name: helloworld

version: 0.1.0

테스트(검증)

헬름 차트 작성이 끝났으면 제대로 작동하는지 검증을 해볼 수 있다. 먼저 문법적인 오류가 없는지 확인 하는 명령은 helm lint 명령을 사용하면 된다. 명령어 실행은 차트 디렉토리 위에서 해야 한다. 이 예제에서는 ../helloworld 디렉토리가 된다.

실행하면 다음과 같은 결과를 볼 수 있다.


%helm linit ./helloworld

==> Linting ./helloworld/

[INFO] Chart.yaml: icon is recommended


1 chart(s) linted, no failures


문법적인 오류가 없는지 점검을 해준다. 다음으로 탬플릿에 밸류가 제대로 적용되서 원하는 YAML을 제대로 생성해나가는지 검증해야 하는데, helm template이라는 명령어를 사용하면 된다. helm lint 명령과 마찬가지로 차트가 저장된 디렉토리의 상위 디렉토리 (../helloworld)에서 실행한다.

다음은 helm template 명령을 실행한 결과이다.


%helm template ./helloworld

# Source: helloworld/templates/helloworld.yaml

apiVersion: apps/v1beta2

kind: Deployment

metadata:

 name: helloworld-deployment

spec:

 replicas: 2

 minReadySeconds: 5

 selector:

   matchLabels:

     app: helloworld

 template:

   metadata:

     name: helloworld-pod

     labels:

       app: helloworld

   spec:

     containers:

     - name: helloworld

       image: gcr.io/terrycho-sandbox/helloworlds:v1

       imagePullPolicy: Always

       ports:

       - containerPort: 8080


내용 처럼 Value.name과  Value.replicaCount 값이 채워져서 Deployment 리소스에 대한 YAML 파일이 생성된것을 확인할 수 있다.

helm template 명령을 helm 클라이언트에서 tiller 서버 접속없이 template에 값이 채워지는지만 테스트를 하는 것이고, tiller 서버에 연결해서 테스트 할 경우에는 helm install --dry-run 옵션을 사용한다.  그리고, 내용을 확인하기 위해서 --debug 옵션을 추가한다.

helm install --name myrelease --dry-run --debug ./helloworld 이렇게 명령어를 사용하면 되는데, 장점은, 실제 서버에 연결해서 같은 릴리즈 버전이 있는지 등의 체크를 해주기 때문에, 실수를 막을 수 있다.

아래는 같은 릴리즈 버전으로 설치하는 것을 --dry-run으로 테스트한 결과이다.


% helm install --name myrelease --dry-run --debug ./helloworld

[debug] Created tunnel using local port: '56274'


[debug] SERVER: "127.0.0.1:56274"


[debug] Original chart version: ""

[debug] CHART PATH: /Users/terrycho/dev/workspace/kube/kubernetes-tutorial/31.helm/helloworld


Error: a release named myrelease already exists.

Run: helm ls --all myrelease; to check the status of the release

Or run: helm del --purge myrelease; to delete it


차트를 같은 이름(릴리즈명/뒤에서 다시 설명함)이 있기 때문에 설치할 수 없다 것을 테스트 단계에서 미리 확인할 수 있다.

실제 설치

그러면 생성한 헬름 차트를 이용해서 쿠버네티스에 리소스를 실제로 설치해보자. 설치 방법은 차트가 있는 디렉토리에서 helm install  명령을 이용해서 인스톨을 하면 된다. 이때 --name이라는 이름으로 설치된 차트 인스턴스의 이름을 설정해줘야 한다. 만약에 이름을 정해주지 않으면 임의의 이름이 자동으로 생성되어 사용된다.


%helm install --name helloworld ./helloworld/


명령을 실행하면 아래와 같이 deployment가 생성되는 것을 확인할 수 있다. 예제에서 설명은 하지 않았지만, 테스트에 사용된 코드에는 Service를 배포하는 부분이 함께 포함되어 있기 때문에 아래 실행결과를 보면 Service까지 같이 생성된것을 확인할 수 있다.


NAME:   helloworld

LAST DEPLOYED: Fri Jun  7 23:01:44 2019

NAMESPACE: default

STATUS: DEPLOYED


RESOURCES:

==> v1beta2/Deployment

NAME                   AGE

helloworld-deployment  1s


==> v1/Pod(related)


NAME                                    READY STATUS RESTARTS AGE

helloworld-deployment-696fc568f9-mc6mz  0/1 ContainerCreating 0 0s

helloworld-deployment-696fc568f9-nsw48  0/1 ContainerCreating 0 0s


==> v1/Service


NAME            AGE

helloworld-svc  1s


설치가 완료되었으면 리소스가 제대로 생성되었는지 확인을 해보기 위해서 kubectl get deploy 명령을 실행한다.


%kubectl get deploy

kubectl get deploy

NAME                    DESIRED CURRENT UP-TO-DATE   AVAILABLE AGE

helloworld-deployment   2 2 2         2 10m


위와 같이 Deployment 리소스가 생성 된것을 확인할 수 있다.

헬름을 통해서 설치된 차트들은 helm list 명령을 이용해서, 설치 상태를 확인할 수 있다.

helm list 명령을 실행해보면 아래와 같이 helloworld 차트가 설치된것을 확인할 수 있다.


%helm list

NAME               REVISION UPDATED                  STATUS   CHART            APP VERSION NAMESPACE

helloworld         1        Fri Jun  7 23:01:44 2019 DEPLOYED helloworld-0.1.0 1.0  




본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

쿠버네티스 패키지 매니저 HELM

Helm의 일반적인 개념

Helm은 리눅스의 apt 툴이나, node.js의 npm과 같은 쿠버네티스용 패키지 매니지먼트 도구 이다. 일반적으로 하나의 소프트웨어를 쿠버네티스에 배포하려면, 간단하게 컨테이너만을 배포해서는 사용하기 어려운 경우가 많다. 외부로 IP를 노출 시키기 위해서 쿠버네티스 서비스를 배포해야 하고,쿠버네티스 pod를 관리할 deployment가 필요하며, 디스크 볼륨과 기타 정책등 부가 적인 부분을 추가로 배포해야 한다.

이미 네트워크나 디스크 설정이 완료된 상태에서 애플리케이션을 업데이트 하는 경우에는 쿠버네티스 deployment나 다른 배포 도구를 이용해도 되지만, 처음부터 모든 것을 설치해야 하는 반복적인 작업이 있는 경우에는 배포 도구로 불가능하다.

그래서 Helm은 애플리케이션 컨테이너 배포는 물론이고, 이에 필요한 쿠버네티스 리소스를 모두 배포해주는 역할을 하는데, 이 배포를 패키지 형태로 한다.

Infrastructure as a code (이하 IaaC)를 구현하는 Terraform + 패키지 매니저인 npm 정도의 개념이 합쳐져 있다고 보면 된다.




<Helm 개념도>

Helm의 구성을 보면 위의 그림과 같다.

먼저 CLI 툴인 클라이언트로 helm이 있다. 이 클라이언트는  Helm 서버 모듈과 통신을 하는데, Helm 서버를 Tiller라고 하고, Tiller는 쿠버네티스 클러스터 내에 설치된다.

helm 을 통해서 인스톨하는 패키지를 Chart라고 한다. Chart는 템플릿으로 설치하고자 하는 쿠버네티스 리소스의 설치 스크립트가 된다. 이 Chart들은 Helm Chart Repository에 저장할 수 있는다. Helm Chart repository는 HTTP server를 지원하는 서버로 Google Cloud Storage나 Git Hub page 또는 웹서버등을 사용할 수 있다.


Helm 설치

Helm 설치는 먼저 helm 클라이언트를 설치해야 한다. https://github.com/helm/helm 에 설치가이드가 나와 있는데, 맥 사용자의 경우 brew로 쉽게 설치가 가능하고, Linux의 경우 scoop등의 패키지 인스톨러를 이용하면 된다.


다음 helm 서버인 Tiller를 설치해야 한다.

Tiller 설치는 간단하게 다음 명령을 클라이언트에서 실행하면 된다. (이때, 이미 클라이언트에 kubectl 명령과 쿠버네티스 연결을 위한 설정이 다 되어있어야 한다.)

% helm init ---history-max 200

(Helm 설치 히스토리의 수를 정의해준다. 최대 히스토리 수를 정하지 않으면 히스토리가 무한으로 증가하게 된다.)


그러면 테스트로 MySQL를 Helm을 이용해서 설치해보자 먼저 Chart 저장되는 repository 를 최신으로 업데이트 한다.

%helm repo update 명령을 실행하면 된다.


다음 mySQL을 설치할것인데,

%helm install stable/mysql

명령을 실행하면 다음과 같이 MySQL이 설치된다. 설치가 끝나면 아래 결과와 같이 mySQL 연결을 테스틑 하는 방법과 ROOT 패스워드를 구하는 방법이 나온다.



위의 그림에서와 같이

%  MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default iron-kitten-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)

명령어를 실행하여, MySQL Root 패스워드를 알아낸다.

다음

% kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il

을 실행해서, 우분투 이미지 기반의 컨테이너를 하나 만든후에, bash로 접속을 한다.

접속이 된 상태에서

% apt-get update && apt-get install mysql-client -y

명령을 이용해서 MySQL 클라이언트를 설치하고

% mysql -h iron-kitten-mysql -p

를 실행하고 앞에서 구한 비밀 번호를 넣으면 아래  그림과 같이 MySQL에 접속이 된다.



Helm에 의해서 설치된 차트 목록을 확인하려면 아래와 같이

% helm list

를 실행하면 된다. 아래 그림에서 보면 앞에서 설치한 mySQL이 iron-kitten이라는 이름으로 설치가 되어있는 것을 확인할 수 있다.


   

만약 설치된 helm chart를 삭제하기 위해서는

%helm delete {Chart명} 을 하면된다.

앞에서 설치한 iron-kitten mysql chart를 삭제하려면

%helm delete iron-kitten

을 실행하면 아래 그림과 같이 삭제되는 것을 확인할 수 있다.



본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

파이어베이스 애널러틱스를 이용한 모바일 데이타 분석

#4 주피터 노트북을 이용한 파이어베이스 데이타 분석 및 시각화

조대협 (http://bcho.tistory.com)

노트북의 개념

빅데이타 분석에서 리포팅 도구중 많이 사용되는 제품군 중의 하나가 노트북이라는 제품군이다. 대표적인 제품으로는 오픈소스 제품중 주피터(https://ipython.org/notebook.html) 와 제플린(https://zeppelin.apache.org/) 이 있다.

노트북은 비지니스에 전달하기 위한 멋진 액셀이나 대쉬보드와 같은 리포트 보다는 데이타를 다루는 데이타 과학자와 같은 사람들이 사용하는 분석도구인데, 제품의 이름 처럼 노트북의 개념을 가지고 있다.

예를 들어서 설명해보자 우리가 수학문제를 풀려면 연습장을 펴놓고 공식을 사용해가면서 하나하나 문제를 풀어나간다. 이처럼, 빅데이타 분석을 하려면, 여러데이타를 분석해가면서 그 과정을 노트하고 노트한 결과를 기반으로 다음 단계의 문제를 풀어나가는 것이 통상적인데, 노트북 소프트웨어는 문제 풀이에 있어서 기존의 연습장 노트와 같은 사용자 경험을 제공한다.

이러한 노트북 소프트웨어의 특징은 메모를 위한 글과, 계산을 위한 소스 코드를 한페이지에 같이 적을 수 있고, 이 소스 코드는 노트북 내에서 실행이 가능하고 결과도 같은 페이지에 출력해준다.


다음 화면은 본인이 작성했던 노트북의 일부로 딥러닝 프레임웍인 텐서플로우에 대해서 공부하면서 간단하게 문법과 샘플 코드를 노트북에 정리한 예이다.



데이타랩

구글의 데이타랩(https://cloud.google.com/datalab/) 은 오픈소스 주피터 노트북을 구글 클라우드 플랫폼에 맞게 기능을 추가한 노트북이다. 기본이 되는 주피터 노트북이 오픈소스이기 때문에, 데이타랩 역시 오프소스로 코드가 공개되어 있다.


데이타랩은 기본으로 파이썬 언어를 지원하며, 빅쿼리 연동등을 위해서 SQL과, 자바 스크립트를 지원한다.

또한 머신러닝의 딥러닝 프레임웍인 텐서플로우도 지원하고 있다.

데이타랩에서 연동할 수 있는 데이타는 구글 클라우드상의 VM이나, 빅쿼리, Google Cloud Storage

데이타랩은 오픈소스로 별도의 사용료가 부가되지 않으며, 사용 목적에 따라서 VM에 설치해서 실행할 수 도 있고, 로컬 데스크탑에 설치해서 사용할 수 도 있다. 도커로 패키징이 되어 있기 때문에 도커 환경만 있다면 손쉽게 설치 및 실행이 가능하다.

데이타 랩 설치

이 글에서는 로컬 맥북 환경에 데이타랩을 설치해서 데이타를 분석 해보도록 하자.

데이타 랩은 앞에서 언급한것과 같이 구글 클라우드 플랫폼 상의 VM에 설치할 수 도 있고, 맥,윈도우 기반의 로컬 데스크탑에도 설치할 수 있다. 각 플랫폼별 설치 가이드는  https://cloud.google.com/datalab/docs/quickstarts/quickstart-local 를 참고하기 바란다. 이 문서에서는 맥 OS를 기반으로 설치하는 방법을 설명한다.


데이타 랩은 컨테이너 솔루션인 도커로 패키징이 되어 있다. 그래서 도커 런타임을 설치해야 한다.

https://www.docker.com/products/docker 에서 도커 런타임을 다운 받아서 설치한다.

도커 런타임을 설치하면 애플리케이션 목록에 다음과 같이 고래 모양의 도커 런타임 아이콘이 나오는 것을 확인할 수 있다.



하나 주의할점이라면 맥에서 예전의 도커 런타임은 오라클의 버추얼 박스를 이용했었으나, 제반 설정등이 복잡하기 때문에, 이미 오라클 버추얼 박스 기반의 도커 런타임을 설치했다면 이 기회에, 도커 런타임을 새로 설치하기를 권장한다.

다음으로 도커 사용을 도와주는 툴로 Kitematic 이라는 툴을 설치한다. (https://kitematic.com/) 이 툴은 도커 컨테이너에 관련한 명령을 내리거나 이미지를 손쉽게 관리할 수 있는 GUI 환경을 제공한다.


Kitematic의 설치가 끝났으면 데이타랩 컨테이너 이미지를 받아서 실행해보자, Kitematic 좌측 하단의 “Dokcer CLI” 버튼을 누르면, 도커 호스트 VM의 쉘 스크립트를 수행할 수 있는 터미널이 구동된다.


터미널에서 다음 명령어를 실행하자


docker run -it -p 8081:8080 -v "${HOME}:/content" \

  -e "PROJECT_ID=terrycho-firebase" \

  gcr.io/cloud-datalab/datalab:local


데이타랩은 8080 포트로 실행이 되고 있는데, 위에서 8081:8080은  도커 컨테이너안에서 8080으로 실행되고 있는 데이타 랩을 외부에서 8081로 접속을 하겠다고 정의하였고, PROJECT_ID는 데이타랩이 접속할 구글 클라우드 프로젝트의 ID를 적어주면 된다.

명령을 실행하면, 데이타랩 이미지가 다운로드 되고 실행이 될것이다.

실행이 된 다음에는 브라우져에서 http://localhost:8081로 접속하면 다음과 같이 데이타랩이 수행된 것을 볼 수 있다.


데이타랩을 이용한 파이어베이스 애널러틱스 데이타 분석 (책에서는 위치 이동 할것 파이어 베이스로)

데이타랩이 설치되었으면, 파이어베이스 애널러틱스를 이용하여 빅쿼리에 수집한 로그를 분석해보자

데이타 랩에서 “+Notebook” 버튼을 눌러서 새로운 노트북을 생성하자

생성된 노트북으로 들어가서 “Add Code” 버튼을 누르고, 생성된 코드 블록 박스에 아래와 같은 SQL을 추가하자


%%sql

SELECT user_dim.app_info.app_instance_id, user_dim.device_info.device_category, user_dim.device_info.user_default_language, user_dim.device_info.platform_version, user_dim.device_info.device_model, user_dim.geo_info.country, user_dim.geo_info.city, user_dim.app_info.app_version, user_dim.app_info.app_store, user_dim.app_info.app_platform

FROM [terrycho-firebase:my_ios.app_events_20160830]


%%sql은 빅쿼리 SQL을 수행하겠다는 선언이다.

다음에 SQL 문장을 기술했는데, 테이블은 terrycho-firebase 프로젝트의 my_ios 데이타셋의 app_events_20160830 테이블에서 쿼리를 하였다.

2016년 8월 30일의 iOS 앱에서 올라온 사용자 관련 정보를 쿼리하는 내용이다. (디바이스 정보, 국가등)

다음은 쿼리 결과 이다.



다음 쿼리는 2016년 6월 1일의 안드로이드와 iOS 접속자에 대해서 국가별 사용자 수 통계를 내는 쿼리이다.


%%sql

SELECT

 user_dim.geo_info.country as country,

 EXACT_COUNT_DISTINCT( user_dim.app_info.app_instance_id ) as users

FROM

[firebase-analytics-sample-data:android_dataset.app_events_20160601],

 [firebase-analytics-sample-data:ios_dataset.app_events_20160601]

GROUP BY

 country

ORDER BY

 users DESC




다음은 2016년 6월 1일 사용자중, 안드로이드와 iOS 모두에서 사용자가 사용하는 언어별로 쿼리를 하는 내용이다.


%%sql

SELECT

 user_dim.user_properties.value.value.string_value as language_code,

 EXACT_COUNT_DISTINCT(user_dim.app_info.app_instance_id) as users,

FROM [firebase-analytics-sample-data:android_dataset.app_events_20160601],

 [firebase-analytics-sample-data:ios_dataset.app_events_20160601]

WHERE

user_dim.user_properties.key = "language"

GROUP BY

language_code

ORDER BY

users DESC


쿼리 결과



이번에는 차트를 사용하는 방법을 알아보자, 안드로이드 로그에서 이벤트 로그중에, 많이 나오는 로그 20개에 대한 분포도를 파이 차트로 그려내는 예제이다.

%%sql --module events

SELECT event_dim.name as event_name, COUNT(event_dim.name) as event_count  

FROM [firebase-analytics-sample-data:android_dataset.app_events_20160601]

GROUP BY event_name

ORDER BY event_count DESC

LIMIT 20


쿼리 결과를 --module 명령을 이용하여 events라는 모듈에 저장한후


%%chart pie --fields event_name,event_count --data events

title: Event count

height: 400

width: 800

pieStartAngle: 20

slices:

 0:

   offset: .2


구글 차트 명령을 이용하여 pie 차트를 그린다. 필드는 앞의 모듈에서 쿼리한 event_name과 event_count 필드를 이용하고, 데이타는 앞에서 정의한 “events” 모듈에서 읽어온다.

차트 실행 결과는 다음과 같다.



이외에도 Tensorflow 연동이나 GCS를 연동하는 방법, 그리고 구글 차트 이외에 일반 plot 함수를 이용하여 그래프를 그리는 등 다양한 기능을 제공하는데, 이에 대한 자세한 설명은 데이타랩을 설치하면 /docs/README.md 파일을 참조하면 다양한 가이드를 찾을 수 있다.



본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.