Helm ChartのTemplate機能を使ってみる

# はじめに

Helmは、Kubernetesアプリケーションにおけるパッケージマネジャーです。
この記事では、テンプレート機能を使ったミニマムなHelm Chartを作成することにより、Template機能の概要について説明します。

Helm Chartについての基本的な概念は、以下の記事で解説しています。興味があればぜひご覧ください。

https://qiita.com/tobita_yoshiki/items/b6c37681d43c6ac8a85a

また、この記事で取り扱うマニフェストファイルや設定ファイルは、以下のリポジトリにあります。

Github: https://github.com/cacapouh/helm-chart-minimum-example/tree/template

# Template機能のざっくり説明

Helm Chartで取り扱うマニフェストファイルでは、Go Templateが利用可能です。
Go TemplateはGo言語で使用可能なテンプレートエンジンです。

テンプレートで利用可能な値は様々ですが、この記事では `Release`, `Values`, `Chart` を取り上げます。

* Releaseオブジェクト
  * リリース情報を持ったオブジェクトで、`Release.Name`や`Release.Namespace`といった値が利用可能です
* Valuesオブジェクト
  * `values.yaml`もしくはユーザー指定のファイルにて定義された値を保持するオブジェクトです
* Chartオブジェクト
  * `Chart.yaml`にて定義された値を保持するオブジェクトです

参考までに、テンプレートで利用可能な値は[こちら](https://helm.sh/docs/chart_template_guide/builtin_objects/)にまとまっています。

# デプロイ対象のアプリ

サンプルアプリとして、Template機能によって生成された値を標準出力するPythonのスクリプトを作成します。

Deploymentのマニフェストファイルで、環境変数をTemplateとして用意し、
環境変数をPythonのスクリプトで標準出力します。

以下はサンプルアプリの概要図になります。

![名称未設定ファイル.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422592/02eb7534-6248-c9c9-c08c-96f993d52405.png)

## Pythonスクリプト

`RELEASE`, `CHART`, `VALUES`という3つの環境変数を標準出力するようにしています。

```python:main.py
import os

if __name__ == '__main__':
    print(os.environ.get('RELEASE'))
    print(os.environ.get('CHART'))
    print(os.environ.get('VALUES'))
```

## Dockerfile

以下は、上記のPythonスクリプト用のイメージを生成するためのDockerfileです。

```Dockerfile:Dockerfile
FROM python:3.9.18-slim

RUN mkdir /work
WORKDIR /work

COPY main.py /work
ENTRYPOINT python main.py
```

## マニフェストファイル

以下は、デプロイ対象のマニフェストファイルです。

マニフェストファイルでは、
Pythonスクリプトから参照する3つの環境変数を、`spec.template.spec.containers.env`で定義しています。

このファイルでは`env.value`でテンプレート機能を使っています。

* `.Release.Name`, `.Release.Namespace`は[組み込みで用意されたもの](https://helm.sh/docs/chart_template_guide/builtin_objects/)です
* `.Chart.Name`, `.Chart.Version`は、`Chart.yml`ファイルに存在する値に置き換えられます
* `.Values.name`は`values.yml`ファイルに存在する値に置き換えられます
    * `helm install`する際に`--values`オプションで明示的に値を保持したファイルを指定することも可能です

```yml:deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-app-deployment
  labels:
    app: simple-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: simple-app
  template:
    metadata:
      labels:
        app: simple-app
    spec:
      containers:
        - name: simple-app
          image: "simple-app:latest"
          imagePullPolicy: IfNotPresent
          env:
            - name: RELEASE
              value: "{{ .Release.Name }}, {{ .Release.Namespace }}"
            - name: CHART
              value: "{{ .Chart.Name }}, {{ .Chart.Version }}"
            - name: VALUES
              value: "{{ .Values.name }}"
```

## Values用のファイル

マニフェストファイルで、`.Values.name`を参照していますが、
以下はこの設定値に対応するファイルになります。

`helm insatll`時に、
`--values devel-values.yml`とすると、「開発用設定」と標準出力されます。
`--values prod-values.yml`とすると、「本番設定」と標準出力されます。


```yml:devel-values.yml
name: "開発用設定"
```

```yml:prod-values.yml
name: "本番設定"
```

# devel-values.ymlを使ったサンプルアプリのデプロイ

以下は`devel-values.yml`を使って、サンプルアプリをデプロイし、
標準出力された内容を確かめた結果です。

`Release`, `Chart`, `Values`オブジェクトが持つ値がそれぞれ標準出力されています。

```
$ helm install ./simple-app --generate-name --values simple-app/devel-values.yml
NAME: simple-app-1704551432
LAST DEPLOYED: Sat Jan  6 23:30:33 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

$ kubectl get pods
NAME                                     READY   STATUS      RESTARTS   AGE
simple-app-deployment-676fdf5c75-4l96m   0/1     Completed   0          2s
simple-app-deployment-676fdf5c75-7srrf   0/1     Completed   0          2s

$ kubectl logs simple-app-deployment-676fdf5c75-4l96m
simple-app-1704551432, default
simple-app, 0.1.0
開発用設定
```

# prod-values.ymlを使ったサンプルアプリのデプロイ

同様に、以下はprod-values.ymlを使ってデプロイした結果です。

```
$ helm install ./simple-app --generate-name --values simple-app/prod-values.yml 
NAME: simple-app-1704551521
LAST DEPLOYED: Sat Jan  6 23:32:01 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

$ kubectl get pods
NAME                                   READY   STATUS      RESTARTS     AGE
simple-app-deployment-5b77bc47-cmzqf   0/1     Completed   1 (6s ago)   6s
simple-app-deployment-5b77bc47-tvltx   0/1     Completed   1 (6s ago)   6s

$ kubectl logs simple-app-deployment-5b77bc47-cmzqf
simple-app-1704551521, default
simple-app, 0.1.0
本番設定
```

# おわりに

HelmのTemplate機能を使って簡素なアプリケーションがデプロイできました :thumbsup: