LoginSignup
28
17

More than 5 years have passed since last update.

独自のHelm Chartの作成とGitHub Pagesでの公開

Last updated at Posted at 2018-11-02

ICPにMySQLに接続するLibertyアプリケーションをデプロイ

で作成した簡単なLiberty-MySQLのアプリケーションをHelmチャートにして公開する方法を確認。

Helmの初期化

Helmを初期化する。

helm init

サーバー側のバージョンが取得出来ていればサーバー側(tiller)も稼働している。

$ helm version --tls
Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.9.1+icp", GitCommit:"843201eceab24e7102ebb87cb00d82bc973d84a7", GitTreeState:"clean"}
$

マニフェストの確認

上記記事で使用していたマニフェストは以下。

ファイル名 説明
mysql-pv.yaml MySQLコンテナが使用するPersistentVolume
mysql-pvc.yaml MySQLコンテナが使用するPersistentVolumeClaim
mysql-secret.yaml MySQLのrootパスワードを格納したSecret
mysql-deployment.yaml MySQLのDeployment
mysql-service.yaml MySQLのService
mysql-init-job.yaml MySQLを初期化するJob
liberty-config.yaml LibertyからMySQLへの接続情報を格納したConfigMap
liberty-secret.yaml LibertyからMySQLへの接続のパスワードを格納したSecret
liberty-deployment.yaml LibertyのDeployment
liberty-service.yaml LibertyのService
liberty-ingress.yaml LibertyにルーティングするIngress

雑なチャートの作成

helm create hellomysqlでチャートの雛形を作成することができるが、雛形からカスタマイズするのは難易度が高いように思う。まずは雑にチャートを作成する。

チャートの構造

Helmの公式サイトによると、チャートの構造は以下の通り。

example/
├── Chart.yaml          # チャートの情報を含むyaml
├── LICENSE             # OPTIONAL: チャートのライセンス情報を含むprain text
├── README.md           # OPTIONAL: READMEファイル
├── charts              # このチャートが依存するチャートを格納するディレクトリー
├── requirements.yaml   # OPTIONAL: 依存するチャートをリストしたyaml
├── templates           # マニフェストのテンプレートを格納するディレクトリー
│   ├── NOTES.txt       # OPTIONAL: チャートの使用方法を記載したplain text
│   ├── _hogehoge.tpl   # OPTIONAL: アンダースコア始まりはマニフェストを含まないテンプレート
│   └── hogehoge.yaml   # マニフェストを含むテンプレート
└── values.yaml         # このチャートのデフォルト値を記載したyaml

上記でOPTIONALになっていないが、values.yamlchartsディレクトリーもなくても大丈夫だったので、最低限必要なものは以下。

  • Chart.yaml
  • templates/*.yaml

チャートの作成

全くパラメータなしでマニフェストをまとめただけのチャートを作成する。

はじめにChart.yamlを作成する。このファイルにチャートの名前やバージョンなどを記載する。

vi hellomysql/Chart.yaml
Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: hellomysql
version: 0.1.0

templatesディレクトリーを作成し、このディレクトリーにマニフェストを全部入れる。

mkdir -p hellomysql/templates

ディレクトリー構造は以下のようになる。

$ tree hellomysql
hellomysql
├── Chart.yaml
└── templates
    ├── liberty-config.yaml
    ├── liberty-deployment.yaml
    ├── liberty-ingress.yaml
    ├── liberty-secret.yaml
    ├── liberty-service.yaml
    ├── mysql-deployment.yaml
    ├── mysql-init-job.yaml
    ├── mysql-pv.yaml
    ├── mysql-pvc.yaml
    ├── mysql-secret.yaml
    └── mysql-service.yaml

1 directory, 12 files
$

これで一応パッケージングできる。パッケージング前にhelm lintコマンドで静的なチェックができる。

$ helm lint hellomysql
==> Linting hellomysql
[INFO] Chart.yaml: icon is recommended
[INFO] values.yaml: file does not exist

1 chart(s) linted, no failures
$

パッケージングを行う。

$ helm package hellomysql
Successfully packaged chart and saved it to: /home/ubuntu/hellomysql-chart/hellomysql-0.1.0.tgz
$

デプロイ確認

PVやIngressが環境に依存するためデプロイできる環境は限られ、また変更できるパラメータもないが、このチャートでもデプロイできるのでデプロイしてみる。

既にアプリケーションがデプロイ済みの場合は削除する。

kubectl delete -f liberty-ingress.yaml -n sugi
kubectl delete -f liberty-service.yaml -n sugi
kubectl delete -f liberty-deployment.yaml -n sugi
kubectl delete -f liberty-config.yaml -n sugi
kubectl delete -f liberty-secret.yaml -n sugi
kubectl delete -f mysql-init-job.yaml -n sugi
kubectl delete -f mysql-service.yaml -n sugi
kubectl delete -f mysql-deployment.yaml -n sugi
kubectl delete -f mysql-secret.yaml -n sugi
kubectl delete -f mysql-pvc.yaml -n sugi
kubectl delete -f mysql-pv.yaml -n sugi

PVのディレクトリーも掃除する。

sudo rm -rf /data/mysql/*

デプロイしてみる。

$ helm install --name test --namespace sugi hellomysql-0.1.0.tgz --tls
NAME:   test
E1024 12:44:34.134084   19753 portforward.go:303] error copying from remote stream to local connection: readfrom tcp4 127.0.0.1:32823->127.0.0.1:53268: write tcp4 127.0.0.1:32823->127.0.0.1:53268: write: broken pipe
LAST DEPLOYED: Wed Oct 24 12:44:33 2018
NAMESPACE: sugi
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME     TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)   AGE
liberty  ClusterIP  10.0.0.153  <none>       9080/TCP  1s
mysql    ClusterIP  10.0.0.167  <none>       3306/TCP  1s

==> v1/Deployment
NAME     DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
liberty  1        1        1           0          1s
mysql    1        1        1           0          1s

==> v1/Pod(related)
NAME                      READY  STATUS             RESTARTS  AGE
liberty-74fd798747-7gqsp  0/1    ContainerCreating  0         1s
mysql-7c47657796-8gj5x    0/1    Pending            0         1s
mysql-init-9cwl8          0/1    Pending            0         0s

==> v1/ConfigMap
NAME            DATA  AGE
liberty-config  3     1s

==> v1/PersistentVolume
NAME      CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS  CLAIM           STORAGECLASS  REASON  AGE
mysql-pv  10Gi      RWO           Retain          Bound   sugi/mysql-pvc  mysql         1s

==> v1/PersistentVolumeClaim
NAME       STATUS  VOLUME    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
mysql-pvc  Bound   mysql-pv  10Gi      RWO           mysql         1s

==> v1/Secret
NAME            TYPE    DATA  AGE
liberty-secret  Opaque  1     1s
mysql-secret    Opaque  1     1s

==> v1/Job
NAME        DESIRED  SUCCESSFUL  AGE
mysql-init  1        0           1s

==> v1beta1/Ingress
NAME     HOSTS  ADDRESS  PORTS  AGE
liberty  *      80       0s


$

リリースを確認する。

$ helm ls --tls --namespace sugi
NAME    REVISION    UPDATED                     STATUS      CHART               NAMESPACE
test    1           Wed Oct 24 12:44:33 2018    DEPLOYED    hellomysql-0.1.0    sugi
ubuntu@icp31-single:~/hellomysql-chart$ helm status test --tls
LAST DEPLOYED: Wed Oct 24 12:44:33 2018
NAMESPACE: sugi
STATUS: DEPLOYED

RESOURCES:
==> v1/PersistentVolumeClaim
NAME       STATUS  VOLUME    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
mysql-pvc  Bound   mysql-pv  10Gi      RWO           mysql         1m

==> v1/Service
NAME     TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)   AGE
liberty  ClusterIP  10.0.0.153  <none>       9080/TCP  1m
mysql    ClusterIP  10.0.0.167  <none>       3306/TCP  1m

==> v1/Deployment
NAME     DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
liberty  1        1        1           1          1m
mysql    1        1        1           1          1m

==> v1beta1/Ingress
NAME     HOSTS  ADDRESS      PORTS  AGE
liberty  *      54.95.4.186  80     1m

==> v1/Secret
NAME            TYPE    DATA  AGE
liberty-secret  Opaque  1     1m
mysql-secret    Opaque  1     1m

==> v1/ConfigMap
NAME            DATA  AGE
liberty-config  3     1m

==> v1/PersistentVolume
NAME      CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS  CLAIM           STORAGECLASS  REASON  AGE
mysql-pv  10Gi      RWO           Retain          Bound   sugi/mysql-pvc  mysql         1m

==> v1/Job
NAME        DESIRED  SUCCESSFUL  AGE
mysql-init  1        1           1m

==> v1/Pod(related)
NAME                      READY  STATUS     RESTARTS  AGE
liberty-74fd798747-7gqsp  1/1    Running    0         1m
mysql-7c47657796-8gj5x    1/1    Running    0         1m
mysql-init-9cwl8          0/1    Completed  2         1m


$

アプリケーションにアクセスする。

$ curl -k https://mycluster.icp/liberty/hellomysql/HelloServlet
user1
user2
user3
user4
user5
user6
Served at: /hellomysql$

これで雑なチャートの作成は完了。

削除しておく。

helm delete --purge test --tls
sudo rm -rf /data/mysql/*

GitHub Pagesでの公開

GitHubにはGitHub Pagesという静的サイトのホスティング機能があるので、この機能を使ってChartリポジトリを作成する。

GitHubでリポジトリを作成する。リポジトリ名は任意。

image.png

作成したリポジトリをローカルにcloneし、gh-pagesというブランチを作成する。このブランチの内容がGitHub Pagesとして公開される。

$ git clone git@github.com:sotoiwa/charts.git
Cloning into 'charts'...
warning: You appear to have cloned an empty repository.
$ cd charts/
$ git checkout -b gh-pages
Switched to a new branch 'gh-pages'
$

リポジトリの直下にstableディレクトリを作成する。

mkdir stable
cd stable

試しに雛形のチャートを作り、そのままパッケージする。

$ helm create example
Creating example
$ helm package example
Successfully packaged chart and saved it to: /home/ubuntu/workspace/charts/stable/example-0.1.0.tgz
$

stableディレクトリで以下のコマンドを実行してインデックスファイルを作成する。

helm repo index .

stableディレクトリが以下の構造になっていればChartリポジトリとして成立する。

$ tree .
.
├── example
│   ├── Chart.yaml
│   ├── charts
│   ├── templates
│   │   ├── NOTES.txt
│   │   ├── _helpers.tpl
│   │   ├── deployment.yaml
│   │   ├── ingress.yaml
│   │   └── service.yaml
│   └── values.yaml
├── example-0.1.0.tgz
└── index.yaml

3 directories, 9 files
$

コミットする。

git add -A
git commit -m "example 0.1.0"
git push --set-upstream origin gh-pages

Liberty-MySQLのアプリケーションのチャートのディレクトリとアーカイブをstableディレクトリに追加する。

$ tree .
.
├── example
│   ├── Chart.yaml
│   ├── charts
│   ├── templates
│   │   ├── NOTES.txt
│   │   ├── _helpers.tpl
│   │   ├── deployment.yaml
│   │   ├── ingress.yaml
│   │   └── service.yaml
│   └── values.yaml
├── example-0.1.0.tgz
├── hellomysql
│   ├── Chart.yaml
│   └── templates
│       ├── liberty-config.yaml
│       ├── liberty-deployment.yaml
│       ├── liberty-ingress.yaml
│       ├── liberty-secret.yaml
│       ├── liberty-service.yaml
│       ├── mysql-deployment.yaml
│       ├── mysql-init-job.yaml
│       ├── mysql-pv.yaml
│       ├── mysql-pvc.yaml
│       ├── mysql-secret.yaml
│       └── mysql-service.yaml
├── hellomysql-0.1.0.tgz
└── index.yaml

5 directories, 22 files
$

インデックスを更新する。

helm repo index .

コミットする。

git add -A
git commit -m "hellomysql 0.1.0"
git push

リポジトリの設定ページを開き、gh-pagesブランチが公開されていることを確認する。他のブランチの内容を公開したい場合はここでソースを選ぶ。

image.png

インデックスにアクセスできることを確認する。

$ curl https://sotoiwa.github.io/charts/stable/index.yaml
apiVersion: v1
entries:
  example:
  - apiVersion: v1
    appVersion: "1.0"
    created: 2018-10-24T13:49:48.400067463Z
    description: A Helm chart for Kubernetes
    digest: 12cdaf8b7c7fafe17632d770af40518ca5ab037df4e033e0ce276ac6eb6e5b98
    name: example
    urls:
    - example-0.1.0.tgz
    version: 0.1.0
  hellomysql:
  - apiVersion: v1
    appVersion: "1.0"
    created: 2018-10-24T13:49:48.400404953Z
    description: A Helm chart for Kubernetes
    digest: 30d09a58f79d57e0d775212c10b4baa386fa937a576b1867491e5cfb7bdd257b
    name: hellomysql
    urls:
    - hellomysql-0.1.0.tgz
    version: 0.1.0
generated: 2018-10-24T13:49:48.399585684Z
$

Chartリポジトリとして追加する。

helm repo add sotoiwa-stable https://sotoiwa.github.io/charts/stable

確認。

$ helm repo list
NAME            URL
stable          https://kubernetes-charts.storage.googleapis.com
local           http://127.0.0.1:8879/charts
ibm-charts      https://raw.githubusercontent.com/IBM/charts/master/repo/stable/
sotoiwa-stable  https://sotoiwa.github.io/charts/stable
$ helm search sotoiwa
NAME                        CHART VERSION   APP VERSION DESCRIPTION
sotoiwa-stable/example      0.1.0           1.0         A Helm chart for Kubernetes
sotoiwa-stable/hellomysql   0.1.0           1.0         A Helm chart for Kubernetes
$

マシなチャートの作成

雑なチャートはパラメータが何もなかったり、リソースの名前が固定だったり、Secretが含まれていたり問題があるので、もう少しマシなチャートを作成する。

参考資料

helm createコマンドが生成する雛形や、既成のチャートをダウンロードして中身を参考にしてチャートを作成しようとしたが、Helmの公式サイトに非常に分かりやすいドキュメント(チュートリアル)があるので、結局そちらを読んだほうが早い。チャートの記載に必要なGoテンプレート言語についてもだいたいわかる。

helmコマンドで雛形を生成する場合は以下のようにする。

helm create hellomysql

既成のチャートをダウンロードして参考にする場合で、デフォルトのstableリポジトリではなくibm-chartsのリポジトリからチャートをダウンロードする場合は、まずリポジトリを追加する。

helm repo add ibm-charts https://raw.githubusercontent.com/IBM/charts/master/repo/stable/

チャートのダウンロードは以下のようにする。

helm fetch ibm-charts/ibm-websphere-liberty
helm fetch ibm-charts/ibm-microclimate
helm fetch ibm-charts/ibm-icplogging

あるいはGitリポジトリをクローンしてもよい。

なお、Libertyのチャートはサブチャートを使うようになっている。ibm-websphere-libertyのチャートとibm-open-libertyのチャートがそれぞれサブチャートとしてibm-shared-libertyのチャートを含んでいる。

オプションのファイルの検討

チャートのファイルのうち、今回どこまで作成するかを検討する。

ファイル 説明 必須 今回の方針
Chart.yaml チャートの情報を含むyaml 必須 作成する
LICENSE チャートのライセンス情報を含むplain txt オプション 作成しない
README.md MarkDownで書かれたREADME オプション 作成しない
requirements.yaml サブチャートへの依存性をリストしたyaml オプション サブチャートは使わないので作成しない
values.yaml チャートのデフォルト値 必須 作成する
charts/* サブチャート オプション サブチャートは使わないので作成しない
templates/* マニフェストテンプレート 必須 作成する
templates/NOTES.txt オプション チャートをinstallしたときに表示される説明を記載したprain txt 作成する

含めるマニフェストの検討

PVについては環境に依存するためチャートには含めない方がよさそう。Secretもチャートには含めない方がよさそう。Ingressも環境に依存するのでON/OFFを切り替えられるようにした方がよさそうだが、ICP前提で今回はとりあえずそのままにする。

PVとSecretは事前に作成するようにREADME.mdでやNOTES.txtでガイドするべきだが今回は省略。

パラメータの検討

それ以外にパラメータ化したいものを検討する。だいたい以下か?

  • Dockerイメージ
  • Libertyのレプリカ数
  • パスワードを格納するSecret名
  • PVのサイズ
  • PVのストレージクラス

これらをvalues.yamlにする。

values.yaml
mysql:
  repository: mysql
  tag: "5.7"
  pullPolicy: IfNotPresent
  secretName: mysql-secret
  persistence:
    size: 10Gi
    storageClassName: mysql

init:
  repository: sotoiwa540/hellomysql-init
  tag: "1.0"
  pullPolicy: Always

liberty:
  repository: sotoiwa540/hellomysql
  tag: "1.0"
  pullPolicy: Always
  replicaCount: 1
  secretName: liberty-secret

tag1.0はクオートしないと数値の1として扱われてイメージのPullに失敗したので注意。

テンプレートの検討

helm createコマンドが生成した雛形の_helpers.tplを確認すると、このテンプレートは以下のNamed Templateを定義している。

Named Template 説明
<チャート名>.name Expand the name of the chart.
<チャート名>.fullname Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name.
<チャート名>.chart Create chart name and version as used by the chart label.

<チャート名>.nameは以下のようなテンプレート。

{{- define "example-v2.11.0.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
  • default .Chart.Name .Values.nameOverrideは、.Values.nameOverrideが与えられなかったときデフォルト値.Chart.Nameを返す
  • trunc 63は63文字で切り捨て
  • trimSuffix "-"は末尾の-を除去

つまり普通は.Chart.Nameを返すが、オーバーライドを可能にしたり、もう少し細やかな対応をしてくれている。

<チャート名>.fullname.Chart.Name.Release.Nameを元に少し複雑なことをやっているが、普通は.Release.Name.Chart.Nameをハイフンでつないだものを返す。

<チャート名>.chartも普通は.Chart.Name.Chart.Version

今回はわかりやすさを優先し、上記を簡単にした以下のテンプレートを使う使わずに各リソースにそのまま.Chart.Nameなどを書くようにする。

なおテンプレートで使われている関数についてはGoテンプレート言語そのもののものもあるが、多くがsprigというテンプレートライブラリのもので、そちらのドキュメントから使い方を確認できる。

リソース名の検討

雛形が生成したdeployment.yamlでは<チャート名>.fullnameを使っている。

  name: {{ template "example-v2.9.1.fullname" . }}

これは普通は<リリース名>-<チャート名>だが、今回は、Deploymentリソースが複数あるので、この指定では重複してしまうので、<リリース名>-<元々のリソース名>にする。

ラベルの検討

既存のibm-chartsのチャートをみるとリソースには以下のラベルがつくようになっている。

  labels:
    app: {{ include "sch.names.fullName" (list .) }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"

一方helm createで生成した雛形のDeployment定義をみると、このラベルはhelmクライアントのバージョンによって異なっていて、どこかのバージョンから標準ラベルが変わったようだ。

v2.9.1
  labels:
    app: {{ template "example-v2.9.1.name" . }}
    chart: {{ template "example-v2.9.1.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
v2.11.0
  labels:
    app.kubernetes.io/name: {{ include "example-v2.11.0.name" . }}
    helm.sh/chart: {{ include "example-v2.11.0.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}

このラベルについてはThe Chart Best Practices GuideのなかにStandard Labelsとして説明があり、Helm自体がこのラベルを使用するわけではなく、あくまでオプションであるという記載がある。また、v2.11.0のhelmコマンドが生成したラベルのほうが最新のラベルであることも確認できる。

今回はv2.9.1の方のラベルをつけることにする。
なお、templateを使うかincludeを使うかも変わっている。templateをより高機能にしたHelm専用の関数がincludeで、結果をパイプラインで他の関数に渡すことができる(templateではできない)。

Lifecycle Hookの検討

フックを使ってインストール後にJobを実行させることができそうなので、MySQLのデータの初期化のJobはHookを使って実行してみる。

metadata:
  annotations:
    "helm.sh/hook": "post-install"

フックを使うとリリースの管理下に入らないことに注意。

デバッグ

チャートのデバックは以下のコマンドを利用すると便利。

静的なチェックは以下。

helm lint hellomysql

tillerでテンプレートのレンダリングを実行し、生成したマニフェストを表示する。

helm install --debug --dry-run hellomysql

チャートの作成

上記をふまえて以下の作業を実施する。

  • 各マニフェストにchartreleaseheritageのラベルをつける
  • DeploymentのPodTemplateselectorにもchartreleaseheritageのラベルを追加する
  • Serviceのselectorchartreleaseheritageのラベルを指定する
  • - 各マニフェストのnameに{{ .Release.Name }}-を追加する
  • IngressのバックエンドのserviceName{{ .Release.Name }}-libertyに変える
  • ConfigMapのmysql-servername"{{ .Release.Name }}-mysql"に変える
  • ConfigMapを参照しているDeploymentでConfigMap名を{{ .Release.Name }}-liberty-config
  • MySQLがマウントするPVCのclaimName{{ .Release.Name }}-mysqlに変える
  • values.yamlに定義したものをマニフェストで.Valuesから取得するようにする。
  • JobにLifecycle Hookのアノテーションをつける
  • Jobが接続するMySQLホスト名を{{ .Release.Name }}-mysqlにする
  • PVとsecretをマニフェストから除外する

最終的に作成したマニフェスト・テンプレートは以下。

$ tree hellomysql
hellomysql
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── liberty-config.yaml
│   ├── liberty-deployment.yaml
│   ├── liberty-ingress.yaml
│   ├── liberty-service.yaml
│   ├── mysql-deployment.yaml
│   ├── mysql-init-job.yaml
│   ├── mysql-pvc.yaml
│   └── mysql-service.yaml
└── values.yaml

2 directories, 11 files
$
Charts.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: hellomysql
version: 0.1.1
NOTES.txt
Thank you for installing {{ .Chart.Name }}.

Your release is named {{ .Release.Name }}.

To learn more about the release, try:

  $ helm status {{ .Release.Name }}
  $ helm get {{ .Release.Name }}
liberty-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-liberty-config
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
data:
  mysql-servername: "{{ .Release.Name }}-mysql"
  mysql-portnumber: "3306"
  mysql-user: "liberty"
liberty-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-liberty
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  selector:
    matchLabels:
      app: liberty
      chart: {{ .Chart.Name }}-{{ .Chart.Version }}
      release: {{ .Release.Name }}
      heritage: {{ .Release.Service }}
  replicas: {{ .Values.liberty.replicaCount }}
  template:
    metadata:
      labels:
        app: liberty
        chart: {{ .Chart.Name }}-{{ .Chart.Version }}
        release: {{ .Release.Name }}
        heritage: {{ .Release.Service }}
    spec:
      containers:
      - name: liberty
        image: "{{ .Values.liberty.repository }}:{{ .Values.liberty.tag }}"
        imagePullPolicy: {{ .Values.liberty.pullPolicy }}
        ports:
        - containerPort: 9080
        env:
        - name: MYSQL_SERVERNAME
          valueFrom:
            configMapKeyRef:
              name: {{ .Release.Name }}-liberty-config
              key: mysql-servername
        - name: MYSQL_PORTNUMBER
          valueFrom:
            configMapKeyRef:
              name: {{ .Release.Name }}-liberty-config
              key: mysql-portnumber
        - name: MYSQL_USER
          valueFrom:
            configMapKeyRef:
              name: {{ .Release.Name }}-liberty-config
              key: mysql-user
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: liberty-secret
              key: liberty-password
liberty-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ .Release.Name }}-liberty
  annotations:
    ingress.kubernetes.io/rewrite-target: /
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  rules:
  - host:
    http:
      paths:
      - path: /liberty
        backend:
          serviceName: {{ .Release.Name }}-liberty
          servicePort: 9080
liberty-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-liberty
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  type: ClusterIP
  selector:
    app: liberty
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
  ports:
  - protocol: TCP
    port: 9080
mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-mysql
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
      chart: {{ .Chart.Name }}-{{ .Chart.Version }}
      release: {{ .Release.Name }}
      heritage: {{ .Release.Service }}
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
        chart: {{ .Chart.Name }}-{{ .Chart.Version }}
        release: {{ .Release.Name }}
        heritage: {{ .Release.Service }}
    spec:
      containers:
      - name: mysql
        image: "{{ .Values.mysql.repository }}:{{ .Values.mysql.tag }}"
        imagePullPolicy: {{ .Values.mysql.pullPolicy }}
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ .Values.mysql.secretName }}
              key: root-password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: {{ .Release.Name }}-mysql-pvc
mysql-init-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-mysql-init
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
  annotations:
    "helm.sh/hook": "post-install"
spec:
  template:
    spec:
      containers:
      - name: init-hellomysql
        image: "{{ .Values.init.repository }}:{{ .Values.init.tag }}"
        imagePullPolicy: {{ .Values.init.pullPolicy }}
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ .Values.mysql.secretName }}
              key: root-password
        command: ["sh", "-c"]
        args: ["mysql -u root -p${MYSQL_ROOT_PASSWORD} -h {{ .Release.Name }}-mysql < init.sql"]
      restartPolicy: OnFailure
mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ .Release.Name }}-mysql-pvc
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  storageClassName: {{ .Values.mysql.persistence.storageClassName }}
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: {{ .Values.mysql.persistence.size }}
mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-mysql
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  ports:
  - port: 3306
  selector:
    app: mysql
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}

ポート番号が固定なのに一部では環境変数を使っているなど中途半端なところがあるがとりあえずこれでよし。

リリース確認

はじめにPVとsecret作成する。

mysql-pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
  name: mysql-pv
spec:
  storageClassName: mysql
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data/mysql"
kubectl apply -f mysql-pv.yaml
mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
type: Opaque
data:
  root-password: cGFzc3dvcmQ=
kubectl apply -f mysql-secret.yaml -n sugi
liberty-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: liberty-secret
type: Opaque
data:
  liberty-password: bGliZXJ0eQ==
kubectl apply -f liberty-secret.yaml -n sugi

チャートをリリースする。チャートはチャート格納ディレクトリーを直接指定。Liberyのレプリカ数をパラメータとして与えてみる。

helm install hellomysql --debug --dry-run --name test --namespace sugi --set liberty.replicaCount=2 --tls
helm install hellomysql --name test --namespace sugi --set liberty.replicaCount=2 --tls
ubuntu@icp31-single:~/workspace/charts/stable$ helm install hellomysql --name test --namespace sugi --set liberty.replicaCount=2 --tls
NAME:   test
LAST DEPLOYED: Mon Nov  5 01:23:12 2018
NAMESPACE: sugi
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                 DATA  AGE
test-liberty-config  3     35s

==> v1/PersistentVolumeClaim
NAME            STATUS  VOLUME    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
test-mysql-pvc  Bound   mysql-pv  10Gi      RWO           mysql         35s

==> v1/Service
NAME          TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)   AGE
test-liberty  ClusterIP  10.0.0.136  <none>       9080/TCP  35s
test-mysql    ClusterIP  10.0.0.71   <none>       3306/TCP  35s

==> v1/Deployment
NAME          DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
test-liberty  2        2        2           2          34s
test-mysql    1        1        1           1          33s

==> v1beta1/Ingress
NAME          HOSTS  ADDRESS      PORTS  AGE
test-liberty  *      54.95.4.186  80     33s

==> v1/Pod(related)
NAME                           READY  STATUS   RESTARTS  AGE
test-liberty-7d8f7497b9-czlk8  1/1    Running  0         33s
test-liberty-7d8f7497b9-xqgvh  1/1    Running  0         33s
test-mysql-cfc8c8c86-9rv7b     1/1    Running  0         33s


NOTES:
Thank you for installing hellomysql.

Your release is named test.

To learn more about the release, try:

  $ helm status test
  $ helm get test
ubuntu@icp31-single:~/workspace/charts/stable$

上記出力で、JobはLifecycleのため上記リリースに含まれていないことが確認できる。

ジョブが完了したことを確認する。

ubuntu@icp31-single:~/workspace/charts/stable$ kubectl get job -n sugi
NAME              DESIRED   SUCCESSFUL   AGE
test-mysql-init   1         1            6m
ubuntu@icp31-single:~/workspace/charts/stable$ kubectl get po -n sugi
NAME                            READY     STATUS      RESTARTS   AGE
test-liberty-7d8f7497b9-czlk8   1/1       Running     0          6m
test-liberty-7d8f7497b9-xqgvh   1/1       Running     0          6m
test-mysql-cfc8c8c86-9rv7b      1/1       Running     0          6m
test-mysql-init-7hbzf           0/1       Completed   1          6m
ubuntu@icp31-single:~/workspace/charts/stable$

アクセス確認。

ubuntu@icp31-single:~/workspace/charts/stable$ curl -k https://mycluster.icp/liberty/hellomysql/HelloServlet
user1
user2
user3
user4
user5
user6
Served at: /hellomysqlubuntu@icp31-single:~/workspace/charts/stable$

以上。

参考リンク

28
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
17