Kubernetes Helmを試してみました。下記はv2.0.0-alpha.5
で時点での情報です。
Kubernetes Helmとは
Kubernetes Helm(以降Helm)とはKubernetesのパッケージマネージャーです。HelmはKubernetesのSIG-Appsで開発がされています。パッケージはChart(s)と呼ばれ、公式でレポジトリkubernetes/chartsが用意されています。Kubernetesクラスタに側にはtillerと呼ばれるデプロイ用のコンポーネントを配置して使用します。
用語 | 意味 | 役割 |
---|---|---|
helm | 船のかじ | yum, aptに相当するパッケージマネージャー。Linux, OSXのバイナリが用意されている |
chart | 海図 | deb, rpmに相当するパッケージ。Kubernetesのマニフェストのテンプレートをまとめたもの |
tiller | 舵柄 | デプロイを担うサーバーコンポーネント |
公式レポジトリ
公式レポジトリではstableとincubatorの2つに分けて管理されています。kubernetes/chartsのstableの説明によると下記のポリシーで運用されています。
- データ永続化の方法が提供される
- アプリケーションのアップグレードがサポートされる
- アプリケーション設定のカスタマイズを許可する
- セキュアなデフォルト設定を持つ
- Kubernetesのアルファ機能を利用しない
公式レポジトリ以外に任意のレポジトリを使用することも可能です。なお、現在は下記のパッケージが提供されています。
Stable
Incubator
旧Helm、DeploymentManagerとの関係
Kubernetes HelmはHelm Classic(旧Helm)というプロジェクトと、Kubernetesチームが開発するdeployment-manager(dm)という2つのツールが統合されたものです。Integrate helm and dm #171によると、ハッカソンでこの2つを統合すると決めたらしく、レポジトリ名も"deployment-manager"から"helm"に変更されました。現在のKubernetes Helmも主にDeis(Engine Yard)のエンジニアが開発しています。参考: Kubernetes HelmのContributors
Helmを試してみる
Helmのインストール
Helmのクライアント(helm
コマンド)のインストールを行います。Homebrew Caskのformulaが用意されてますが、最新のバージョン(v2.0.0-alpha.5
)を使いたかったので、releasesからダウンロードしPATHの通った場所にhelm
バイナリを配置しました。
$ export HELM_OS=darwin && wget https://storage.googleapis.com/kubernetes-helm/helm-v2.0.0-alpha.5-$HELM_OS-amd64.tar.gz && tar -zxvf helm-v2.0.0-alpha.5-$HELM_OS-amd64.tar.gz && cd $HELM_OS-amd64
下記のコマンドでクラスタの初期化を行います。初期化ではkubernetesクラスタにサーバーコンポーネント(tiller
)のデプロイを行うため、kubectlの接続先設定もされている必要があります。
$ helm init
Creating /Users/tkusumi/.helm
Creating /Users/tkusumi/.helm/repository
Creating /Users/tkusumi/.helm/repository/cache
Creating /Users/tkusumi/.helm/repository/local
Creating /Users/tkusumi/.helm/repository/repositories.yaml
Creating /Users/tkusumi/.helm/repository/local/index.yaml
$HELM_HOME has been configured at $HOME/.helm.
Tiller (the helm server side component) has been installed into your Kubernetes Cluster.
Happy Helming!
下記のようにサーバーコンポーネントのtillerがkubernetesクラスタのkube-system
ネームスペースにデプロイされます。
$ kubectl get pods --all-namespaces | grep tiller
kube-system tiller-deploy-637859184-v6za1 1/1 Running 0 1m
helm version
でクライアント、サーバーのバージョンを確認できます。
$ helm version
Client: &version.Version{SemVer:"v2.0.0-alpha.5", GitCommit:"36ec1901ebd68ae976fa8ef332ca5ed44598fc24", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.0.0-alpha.5", GitCommit:"4de5c4aa578ed9ca173aff472f00d2167ec59a88", GitTreeState:"dirty"}
参考
Helmでパッケージをインストールする
helm search
でstableパッケージの一覧が取得できます。(2.0.0-Alpha.5
からの機能)
$ helm search
NAME VERSION DESCRIPTION
stable/drupal 0.3.2 One of the most versatile open source content m...
stable/jenkins 0.1.0 A Jenkins Helm chart for Kubernetes.
stable/mariadb 0.5.0 Chart for MariaDB
stable/mysql 0.1.0 Chart for MySQL
stable/redmine 0.3.1 A flexible project management web application.
stable/wordpress 0.3.0 Web publishing platform for building blogs and ...
helm install PACKAGE_NAME
でパッケージのインストールを行います。ここではJenkinsをインストールしてみます。インストール時にパッケージごとの設定を指定することができます。指定可能な値は各パッケージのREADMEにかかれています。参考: JenkinsのREADME
$ helm install stable/jenkins
Fetched stable/jenkins to jenkins-0.1.0.tgz
viable-robin
Last Deployed: Tue Oct 11 13:57:50 2016
Namespace: default
Status: DEPLOYED
~省略~
Notes:
Getting Started:
1. Get your 'admin' user password by running:
printf $(printf '\%o' `kubectl get secret --namespace default viable-robin-jenkins -o jsonpath="{.data.jenkins-admin-password[*]}"`);echo
2. Get the Jenkins URL to visit by running these commands in the same shell:
**** NOTE: It may take a few minutes for the LoadBalancer IP to be available. ****
**** You can watch the status of by running 'kubectl get svc -w viable-robin-jenkins' ****
export SERVICE_IP=$(kubectl get svc --namespace default viable-robin-jenkins -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:8080/login
3. Login with the password from step 1 and the username: admin
For more information on running Jenkins on Kubernetes, visit:
https://cloud.google.com/solutions/jenkins-on-container-engine
Jenkinsにアクセスする手順が表示されるので手順の通りアクセスし、正しくJenkinsがインストールされたことを確認します。
下記のようにJenkinsのPodが配置されました。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
viable-robin-jenkins-4218656479-dvu4v 1/1 Running 0 4m
helm list
コマンドでデプロイされた一覧を確認することができます。
$ helm list
NAME REVISION UPDATED STATUS CHART
viable-robin 1 Tue Oct 11 13:57:50 2016 DEPLOYED jenkins-0.1.0
パッケージ(Charts)を試しに作ってみる
ここではサンプルに任意の文字列を設定できるnginxのパッケージ(Charts)を作ります。
helm create
というコマンドで雛形を生成します。
$ helm create helloworld
Creating helloworld
下記の構成でファイルが作られます。
helloworld/
Chart.yaml # chartの情報を記載するyaml
values.yaml # chartのデフォルト設定
charts/ # chartの依存を含めるディレクトリ
templates/ # マニフェストファイルのテンプレートを配置するディレクトリ
templates/
以下にkubernetesのマニフェストファイルのテンプレートを配置します。ここでは下記のマニフェストのテンプレートを配置しました。テンプレートはGoのtext/template形式で記述します。.Values
というのが任意に設定する情報です。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
# 本来は{{.Release.Name}}などを使ってユニークにする必要がある
name: "hello-nginx"
labels:
spec:
# 任意のレプリカ数を設定できる
replicas: {{.Values.replicaCount}}
template:
metadata:
labels:
app: "hello-nginx"
spec:
containers:
- image: nginx:1.11.4
name: nginx
ports:
- containerPort: 80
command:
- /bin/bash
- -c
# 任意の値をindex.htmlで表示
- 'echo "<h1>{{.Values.message}}</h1>" > /usr/share/nginx/html/index.html; /usr/sbin/nginx -g "daemon off;"'
apiVersion: v1
kind: Service
metadata:
name: hello-nginx
labels:
spec:
ports:
- port: 80
name: http
targetPort: 80
selector:
app: "hello-nginx"
type: LoadBalancer
values.yaml
に初期値を記載しておきます。
replicaCount: 2
message: hello world!
helm lint
という構文チェックツールが付属していおり、構文エラーをチェックすることができます。
$ helm lint helloworld
==> Linting helloworld
[ERROR] templates/: render error in "helloworld/templates/hello-deployment.yaml": template: helloworld/templates/hello-deployment.yaml:14:24: executing "helloworld/templates/hello-deployment.yaml" at <{{template "fullname...>: template "fullname" not defined
Error: 1 chart(s) linted, 1 chart(s) failed
構文に問題がなければパッケージ(tgz
ファイル)を作成します。
$ helm package helloworld
パッケージされたhelloworld-0.1.0.tgz
が作成されました。下記の用にインストールができます。テンプレートの変数は--set
フラグでカンマ区切りのkey=value形式、または--values
フラグでyaml形式で指定することができます。
$ helm install --set 'message=It works!,replicaCount=3' helloworld-0.1.0.tgz
right-quail
Last Deployed: Tue Oct 11 16:19:10 2016
Namespace: default
Status: DEPLOYED
Resources:
==> extensions/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-nginx 3 3 3 0 0s
==> v1/Service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-nginx 10.187.251.4 <pending> 80/TCP 0s
ロードバランサのEXTERNAL-IPを確認してブラウザでアクセスします。
$ kubectl get svc hello-nginx
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-nginx 10.187.251.4 104.155.129.166 80/TCP 53s
既存のChartを見ると、他にもラベルなどの設定がいろいろとあるので、実際に作る際は既存のものを参考にするとよいと思います。例えばRelease.Name
(指定しないとランダムで付けられる)のような事前に定義された変数があり、これらを使ってユニークなname
を設定したりする必要があります。
その他にChartでできること
Chartsのドキュメントによると他にChartsで下記のことができるようです。
依存関係
Chartの依存関係をcharts/
ディレクトリへのコピーまたはrequirements.yaml
による定義で表現することができます。これにより自動的にChartの依存関係を解決することができます。
dependencies:
- name: apache
version: 1.2.3
repository: http://example.com/charts
- name: mysql
version: 3.2.1
repository: http://another.example.com/charts
フック
パッケージインストール、削除、アップグレード時にフックする機能が提供されています。例えばシークレットを動的に作ることや、アップグレード前にDBのバックアップを取るなどの用途に利用できます。下記のフックポイントが用意されています。
- pre-install
- post-install
- pre-delete
- post-delete
- pre-upgrade
- post-upgrade
フックの処理はKubernetesのBatch Jobとして定義し、下記のようにアノテーションでフックポイントを指定できます。カンマ区切りで複数していすることもできます。
annotations:
"helm.sh/hook": post-install