helmを導入してK8sのyamlをテンプレート記載したい
- helmとは
- なぜhelmがほしいのか
helmとは
Kubernetes(K8s)に関する技術で、K8s用のyamlを記載しやすいようにするモノ、という理解
そもそもパッケージ管理ソフトなので、wordpressをK8sで入れたい!とかいうときに世の中にあるパッケージを使ってインストールということも可能(ぽい)
- 参考 qiita.com
なぜhelmがほしいのか
どういうシーンでほしいかというと
例えば、iamgeのpullするUrlを隠蔽したい場合、です。(もしくは環境毎にimageの情報が変わる、など)
- imageはECRからpullしたい
- 例:
<i>aws_account_id</i>.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latestからpullしたい
- 例:
- でもGitHubのpublicなリポジトリに直接AWSアカウントをpushしたくない
結論
例えば、
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
labels:
app: sample
spec:
replicas: 2
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: sample
image: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
ports:
- containerPort: 80
こんなふうに、直接imageを記載するのを避けたい。
(aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latestを直接記載したくない)
version情報
$ helm version
version.BuildInfo{Version:"v3.3.3", GitCommit:"55e3ca022e40fe200fbc855938995f40b2a68ce0", GitTreeState:"dirty", GoVersion:"go1.15.2"}
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-13T11:52:32Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:18:29Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"linux/amd64"}
helm
上記問題点をhelmを使うことによって解決できます
helmはyamlの一つの機能として、テンプレーティングを行えます。
上記sample-deploymentというdeploymentを例にすると
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
labels:
app: sample
spec:
replicas: 2
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: sample
image: {{ .Values.app.imageUrl }}
ports:
- containerPort: 80
このように{{ .Values.app.imageUrl }}と記載し、この部分をhelmに別ファイルで渡すことができます
そしてその別ファイルをGitHubにpushしない運用によって、秘匿情報を隠蔽できたり、環境毎にyamlを用意しなくても済む、というもの。
helmを使うと、K8sのyamlを直接記載せずに、
上記テンプレートだけをひたすら記載するような運用になる(と思います)
helm使い方
- helmのインストール
$ brew install helm
- helmの初期化(プロジェクト作成)
$ helm create mychart
mychartフォルダにサンプルとなるchart類が作成されます
フォルダ構成は以下の感じ
./mychart ├── Chart.yaml ├── charts ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── hpa.yaml │ ├── ingress.yaml │ ├── service.yaml │ ├── serviceaccount.yaml │ └── tests │ └── test-connection.yaml └── values.yaml
基本的にいじるのが、templatesディレクトリの中身と、values.yamlの中身
最小限の構成への変更
シンプルな構成とするために、上記helm create mychartで作ったchartから、不要部分を削除します
以下のファイルを削除
mychart/charts/削除mychart/templates/の中身削除mychart/values.yamlの中身を全削除
mychart/values.yamlを記入
app: imageUrl: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
mychart/tempates/deployment.yamlを記入
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
labels:
app: sample
spec:
replicas: 2
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: sample
image: {{ .Values.app.imageUrl }}
ports:
- containerPort: 80
上記2つのファイルを記載した状態でheml installしていきます
helm installのチェック
$ helm install --dry-run --debug --generate-name ./mychart
これで、このhelmを実行した際に何が起こるか(どのようなK8sリソースが作成されるか)がわかる
$ helm install --dry-run --debug --generate-name ./mychart
NAME: mychart-1600747915
LAST DEPLOYED: Tue Sep 22 13:11:56 2020
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
app:
imageUrl: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
HOOKS:
MANIFEST:
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
labels:
app: sample
spec:
replicas: 2
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: sample
image: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
ports:
- containerPort: 80
このように表示されます
肝心のimage部分image: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latestとなっているので想定通り
helm install
helm installにてリソースをK8sに反映していきます。
以下のようなコマンド構成です。
$ helm install <chart-name> <chart-directory>
chartに名前を付ける必要があります
(省略できるようですが、省略した場合ランダムな名前がつけられてめんどくさいので、原則名前つけないといけない)
$ helm install chartname ./mychart NAME: chartname LAST DEPLOYED: Tue Sep 22 13:20:16 2020 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None
このように出ます。
kubectlで確認
$ kubectl get all NAME READY STATUS RESTARTS AGE pod/sample-deployment-b978cbc69-lczpd 0/1 ErrImagePull 0 32s pod/sample-deployment-b978cbc69-tswdg 0/1 ErrImagePull 0 32s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/sample-deployment 0/2 2 0 32s NAME DESIRED CURRENT READY AGE replicaset.apps/sample-deployment-b978cbc69 2 2 0 32s
imageがめちゃくちゃ適当な名前(aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest)なので起動は失敗していますが、なんかそれっぽい。
helm list
$ helm listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION chartname default 1 2020-09-22 13:20:16.082367 +0900 JST deployed mychart-0.1.0 1.16.0
インストール済みのhelmのlistが出ます
helm upgradeの準備
インストール済みのchartを更新したい場合にはhelm upgradeです
$ helm upgrade <chart-name>
今回以下の内容を変更します
- deploymentのコンテナ名称を
myappにする - imageを
nginx:latestにする
values.yamlの変更
app: imageUrl: nginx:latest appName: myapp
このように変更しました
deployment.yamlを変更
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
labels:
app: sample
spec:
replicas: 2
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: {{ .Values.app.appName }}
image: {{ .Values.app.imageUrl }}
ports:
- containerPort: 80
{{ .Values.app.appName }}を追記
helm upgradeの実行
helm upgradeによってchartが更新できるわけですが、その前に内容を確認したいです。
その場合には--dry-runを使います。
ついでに--debug表示もします
$ helm upgrade --dry-run --debug chartname ./mychart
upgrade.go:121: [debug] preparing upgrade for chartname
upgrade.go:129: [debug] performing update for chartname
upgrade.go:287: [debug] dry run for chartname
Release "chartname" has been upgraded. Happy Helming!
NAME: chartname
LAST DEPLOYED: Tue Sep 22 13:29:21 2020
NAMESPACE: default
STATUS: pending-upgrade
REVISION: 2
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
app:
appName: myapp
imageUrl: nginx:latest
HOOKS:
MANIFEST:
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
labels:
app: sample
spec:
replicas: 2
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: myapp
image: nginx:latest
ports:
- containerPort: 80
これで結果を確認できます(まだ適応されてはおらず、結果を表示しただけです)
pluginについて
helm upgradeを実行する前に、diffというプラグインを使ってみます
helmの差分を表示できるpluginのようです
github.com
hlem用のプラグインが多く開発されており、いろいろなものがあるようです。
- diff pluginのinstall
$ helm plugin install https://github.com/databus23/helm-diff
diffの確認
--valuesでvalues.yamlを指定しています(これしないとうまく差分が出ない)
helm diff upgrade chartname ./mychart --values ./mychart/values.yaml
default, sample-deployment, Deployment (apps) has changed:
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
labels:
app: sample
spec:
replicas: 2
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- - name: sample
- image: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
+ - name: myapp
+ image: nginx:latest
ports:
- containerPort: 80
内容は問題なさそうなので、helm upgradeをやっていきます
helm upgradeの実行
helm upgradeの実行をします
コマンドの実行結果は以下のような感じでした。
-valuesに./mychart/values.yamlを指定しています(diffのコマンドからdiff部分を削除しただけ)
$ helm upgrade chartname ./mychart --values ./mychart/values.yaml Release "chartname" has been upgraded. Happy Helming! NAME: chartname LAST DEPLOYED: Tue Sep 22 13:58:40 2020 NAMESPACE: default STATUS: deployed REVISION: 2 TEST SUITE: None
upgradeの結果の確認
$ kubectl get all NAME READY STATUS RESTARTS AGE pod/sample-deployment-787c75d69d-99gk7 1/1 Running 0 112s pod/sample-deployment-787c75d69d-x6krf 1/1 Running 0 106s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/sample-deployment 2/2 2 2 4m7s NAME DESIRED CURRENT READY AGE replicaset.apps/sample-deployment-787c75d69d 2 2 2 112s replicaset.apps/sample-deployment-b978cbc69 0 0 0 4m7s
imageをnginxにしたので動き出しました。
一部設定の隠蔽
今回の目的はGitHubにPushしたくないことでした。
以下のような方針で秘匿情報を隠蔽します
values.yamlにはデフォルト値を書いておくoverride.yamlというファイルを作り、ここに秘匿情報を書く- 秘匿にしたい情報のみこのファイルに書く
- ファイル名はなんでもOKです
override.yamlを.gitignore登録しておく
override.yaml
以下のように記載します(今回はapp.imageUrlを隠蔽したい)
app: imageUrl: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
app.imageUrlのみを上書きします
この状態でdiffしてみます
--valuesコマンドを2つ以上指定することができます
helm diff upgrade chartname ./mychart --values ./mychart/values.yaml --values ./mychart/override.yaml
default, sample-deployment, Deployment (apps) has changed:
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
labels:
app: sample
spec:
replicas: 2
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: myapp
- image: nginx:latest
+ image: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
ports:
- containerPort: 80
こうなります。
想定通り。
upgradeします
$ helm upgrade chartname ./mychart --values ./mychart/values.yaml --values ./mychart/override.yaml
無事にupgradeが完了
helm delete
最後は削除します
$ helm delete chartname