そんな今日この頃の技術ネタ

本家側に書くほどでもない小ネタ用

Kubernetes関連の便利ツール: Helm

便利ツール紹介その2。

HelmはKubernetesのパッケージ管理ツールである。リポジトリに登録された構成情報(これをChartと呼ぶ)をinstallコマンドに適時引数で設定情報を与え、簡単に自分のクラスタに導入(これをReleaseと呼ぶ)することができるものである。

github.com

例えば公式リポジトリにstable/mysqlとして登録されているChartをmy-databaseという名称でパスワード等を設定して展開するには

$ helm install --name my-release \
  --set mysqlRootPassword=secretpassword,mysqlUser=my-user,mysqlPassword=my-password,mysqlDatabase=my-database \
    stable/mysql

という具合である。

もちろん用意されているChartを導入するという用途もそれはそれで便利ではあるのだが、自作の構成をHelmで扱うことによりシステムの運用にも便利に活用することができる。今回はそちらに軸足を置いて解説する。


導入

MacであればHomebrew経由でクライアントを導入できる

$ brew install kubernetes-helm


Helmは

  • ユーザが直接操作を行うクライアント
  • 対象クラスタのkube-systemにインストールされるサーバ=tiller
  • Chartを保存するリポジトリ=>独自にhttpで立てることができる

の3要素で動作する。

kubectlの接続情報がある状態で以下のコマンドによりtillerのセッティングを行うことができる。

$ helm init

$ helm version
Client: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}


Chartの作成

helm create CHARTコマンドにより雛形を作成できる。

$  helm create sample
Creating sample

$ tree sample/
sample/
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── ingress.yaml
│   └── service.yaml
└── values.yaml

2 directories, 7 files
  • Chart.yaml: 名称やバージョン等の基本情報を記述
  • values.yaml: 環境により変更されうる値を格納
  • templates以下: Manifestfileを格納


templateディレクトリ以下にKuberetesのManifestfileを格納するイメージになる。この時にyamlファイル内に変数や条件分岐やループなんかを記述することができる。

  • {{ .Values.key }}のようにして変数を埋め込み
  • {{-if OPTION -}}による条件分岐
  • {{- range VALUE := VALUES -}}{{- end -}}によるループ
  • {{template}}によるテンプレート埋め込み
$ head sample/templates/deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: {{ template "sample.fullname" . }}
  labels:
    app: {{ template "sample.name" . }}
    chart: {{ template "sample.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:


そして、ここで埋め込む変数はvalue.yamltemplates/_helpers.tplなどで定義することができる。

$ head sample/values.yaml
replicaCount: 1

image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent

例えば上のstableを取得するならば{{Values.image.tag}}と指定すれば良い。


また、この変数はhelm install/upgradeコマンドにおいて--setオプションによって外部から値を渡すことができる。(あるいはファイルとして与える事もできる。)

開発・本番などの環境によって変動しうる要素をこの変数で扱うことで取り回しが容易になる他、Dockerイメージのタグを変数として扱うことによってシステムの更新にも活用することができる。


Chartの記述が完了したらhelm lintでシンタックスチェックを行う。ここで問題がなければ、単純にパスを直に指定して操作を行うようなこともできる(例: helm install --name hogehgoe ./sample)し、あるいはhelm package ./sampleで固めた上でディレクトリにまとめてhelm repoコマンドでindex.yamlを作成し、これらをhttpサーバにアップロードして専用のリポジトリを作ることもできる。

注意点として、リポジトリを使用する場合はバージョンが同一だと既にダウンロードされたChartが使われてしまうので、Chart.yamlのversion項を横着せずに更新すること。


クラスタへの展開

クラスタに展開するには以下のような手順を踏む。

  1. helm repo add [NAME] [URL]でリポジトリ追加
  2. helm repo updateで最新化
  3. helm install [CHART] --name [RELEASE]でクラスタに展開
  4. helm upgrade [RELEASE] --set key=valueで任意に設定値を変更
  5. 必要に応じてhelm rollback [RELEASE] [REVISION]で任意の状態に戻すこともできる
  6. helm delete --purge [RELEASE]で削除


例えばCIなんかで利用することを想定すると、以下のようなコマンドを叩かせるのが良いのではないだろうか。

  • 展開済みかどうかに関わらず展開したいのでupgrade --install
  • 展開先のネームスペースを指定--namespace
  • 接続先を明示的に指定するために--kube-context(kubectl config get-contextsで確認できる)
  • 別のリポジトリや手動操作からの設定値を継承するために--reuse-values
$ helm --kube-context [CONTEXT] \
    --namespace [NAMESPACE] \
    upgrade --install [RELEASE] [CHART] \
    --reuse-values 


まとめ

  • Helmを用いることで環境間の差異を変数として扱うことができる
  • 設定値を引数として渡すことでイメージの更新もできるのでCIで扱い易い
  • もしもの時のロールバックも容易

ということでKubernetesのシステムを運用する上で便利に活用することができる。

入門 Kubernetes

入門 Kubernetes

  • 作者: Kelsey Hightower,Brendan Burns,Joe Beda,松浦隼人
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2018/03/22
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る


Kubernetesの運用という話題でいえば昨今だとSpinnakerなんかも話題に上ることが多いんだけど、あれ自体が結構なリソースを食うので個人や一部署レベルで導入するには厳しい感じがってまだ試せてないんだよね・・・