Kubernetes の ConfigMap は、アプリケーション設定をコードから分離する便利な仕組みです。
しかし、複数のファイルを ConfigMap として 1 つの Pod 上のディレクトリにマウントしたい場合、単純な volume 参照だけでは管理しづらくなるケースがあります。
この記事では、次の 3 パターンを比較・紹介します。
- ConfigMap に複数ファイルを定義する
 - ConfigMap をファイル単位で分割し、
projectedvolume で統合する - kustomize を使ってファイル群から ConfigMap を自動生成する
 
ConfigMap に複数ファイルを定義する(volume)
まずは最も基本的な方法です。
下記のような ConfigMap を用意すれば、複数のファイルを Pod の volume にマウントできます。
apiVersion: v1
kind: ConfigMap
metadata:
  name: multiple-config
data:
  file1.json: |
    {
      "key": "AAA"
    }
  file2.json: |
    {
      "key": "BBB"
    }
Pod のマニフェストは以下のようになります。
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
    - image: nginx
      name: app
      volumeMounts:
        - mountPath: /etc/config
          name: multiple-config-volume
  volumes:
    - name: multiple-config-volume
      configMap:
        name: multiple-config
この構成では /etc/config/ 配下に file1.json と file2.json がファイルとしてマウントされます。
> kubectl exec -it sample-pod -- ls /etc/config
file1.json  file2.json
> kubectl exec -it sample-pod -- cat /etc/config/file1.json
{
  "key": "AAA"
}
この構成の課題
file1.json と file2.json の両方を同じ configmap.yaml に記述しているため、片方を変更した際も同じファイルに手を入れる必要があります。
影響範囲が広く、誤変更のリスクが高まります。
ConfigMap をファイル単位で分割し、projected volume で統合する
上記の問題を解消するには、ファイルごとに ConfigMap を分割し、projected volume を使って 1 つのディレクトリにまとめてマウントする方法があります。
apiVersion: v1
kind: ConfigMap
metadata:
  name: multiple-config-file1
data:
  file1.json: |
    {
      "key": "AAA"
    }
apiVersion: v1
kind: ConfigMap
metadata:
  name: multiple-config-file2
data:
  file2.json: |
    {
      "key": "BBB"
    }
Pod 側では projected volume を定義します。
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
    - image: nginx
      name: app
      volumeMounts:
        - mountPath: /etc/config
          name: multiple-config-volume
  volumes:
    - name: multiple-config-volume
      projected:
        sources:
          - configMap:
              name: multiple-config-file1
          - configMap:
              name: multiple-config-file2
これにより、file1.json と file2.json をそれぞれ独立した ConfigMap として管理しながら、Pod 内では同じディレクトリにマウントできます。
> kubectl exec -it sample-pod -- ls /etc/config
file1.json  file2.json
> kubectl exec -it sample-pod -- cat /etc/config/file2.json
{
  "key": "BBB"
}
kustomize で ConfigMap をファイル群から自動生成する
kustomize を使用している場合、configMapGenerator を使うことで複数ファイルから ConfigMap を簡単に生成できます。
ファイル構成(例)
.
├── config/
│   ├── file1.json
│   └── file2.json
├── kustomization.yaml
{
  "key": "AAA"
}
{
  "key": "BBB"
}
kustomization.yaml の定義
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
  - name: multiple-config
    files:
      - config/file1.json
      - config/file2.json
kustomize build . を実行すると、以下のような ConfigMap が生成されます。
apiVersion: v1
data:
  file1.json: "{\r\n  \"key\": \"AAA\"\r\n}\r\n"
  file2.json: "{\r\n  \"key\": \"BBB\"\r\n}\r\n"
kind: ConfigMap
metadata:
  name: multiple-config-456ttgghmb
生成される ConfigMap の名前には、内容に基づいたハッシュが付与されます。
これは中身の変更を検知し、Pod の再作成を促す効果があります。
サフィックスを無効にするには?
ハッシュ付きの名前が不要な場合は、次のように generatorOptions を設定します。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
  - name: multiple-config
    files:
      - config/file1.json
      - config/file2.json
    options:
      disableNameSuffixHash: true
まとめ
| 方法 | 特徴 | 向いているケース | 
|---|---|---|
| 単一の ConfigMap に複数ファイル | 一番シンプル | 小規模構成・頻繁な更新がない | 
| projected volume で統合 | ファイルごとに ConfigMap 分割可能 | 設定ごとに責任分離したい場合 | 
| kustomize で生成 | ファイルから自動生成できる | GitOps・IaCを採用しているプロジェクト |