kustomizeで復数環境のマニフェストファイルを簡単整理

2021年6月18日(金)
千村 健太朗

develop用の環境設定

続いて、develop環境用のoverlays/developを構成しましょう。baseとの差分がproductionよりも少し多いですが、ひとつひとつ整理して配置すれば難しくありません。overlays/developのディレクトリは下記のようになりました。

overlays/develop/
├── config
│   ├── accesscount
│   │   └── config.env
│   ├── accesscountdb
│   │   ├── config.env
│   │   └── schema.sql
│   ├── article
│   │   └── config.env
│   ├── articledb
│   │   └── schema.sql
│   ├── rank
│   │   └── config.env
│   ├── rankdb
│   │   └── schema.sql
│   └── website
│       └── config.env
├── deployment-accesscount.yaml
├── deployment-article.yaml
├── deployment-rank.yaml
├── deployment-website.yaml
├── kustomization.yaml
├── service-accesscountdb.yaml
├── service-articledb.yaml
├── service-rankdb.yaml
├── statefulset-accesscountdb.yaml
├── statefulset-articledb.yaml
└── statefulset-rankdb.yaml

随分とファイルが多くなっていますが、これだけではよく分かりませんね。続けて、kustomization.yamlを見てみましょう。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../base
- statefulset-articledb.yaml
- service-articledb.yaml
- statefulset-accesscountdb.yaml
- service-accesscountdb.yaml
- statefulset-rankdb.yaml
- service-rankdb.yaml

secretGenerator:
- name: article-config
  envs:
  - config/article/config.env
- name: accesscount-config
  envs:
  - config/accesscount/config.env
- name: rank-config
  envs:
  - config/rank/config.env

configMapGenerator:
- name: website-config
  envs:
  - config/website/config.env

images:
- name: article
  newName: registry.gitlab.com/creationline/thinkit-kubernetes-sample1/article
  newTag: dev
- name: accesscount
  newName: registry.gitlab.com/creationline/thinkit-kubernetes-sample1/accesscount
  newTag: dev
- name: rank
  newName: registry.gitlab.com/creationline/thinkit-kubernetes-sample1/rank
  newTag: dev
- name: website
  newName: registry.gitlab.com/creationline/thinkit-kubernetes-sample1/website
  newTag: dev

patches:
- deployment-accesscount.yaml
- deployment-article.yaml
- deployment-rank.yaml
- deployment-website.yaml

こちらも、上から見ていきます。resourcesフィールドでは、baseに加えてdevelop環境でのみ読み込むDB用のマニフェストを指定します。同一ディレクトリに配置されているyamlファイルが読み込まれています。

secretGenerator、configMapGenerator、imagesはproduction環境と同様です。imageのnewTagbがprodではなくdevになっていますね。

patchフィールドでマニフェストに設定を追加する

さて、一番下にpatchesという新しいフィールドが出てきています。ここにpatch用のyamlファイルを指定することで、もともとresourcesで指定していたyamlファイルに修正を加えることができます。deployment-article.yamlのパッチファイルを見てみましょう。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: article
spec:
  template:
    spec:
      containers:
      - name: article
        env:
        - name: DEBUG
          value: 'false'
        - name: ENABLE_DEBUGGER
          value: 'false'
        - name: DEBUGGER_PORT
          value: '8000'
        ports:
        - name: debugger
          containerPort: 8000
          protocol: TCP

一見するとシンプルなDeploymentのマニフェストですが、必須のはずのimage等の指定がありません。これは、本来適用したいdevelop環境用のマニフェストと、共通部分のbaseに記述したマニフェストの差分のみを取り出して記述しているためです。articleコンテナに環境変数とport指定をしています。kustomizeを利用することで、この差分のみを記述したマニフェストをbaseのマニフェストにマージできます。

それでは、実際に出力してみましょう。

$ kubectl kustomize overlays/develop/

ここでも全てのマニフェストが出力されますが、一部を抜粋して記載します。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: article
  name: article
spec:
  replicas: 1
  selector:
    matchLabels:
      app: article
  template:
    metadata:
      labels:
        app: article
    spec:
      containers:
      - env:
        - name: DEBUG
          value: "false"
        - name: ENABLE_DEBUGGER
          value: "false"
        - name: DEBUGGER_PORT
          value: "8000"
        envFrom:
        - secretRef:
            name: article-config-994cb4cf7h
        image: registry.gitlab.com/creationline/thinkit-kubernetes-sample1/article:dev
        name: article
        ports:
        - containerPort: 8000
          name: debugger
          protocol: TCP
        - containerPort: 8080
          name: web
          protocol: TCP
        resources:
          limits:
            cpu: "1"
            memory: 2Gi
          requests:
            cpu: 200m
            memory: 512Mi
### 省略
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: accesscountdb
  name: accesscountdb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: accesscountdb
### 省略

Deploymentのマニフェストに環境変数とport指定が反映されていることが分かります。また、develop環境のみで適用するstatefulsetのマニフェストも反映されています。

実際に、これらのマニフェストをkubernetesクラスタに適用してみましょう。前回と同じアプリケーションが動くはずです。

kubectl apply -k overlays/develop/

よく使われるプラグイン

今回は、kustomizeのプラグインとしてimages、configMapGenerator、secretGenerator、patchesを紹介しました。これ以外にも様々なプラグインがあるので、代表的なものをまとめて紹介します。詳細は公式ドキュメントをご参照ください。

ConfigMapGenerator

ConfigMapGeneratorはConfigMapを定義するためのプラグインです。ConfigMapはSecretと並び、しばしば環境ごとに異なる値が設定されるリソースで、kustomizeではより簡易にConfigMapを環境ごとに定義できます。

ConfigMapGeneratorにはfile形式、env file形式、literal形式の3通りの設定方法があります。それぞれ見ていきましょう。file形式では、ファイルの内容をそのままconfigmapに設定します。設定値と出力されるConfigMapは下記のとおりです。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: config-file
  files:
  - config.file
$ cat config.file
hoge-data...
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-file-fdcbe09876
data:
  config.file: hoge-data...

env形式もfile形式と同じくファイルを取り込んで内容をconfigmapに設定しますが、ファイルの内容をkey-value形式で取り込みます。設定値および出力されるConfigMapは下記のとおりです。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: config-env
  envs:
  - config/website/config.env
$ cat config.env
hoge=fuga
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-file-fdcbe09876
data:
  hoge: fuga

literal形式ではファイルを取り込まず、直接key-valueの値を設定します。ConfigMapそのものの記法と同じです。設定値および出力されるConfigMapは下記のとおりです。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: config-literal
  literals:
  - hoge=fuga
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-file-fdcbe09876
data:
  hoge: fuga

SecretGenerator

SecretGeneratorはSecretを定義するためのプラグインです。機能と使い方はConfigMapGeneratorとほぼ同じですが、Secretのtypeを指定するフィールドを使うことができます。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: app-tls
  files:
  - secret/tls.cert
  - secret/tls.key
  type: "kubernetes.io/tls"

ImageTagTransformer

ImageTagTransformerは、Podのimageを書き換えるTransformerです。imagesフィールドで指定します。newName、newTagを指定することでimage名とtagをそれぞれ別個に書き換えることができます。マニフェストの中でimageタグは特に書き換わることが多いフィールドですが、ImageTagTransformerを使うと一括ですべてのマニフェストを変更できて非常に便利です。ただし、一部のマニフェストのみに変更を適用することはできないので、注意しましょう。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: hoge
  newName: registry.gitlab.com/creationline/hoge
  newTag: dev

ちなみに、これまで出てきたGeneratorは新たにリソースを作成するプラグインですが、Transformerはresourcesで読み込まれたリソースのマニフェストを書き換えるプラグインです。

LabelTransformer

LabelTransformerはリソースのlabelを書き換えるTransformerです。commonLabelsフィールドで指定します。PodやServiceなど、リソースの種類によらず、すべてのリソースに適用されますが、すでにkeyが存在する場合は上書きされます。アプリケーション単位で、識別用に共通のLabelを付けてリソースを管理したい場合などに便利です。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
  hoge: fuga

NamespaceTransformer

NamespaceTransformerはリソースのnamespaceを書き換えるTransformerです。namespaceフィールドで指定します。こちらも、すでに値が設定されている場合には上書きされます。アプリケーション単位でnamespaceを分けている場合には、一括で付与できるため非常に便利です。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: hoge-namespace

ReplicaCountTransformer

ReplicaCountTransformerはDeploymentリソースやStatefulSetリソースのレプリカ数を書き換えるTransformerです。replicasフィールドで指定します。Autoscalerを使わず、replica数をマニフェスト上で管理している場合に使うことができます。対象となるDeploymentリソース単体ごとに指定するため一括で設定できるというメリットはありませんが、環境ごとにレプリカ数が異なる場合に差分を見やすく管理できます。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
replicas:
- name: hoge-deployment
  count: 3

PatchTransformer

PatchTransformerはリソースを任意に変更できる強力なTransformerです。patchesフィールドで指定します。今回の例で紹介したように、マニフェストを表すyamlファイル同士を結合して出力できます。差分のみを表すパッチ用のyamlファイルをoverlays配下に配置することで、環境ごとの差分を非常に柔軟に切り出すことができます。

今回紹介したyamlファイルの単純なマージの他にも、JSONパッチの形式でyamlファイルを操作できます。単純なマージではすでにyamlファイルに存在するフィールドを削除できませんが、JSONパッチでremoveオペレーションを指定することで削除できるようになります。それぞれkubectlのpatchサブコマンドと同等の機能を提供します。

下記は、DeploymentリソースからlivenessProbeフィールドを削除する例です。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patches:
- patch: |-
    - op: remove
      path: /spec/template/spec/containers/0/livenessProbe
  target:
    group: apps
    version: v1
    kind: Deployment
    name: hoge-deployment

kustomizeでは、他にも様々なプラグインが用意されています。ぜひ、公式ドキュメントを参考に試してみてください。また、要件を満たすプラグインがない場合は、拡張プラグインを自作することもできます。

おわりに

今回は、kustomizeを利用して環境差分を吸収する構成を取りました。環境差分を吸収する他にも、頻繁に設定を変更するコンテナイメージ等の項目を切り出すことで変更がしやすくなったりと、使用するメリットは大きいです。必ずしも使わなければならないものではありませんが、マニフェストが複雑になってきたな…と感じた際には、適用を検討してみましょう。

次回は、ここ2回でしれっと登場していた「StatefulSet」と「Volume」について解説します。データベースなど、StatefulなアプリケーションをKubernetes上で実行するために重要なコンポーネントです。お楽しみに!

クリエーションライン株式会社 Exploratory Development & Incubation Team
クリエーションライン株式会社 EDIT所属、Linux Foundation公認kubernetesインストラクター。アプリケーション開発と千台規模のオンプレミスサーバ運用を経て、DevOpsとkubernetesの世界に触れる。 現在はKubernetes基盤の構築やサポートやトレーニングに従事。富山事業所メンバーと富山を盛り上げるべく活動中。
Twitter: https://twitter.com/cl_toyama

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています