この記事ではHelmのChart(チャート)の作り方と公開方法を紹介します。
前の記事はこちら→ 【手順あり】実際に使ってみて学ぼう「kubernetes Helm」とは? - フラミナル
環境
名前 | バージョン |
---|---|
OS | CentOS Linux release 7.6.1810 (Core) |
kubelet | v1.18.1 |
kubeadm | v1.18.1 |
docker | v1.13.1 |
Helm | v2.16.5 |
作業手順
前提
- kubernetesがインストール済みである
- Helm Clientがインストール済みである
- Helm initが完了している
終わってない場合はこちらの記事の内容を実施してください。
・【手順あり】実際に使ってみて学ぼう「kubernetes Helm」とは? - フラミナル
Helmチャートの雛形作成
まずは雛形を作ります。
[root@master helm-practice]# helm create sample-chart Creating sample-chart
そうするとこのようなファイル群が作成されます。
[root@master helm-practice]# tree sample-chart/ sample-chart/ |-- Chart.yaml |-- charts |-- templates | |-- NOTES.txt | |-- _helpers.tpl | |-- deployment.yaml | |-- ingress.yaml | |-- service.yaml | |-- serviceaccount.yaml | `-- tests | `-- test-connection.yaml `-- values.yaml 3 directories, 9 files
全て使う必要はないのですが代表的なものが含まれています。
Helmのパッケージはテンプレートと変数ファイルで成り立っています。変数ファイルで指定された変数をテンプレートに埋め込み、それをHelmのtiller podに渡しています。
テンプレート(sample-chart/templates/service.yaml)
apiVersion: v1 kind: Service metadata: name: {{ include "sample-chart.fullname" . }} labels: {{ include "sample-chart.labels" . | indent 4 }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http protocol: TCP name: http selector: app.kubernetes.io/name: {{ include "sample-chart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }}
変数ファイル(sample-chart/values.yaml)
Default values for sample-chart. # This is a YAML-formatted file. # Declare variables to be passed into your templates. replicaCount: 1 image: repository: nginx tag: stable pullPolicy: IfNotPresent imagePullSecrets: [] nameOverride: "" fullnameOverride: "" serviceAccount: # Specifies whether a service account should be created create: true # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template name: podSecurityContext: {} # fsGroup: 2000 securityContext: {} # capabilities: # drop: # - ALL # readOnlyRootFilesystem: true # runAsNonRoot: true # runAsUser: 1000 service: type: ClusterIP port: 80 ingress: enabled: false annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: - host: chart-example.local paths: [] tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following # lines, adjust them as necessary, and remove the curly braces after 'resources:'. # limits: # cpu: 100m # memory: 128Mi # requests: # cpu: 100m # memory: 128Mi nodeSelector: {} tolerations: [] affinity: {}
テンプレート(sample-chart/templates/service.yaml)の修正
NodePortで提供したいので変更しましょう。
apiVersion: v1
kind: Service
metadata:
name: {{ include "sample-chart.fullname" . }}
labels:
{{ include "sample-chart.labels" . | indent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
+ nodePort: {{ .Values.service.nodePort }}
selector:
app.kubernetes.io/name: {{ include "sample-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
変数ファイル(sample-chart/values.yaml)の修正
securityContext: {} # capabilities: # drop: # - ALL # readOnlyRootFilesystem: true # runAsNonRoot: true # runAsUser: 1000 service: - type: ClusterIP + type: NodePort port: 80 + nodePort: 30088 ingress: enabled: false annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: - host: chart-example.local paths: []
Helmチャートを実行してみる
今作ったチャートを実行してみましょう。
[root@master helm-practice]# helm install --name sample-helm sample-chart NAME: sample-helm LAST DEPLOYED: Tue Apr 14 19:09:11 2020 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE sample-helm-sample-chart 0/1 1 0 0s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE sample-helm-sample-chart-b5bc67674-m4c6c 0/1 ContainerCreating 0 1s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-helm-sample-chart NodePort 10.107.170.223 <none> 80:30088/TCP 0s ==> v1/ServiceAccount NAME SECRETS AGE sample-helm-sample-chart 1 0s NOTES: 1. Get the application URL by running these commands: export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services sample-helm-sample-chart) export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT
起動の確認をします。
[root@master helm-practice]# kubectl get pods |grep sample sample-helm-sample-chart-b5bc67674-m4c6c 1/1 Running 0 97s [root@master helm-practice]# [root@master helm-practice]# kubectl get svc | grep sample sample-helm-sample-chart NodePort 10.107.170.223 <none> 80:30088/TCP 2m11s
NodePort
も問題なく指定できていますね。curl
を叩くとアクセスもできます。
[root@master helm-practice]# curl 0.0.0.0:30088 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
もう使わないので削除しましょう。
[root@master helm-practice]# helm delete sample-helm release "sample-helm" deleted
作ったチャートをパッケージ化して公開しよう
チャートのパッケージ化
まずは作ったチャートをtgz形式にパッケージ化します。
[root@master helm-practice]# helm package --dependency-update --save=false ./sample-chart/ No requirements found in /home/vagrant/k8s-sample/helm-practice/sample-chart/charts. Successfully packaged chart and saved it to: /home/vagrant/k8s-sample/helm-practice/sample-chart-0.1.0.tgz
そしてリポジトリ用のindex.yaml
を生成します。
[root@master helm-practice]# helm repo index . [root@master helm-practice]# cat index.yaml apiVersion: v1 entries: sample-chart: - apiVersion: v1 appVersion: "1.0" created: "2020-04-14T19:24:27.135096708Z" description: A Helm chart for Kubernetes digest: 329f538550d312826a6ae2554a4e5e4da939d37baa02078d7a98c9692c458e81 name: sample-chart urls: - sample-chart-0.1.0.tgz version: 0.1.0 generated: "2020-04-14T19:24:27.133923454Z"
チャートをリポジトリへ追加
続いてこれをリポジトリに追加します。
今回はローカルにWebサーバを立ち上げてそこに置いてみることにします。
[root@master helm-practice]# python -m SimpleHTTPServer 30000 & [1] 16411
このコマンドで先ほどsample-chart-0.1.0.tgz
を作ったところをルートディレクトリとするHTTPサーバが起動しました。ブラウザでアクセスするとこんな風に見えます。
これをhelmのリポジトリに追加してあげましょう。myrepo
という名前で登録してみます。
[root@master helm-practice]# helm repo add myrepo http://0.0.0.0:30000 127.0.0.1 - - [14/Apr/2020 19:25:04] "GET /index.yaml HTTP/1.1" 200 - "myrepo" has been added to your repositories
無事登録ができたらhelm search
で作ったものを検索しましょう。
[root@master helm-practice]# helm search sample-chart NAME CHART VERSION APP VERSION DESCRIPTION myrepo/sample-chart 0.1.0 1.0 A Helm chart for Kubernetes
作ったチャートをkubernetesに適用してみる
では、おいたHelmチャートを実際に使ってみましょう!
[root@master helm-practice]# helm install sample-chart --name sample-chart-from-myrepo NAME: sample-chart-from-myrepo LAST DEPLOYED: Tue Apr 14 19:27:12 2020 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE sample-chart-from-myrepo 0/1 1 0 0s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE sample-chart-from-myrepo-58dc894c44-zxmpd 0/1 ContainerCreating 0 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-chart-from-myrepo NodePort 10.104.137.39 <none> 80:30088/TCP 0s ==> v1/ServiceAccount NAME SECRETS AGE sample-chart-from-myrepo 1 0s NOTES: 1. Get the application URL by running these commands: export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services sample-chart-from-myrepo) export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT
ここまでできたら先ほど同様に動作チェックです。
[root@master helm-practice]# kubectl get pods | grep myrepo sample-chart-from-myrepo-58dc894c44-zxmpd 1/1 Running 0 2m2s [root@master helm-practice]# [root@master helm-practice]# kubectl get svc | grep myrepo sample-chart-from-myrepo NodePort 10.104.137.39 <none> 80:30088/TCP 2m13s [root@master helm-practice]# [root@master helm-practice]# [root@master helm-practice]# curl 0.0.0.0:30088 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
以上で終了です、お疲れ様でした。
いかがだったでしょうか。Helmでのチャート管理と公開が意外に簡単にできたんじゃないかと思います。
参考
こちらはHelmをもう少し学んでみたい方向けの書籍です。