【Kubernetes】ConfigMapとは(概要から生成・利用方法まで) | 若手エンジニアのブログ

若手エンジニアのブログ

文系出身の若手女子エンジニアによる技術ブログ。
日々の経験や学びをアウトプットするためにブログを書いています。
バックエンド(Java+SpringFramework)を経てインフラエンジニアになりました。
今は育休中につき、本で勉強したことを中心にアウトプットしています。

今回はKubernetes(以下k8s)のConfigMapについてまとめていきます。

 

もくじ

1.ConfigMapとは 
 (概要ConfigMapの特徴と注意点

2.ConfigMap作成方法
 (通常マニフェスト利用ディレクトリ利用ファイル利用リテラル利用ConfigMapGenerator利用

3.ConfigMap利用方法
環境変数として個別利用環境変数としてまるごと利用Volumeとしてマウント

参考文献

 

■ConfigMapとは

◎概要

設定情報などのデータを、Key-Value形式で保存しておくリソース。

言い換えると、環境変数を登録しておけるリソース。

 

ConfigMapは、k8sのConfig & Storageリソースの1つにあたり、k8sのVolumeプラグインの1つでもある。

 

なお、パスワードなどの機密情報の保存には向かない。

機密情報の安全な保管には、Sercretというリ別のソースを使うべきである。

 

◎ConfigMapの特徴と注意点

・ConfigMapのマニフェストファイルには、キーと値を保管しておくためのdataセクションがある。
・ConfigMap名は、DNSのサブドメイン名に一致している必要がある。
・PodとConfigMapは同じネームスペース上にある必要がある。

 

■ConfigMap生成方法

ConfigMapの生成方法は大きく5種類ある。

個人的には、k8sのv1.14以降で使える、ConfigMapGenerator(kustomization.yaml)を使う方法がおすすめ。

 

◎通常マニフェスト利用

マニフェストファイルの作成例を以下に示す。

※データの中身は公式サイトからそのまま使わせて頂きました

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-example
data:
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

 

・kindはそのままConfigMapでOK。

・data部分に、 「キー名: 値」となるように、設定値を記述していく。

・値が複数行にわたる場合(配列的なかんじ)は、

 キー: |

     キー1=値

   キー2=値

   :

というように記述していく。

・キー名は、「.」または「_」の記号を使える。

 

長所としては、他のyamlファイルと似た要領で書けること。

一方で、ConfigMapリソースに値をそのままべた書きするため、修正時はリソースをあげ直す必要はある。

 

◎ディレクトリ利用

指定したディレクトリ内にある有効なファイル(サブディレクトリ、シンボリックリンク等は含まれない)から、1つのConfigMapを生成する方法。

後に述べるファイル利用による生成とは異なり、ディレクトリ内の有効な全ファイルを1つにまとめてくれるため、複数ファイルを1つのConfigMapに統合したい時に活用する。

 

<基本のコマンド>

 kubectl create configmap (ConfigMap名) --from-file=(ディレクトリパス)

 

<詳細&使用例>

 https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#create-configmaps-from-directories

 

◎ファイル利用

「キー=バリュー」形式で記述したファイルをあらかじめ準備し、ファイルから生成する方法。

前述のディレクトリ利用とは異なり、生成元のファイルを個別に指定したい時に活用する。

<基本のコマンド>

 kubectl create configmap (ConfigMap名) --file-name=(ファイルのパス)

 

<複数ファイルから生成したい時>

"--file-name"以下を連ねて書いていけばOK。

 kubectl create configmap (ConfigMap名) --file-name=(ファイル1のパス) --file-name=(ファイル2のパス) …

 

<ConfigMapのキー名を変えたい時>

基本のコマンドでConfigMapを生成すると、ConfigMapで定義されたキーにアクセスするためには

「もとのファイル名.キー名」を指定する必要がある。

この時、「もとのファイル名」部分を、ファイル名以外の名称に変えたい場合は、以下のようにConfigMapを生成する。

 kubectl create configmap (ConfigMap名) --file-name=(もとのファイル名に代わる名称)=(ファイルのパス) 

 

<詳細&使用例>

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#create-configmaps-from-files

 

◎リテラル利用

「キー=バリュー」の設定値を直接指定して、ConfigMapを生成する時に利用する。

個別生成のため、とてもじゃないけど管理しきれない。ので、使いどころは、試しにConfigMapを設定してみたいといった時に限られそう。。

 

<基本のコマンド>

 kubectl create configmap (ConfigMap名) --from-literal=(キー)=(バリュ-)

 

<詳細&使用例>

https://kubernetes.io/ja/docs/tasks/configure-pod-container/configure-pod-configmap/#create-configmaps-from-literal-values

 

◎ConfigMapGeneratorの利用

公式には小難しく「ジェネレーター」と書かれている手法だが、簡単に言うと、

ディレクトリやファイル、リテラルから、手打ちで「kubectl create」してきたものを、

yamlファイルにあらかじめ書いておいて、applyしましょうというやつ。

 

ただし、yamlファイル名は「kustomization.yaml」である必要がある。

 

kustomization.yamlの作成例1 ファイルから生成>

※公式より転記させていただきました

configMapGenerator:
- name: game-config-4
  files:
  - configure-pod-container/configmap/game.properties

 

そのまますぎて解説するまでもないが、以下のように記述されている。

 ・最初に、configMapGeneratorであることを宣言。

 ・ConfigMapの名称を、nameで指定。

 ・ConfigMapの元ネタとなるファイルパスを、 filesで指定。(もちろん複数ファイル指定も可)

 

通常のマニフェストファイルより、さらに簡潔に書けることや、

設定値の元ネタとなるファイルを指定できることが特徴である。

 

<kustomization.yamlの作成例2 リテラルから生成>

※同じく公式より転記させて頂きました

configMapGenerator:
- name: special-config-2
  literals:
  - special.how=very
  - special.type=charm

ファイル指定の際にfilesだったところを、literalsで値を設定している。

指定内容は、キー=バリューの形式で記述する。

 

<kustomization.yamlのデプロイ>

kubectl applyすればOKだが、「-f」ではなく「-k」とすること、

ファイル名は指定しなくて良い(Generatorとして勝手に認識してくれる)ことに気を付けたい。

またそのため、kustomization.yamlを配置したディレクトリ内で、kubectl applyを実行すること。

 実行コマンド例: kubectl apply -k .

 

■ConfigMapsの参照方法

デプロイしたConfigMapは、環境変数やVolume領域の値として用いられる。

podなどにおいて、環境変数として参照する方法と、Volumeにマウントして参照する方法を解説する。

 

◎環境変数として個別利用

ConfigMap内の特定のキー&バリューを個別指定し、その値をpod内で使えるようにする方法。

pod内特有の定数名で、該当値を利用することができる。

 

<pod作成例>

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: sample
      env:
        - name: TEST_KEY
          valueFrom:
            configMapKeyRef:
              name: test-configmap
              key: test.key

環境変数の設定は、マニフェストファイル内の、spec.containers[].envで行う。

 

spec.containers[].env.name(例の「TEST_KEY」の部分)は、このpod内で使う環境変数の名称。

 

spec.containers[].env.valueFrom以下に、どのConfigMapの、どのキーの値を取ってくるか、を記述する。

今回は、「test-config」という名前のConfigMap内に定義された、「test.key」というキー名の値を取得している。

 

もし、ConfigMapから複数取得したい場合は、以下のように続けて記述する。

異なるConfigMapから値を取得してくることも可能である。

      env:
        - name: TEST_KEY
          valueFrom:
            configMapKeyRef:
              name: test-configmap
              key: test.key

      env:
        - name: EXAMPLE_KEY
          valueFrom:
            configMapKeyRef:
              name: example-configmap
              key: example.key

 

ConfigMap名とキーを個々に指定する方法は、

どのConfigMapのどの値を、何という名称で使うかが明確になる一方、

やや冗長な構成になってしまうデメリットもある。

 

ちなみに、定義した環境変数は、 $(環境変数名) で、pod内で利用できる。

 

◎環境変数としてまるごと利用

ConfigMapの内容をまるごと取ってきて、pod内で使えるようにする方法もある。

先ほど紹介したのは、あるConfigMapの、1つのキー&バリューを個別指定して取得する方法だったが、

この方法では、あるConfigMap内に定義された全てのキー&バリューを参照できるようになる。

 

<pod作成例>

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: sample
      envFrom:
      - configMapRef:
          name: test-configmap

spec.containers[]以下に設定していくのは、個別にキーを取得する時と同じ。

ただし、個別の際は、spec.containers[].env[]として設定していたところを、

spec.containers[].envFrom[]となっているところに注意。

 

また、個別の時と異なり、pod内でどのような名称で環境変数として扱うかの定義はない。

単に、どのConfigMapを使うかを指定するだけとなる。

 

従って、個別時のようなマニフェストファイルの冗長性の問題は解消される。

一方で、対象ConfigMap内にどのような値が定義されているかが見えづらい短所もある。

個別取得か、まるごと取得かは、どちらが良いということはなく、状況に応じて使い分けていくことが大事である。

 

◎Volumeとしてマウント

ボリューム(pod間の共有データ領域)に、ConfigMaopのデータを追加し、参照できるようにする方法。

pod作成のためのマニフェストファイルの書き方は、ボリューム一般のマウントのための書き方に同じ(別途記事を書く予定)だが、一応例を示す。

<pod作成例>

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config

 

まず、spec.containers[].volumeMounts以下に、

Volumeのマウント先情報(Volume名(name)と、マウント先のディレクトリパス(mountPath))を記述する。

※Volumeの追加先ディレクトリに他のデータがあった場合、削除されてしまうため、パス指定先に注意。

 

加えて、Volumeに、どんな情報を入れたいかを、spec.volumes以下に記述する。

Volume名(name)を明記のうえで、ConfigMapの名前(configMap.name)を記載することで、当該VolumeにConfigMapの内容を登録できる。

 

上記のマニフェストファイルによって、ConfigMapをVolumeに追加した後、

マウント先のディレクトリパス(今回は/etc/config)内には、

ConfigMapて定義されたキーの名前で、ファイルが作られている。

 

■参考文献

・公式

 https://kubernetes.io/docs/concepts/configuration/configmap/

 https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

 

・青山真也著『Kubernetes完全ガイド