ConfigMapを使って任意のファイルをpod内に生成する


(2020/10/30作成)

はじめに

最近kubernetesを触り始めて、kustomizeでpodを立てることを学んでいる。
その中でConfigMapを作ってpod内にファイル生成をする方法が何となく理解できたので、アウトプットしてみた。

大体のことは公式ドキュメントに書いてあるのでそちらを参照されたし

ConfigMapとは

  • 設定情報などのKey-Vlaueで保持できるデータを保存しておくリソース
  • podに置きたいファイル、設定したい環境変数などをマニフェストとして持つことができる
  • パスワードなど、暗号化したい情報はSecretを使う、という使い分けがある

環境

kubernetes v1.18.1

やりたいこと

  • k8sでpodを立てるときに、pod内の特定のvolumeパスに任意のファイルを生成したい

手順

  1. 生成したいファイルをConfigMap化する(ConfigMapGenerator)
  2. pod内のvolume pathを定義する(volumeMounts)
  3. 2で定義したパスに対してどのようなファイルを生成するかを記述する(volumes)
  4. kustomize buildコマンドを実行する
  5. applyする

  • pod内の/hoge/fuga配下にA.txtを配置する。
  • A.txtは手元のファイルを元に作成。

概要図

※比較のためにB.txtを書いているが以下の詳細ではB.txtの作成は省略する

ディレクトリ構成

.
├── kustomization.yml
├── deployment.yml
└── A.txt

ConfigMapGeneratorを書く

  • ConfigMapGeneratorを利用する利点としては以下
    • ConfigMapのyamlファイルを自分で作成する必要がない
    • 元ファイルとマニフェストを分離できる
      (Aファイルをpodに置きたいと思ったらAファイルを用意すればいい)

逆に言えば、ConfigMapGeneratorを利用しないでも、自分でkind: ConfigMapのyamlを用意して、その中のValueとして配置したいファイルの中身が書いてあればよい

-> 別でConfigMapのyamlを用意する場合

  • 今回の例の場合A.txtを元にpod内に同じA.txtを配置したいので以下となる。
kustomization.yml
resources:
- deployment.yml

configMapGenerator:
- name: ConfigMapA  #作成されるConfigMapの識別名
  files: 
  - A.txt  #元となるファイルを記載
A.txt
aaa
bb
cccc
  • これにkusomize buildコマンドを実行することにより以下のようなマニフェストが作成される
<省略>
data:
  A.txt: |-  # ファイル名が"key"に、中身が"Value"になる
    aaa
    bb
    cccc
kind: ConfigMap
metadata:
  name: ConfigMapA-<乱数> #なぜか最後に乱数が入る
<省略>

pod内のvolume pathを定義する(volumeMounts)

  • deployment.yml.spec.containers[].volumeMounts[]を記述。
  • 今回のファイル作成先となる/hoge/fugaを定義する。
deployment.yml
kind: Deployment
<省略>
    spec:
    containers:
    - name: sample
        image: sample-image
        volumeMounts:
        - name: path-a  #Volumeパスの識別名
        mountPath: "/hoge/fuga"  #デフォルトで無ければパスが作成される

定義したパスに対してどのようなファイルを生成するかを記述する(volumes)

  • ConfigMapGeneratorで作成されるConfigMapAを用いる
  • ConfigMapA内のどの箇所(key)を使って、何という名前(path)のファイルを生成するかを書く
deployment.yml
kind: Deployment
<省略>
    spec:
    containers:
    <省略>
        volumes:
            - name: path-a  #上でマウントしたVolumeパスを指定
            configMap:  #ConfigMapを元にファイルを作成することを宣言
                name: ConfigMapA  #ConfigMapを識別
                items:
                - key: A.txt #ConfigMapAの中の"key"を指定
                  path: A.txt #pod内に作成するファイル名を記載

kustomize buildコマンドを実行する

  • ConfigMapとdeployment.ymlが合わさったマニフェストが作成される。
  • 作成されたConfigMapのnameは、上で書いたように指定したConfigMapAではなくConfigMapA-<乱数>となるが、Volumesでの指定も勝手に書き換えてくれるのでOK
kustomize build . > kustomize-deployment.yml

applyする

kubectl apply -f kustomize-deployment.yml
  • podが立ち上がったら
kubectl exec -it <pod名> /bin/bash

などでpod内に想定通りファイルがあるか確認してみてください。

おまけ

別でConfigMapのyamlを用意する場合

  • kind: ConfigMapのyamlを書くだけ
  • ファイルを元にConfigMapを作成するのはコマンドでもできる
    • metadata.nameはConfigMapの識別名となる。(マニフェスト内で指定されるのはこっち。ConfigMapのファイル名は何でもいいし使われない)
kubectl create configmap --dry-run=client <metadata.name> --from-file=<file> -o yaml > <hoge>.yml

patchファイルを用いる場合のvolumes

  • いわゆる以下のような構成で、素のdeploymentを用意して、patchを当ててkustomizeを管理する場合
.
├── base
│   ├── kustomization.yml
│   └── deployment.yml
└── overlays
    └── prod
        ├── kustomization.yml
        ├── patch-deployment.yml
        └── A.txt
  • deployment.ymlで先にディレクトリを定義をしたければ、下記のように空のディレクトリを宣言し、
base/deployment.yml
      volumes:        
        - name: path-a
          emptyDir: {}
  • patch-deployment.yml側でnullであることを改めて宣言し直さなければいけない
overlays/patch-deployment.yml
      volumes:
        - name: path-a
          emptyDir: null
          configMap:
            name: ConfigMapA
            items:
              - key:
                path:
  • patchの方でディレクトリパスを定義すればこんなことにはならなそうですが