|
| 1 | +--- |
| 2 | +title: ConfigMap |
| 3 | +content_type: concept |
| 4 | +weight: 20 |
| 5 | +--- |
| 6 | + |
| 7 | +<!-- overview --> |
| 8 | + |
| 9 | +{{< glossary_definition term_id="configmap" prepend="ConfigMapは、" length="all" >}} |
| 10 | + |
| 11 | +{{< caution >}} |
| 12 | +ConfigMapは機密性や暗号化を提供しません。保存したいデータが機密情報である場合は、ConfigMapの代わりに{{< glossary_tooltip text="Secret" term_id="secret" >}}を使用するか、追加の(サードパーティー)ツールを使用してデータが非公開になるようにしてください。 |
| 13 | +{{< /caution >}} |
| 14 | + |
| 15 | +<!-- body --> |
| 16 | + |
| 17 | +## 動機 |
| 18 | + |
| 19 | +アプリケーションのコードとは別に設定データを設定するには、ConfigMapを使用します。 |
| 20 | + |
| 21 | +たとえば、アプリケーションを開発していて、(開発用時には)自分のコンピューター上と、(実際のトラフィックをハンドルするときは)クラウド上とで実行することを想像してみてください。あなたは、`DATABASE_HOST`という名前の環境変数を使用するコードを書きます。ローカルでは、この変数を`localhost`に設定します。クラウド上では、データベースコンポーネントをクラスター内に公開するKubernetesの{{< glossary_tooltip text="Service" term_id="service" >}}を指すように設定します。 |
| 22 | + |
| 23 | +こうすることで、必要であればクラウド上で実行しているコンテナイメージを取得することで、ローカルでも完全に同じコードを使ってデバッグができるようになります。 |
| 24 | + |
| 25 | +## ConfigMapオブジェクト |
| 26 | + |
| 27 | +ConfigMapは、他のオブジェクトが使うための設定を保存できるAPI[オブジェクト](/ja/docs/concepts/overview/working-with-objects/kubernetes-objects/)です。ほとんどのKubernetesオブジェクトに`spec`セクションがあるのとは違い、ConfigMapにはアイテム(キー)と値を保存するための`data`セクションがあります。 |
| 28 | + |
| 29 | +ConfigMapの名前は、有効な[DNSのサブドメイン名](/ja/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)でなければなりません。 |
| 30 | + |
| 31 | +## ConfigMapとPod |
| 32 | + |
| 33 | +ConfigMapを参照して、ConfigMap内のデータを元にしてPod内のコンテナの設定をするPodの`spec`を書くことができます。このとき、PodとConfigMapは同じ{{< glossary_tooltip text="名前空間" term_id="namespace" >}}内に存在する必要があります。 |
| 34 | + |
| 35 | +以下に、ConfigMapの例を示します。単一の値を持つキーと、Configuration形式のデータ片のような値を持つキーがあります。 |
| 36 | + |
| 37 | +```yaml |
| 38 | +apiVersion: v1 |
| 39 | +kind: ConfigMap |
| 40 | +metadata: |
| 41 | + name: game-demo |
| 42 | +data: |
| 43 | + # プロパティーに似たキー。各キーは単純な値にマッピングされている |
| 44 | + player_initial_lives: "3" |
| 45 | + ui_properties_file_name: "user-interface.properties" |
| 46 | + # |
| 47 | + # ファイルに似たキー |
| 48 | + game.properties: | |
| 49 | + enemy.types=aliens,monsters |
| 50 | + player.maximum-lives=5 |
| 51 | + user-interface.properties: | |
| 52 | + color.good=purple |
| 53 | + color.bad=yellow |
| 54 | + allow.textmode=true |
| 55 | +``` |
| 56 | +
|
| 57 | +ConfigMapを利用してPod内のコンテナを設定する方法には、次の4種類があります。 |
| 58 | +
|
| 59 | +1. コマンドライン引数をコンテナのエントリーポイントに渡す |
| 60 | +1. 環境変数をコンテナに渡す |
| 61 | +1. 読み取り専用のボリューム内にファイルを追加し、アプリケーションがそのファイルを読み取る |
| 62 | +1. Kubernetes APIを使用してConfigMapを読み込むコードを書き、そのコードをPod内で実行する |
| 63 | +
|
| 64 | +これらのさまざまな方法は、利用するデータをモデル化するのに役立ちます。最初の3つの方法では、{{< glossary_tooltip text="kubelet" term_id="kubelet" >}}がPodのコンテナを起動する時にConfigMapのデータを使用します。 |
| 65 | +
|
| 66 | +4番目の方法では、ConfigMapとそのデータを読み込むためのコードを自分自身で書く必要があります。しかし、Kubernetes APIを直接使用するため、アプリケーションはConfigMapがいつ変更されても更新イベントを受信でき、変更が発生したときにすぐに反応できます。この手法では、Kubernetes APIに直接アクセスすることで、別の名前空間にあるConfigMapにもアクセスできます。 |
| 67 | +
|
| 68 | +以下に、Podを設定するために`game-demo`から値を使用するPodの例を示します。 |
| 69 | + |
| 70 | +```yaml |
| 71 | +apiVersion: v1 |
| 72 | +kind: Pod |
| 73 | +metadata: |
| 74 | + name: configmap-demo-pod |
| 75 | +spec: |
| 76 | + containers: |
| 77 | + - name: demo |
| 78 | + image: game.example/demo-game |
| 79 | + env: |
| 80 | + # 環境変数を定義します。 |
| 81 | + - name: PLAYER_INITIAL_LIVES # ここではConfigMap内のキーの名前とは違い |
| 82 | + # 大文字が使われていることに着目してください。 |
| 83 | + valueFrom: |
| 84 | + configMapKeyRef: |
| 85 | + name: game-demo # この値を取得するConfigMap。 |
| 86 | + key: player_initial_lives # 取得するキー。 |
| 87 | + - name: UI_PROPERTIES_FILE_NAME |
| 88 | + valueFrom: |
| 89 | + configMapKeyRef: |
| 90 | + name: game-demo |
| 91 | + key: ui_properties_file_name |
| 92 | + volumeMounts: |
| 93 | + - name: config |
| 94 | + mountPath: "/config" |
| 95 | + readOnly: true |
| 96 | + volumes: |
| 97 | + # Podレベルでボリュームを設定し、Pod内のコンテナにマウントします。 |
| 98 | + - name: config |
| 99 | + configMap: |
| 100 | + # マウントしたいConfigMapの名前を指定します。 |
| 101 | + name: game-demo |
| 102 | + # ファイルとして作成するConfigMapのキーの配列 |
| 103 | + items: |
| 104 | + - key: "game.properties" |
| 105 | + path: "game.properties" |
| 106 | + - key: "user-interface.properties" |
| 107 | + path: "user-interface.properties" |
| 108 | +``` |
| 109 | + |
| 110 | +ConfigMapは1行のプロパティの値と複数行のファイルに似た形式の値を区別しません。問題となるのは、Podや他のオブジェクトによる値の使用方法です。 |
| 111 | + |
| 112 | +この例では、ボリュームを定義して、`demo`コンテナの内部で`/config`にマウントしています。これにより、ConfigMap内には4つのキーがあるにもかかわらず、2つのファイル`/config/game.properties`および`/config/user-interface.properties`だけが作成されます。 |
| 113 | + |
| 114 | +これは、Podの定義が`volumes`セクションで`items`という配列を指定しているためです。もし`items`の配列を完全に省略すれば、ConfigMap内の各キーがキーと同じ名前のファイルになり、4つのファイルが作成されます。 |
| 115 | + |
| 116 | +## ConfigMapを使う |
| 117 | + |
| 118 | +ConfigMapは、データボリュームとしてマウントできます。ConfigMapは、Podへ直接公開せずにシステムの他の部品として使うこともできます。たとえば、ConfigMapには、システムの他の一部が設定のために使用するデータを保存できます。 |
| 119 | + |
| 120 | +{{< note >}} |
| 121 | +ConfigMapの最も一般的な使い方では、同じ名前空間にあるPod内で実行されているコンテナに設定を構成します。ConfigMapを独立して使用することもできます。 |
| 122 | + |
| 123 | +たとえば、ConfigMapに基づいて動作を調整する{{< glossary_tooltip text="アドオン" term_id="addons" >}}や{{< glossary_tooltip text="オペレーター" term_id="operator-pattern" >}}を見かけることがあるかもしれません。 |
| 124 | +{{< /note >}} |
| 125 | + |
| 126 | +### ConfigMapをPodからファイルとして使う |
| 127 | + |
| 128 | +ConfigMapをPod内のボリュームで使用するには、次のようにします。 |
| 129 | + |
| 130 | +1. ConfigMapを作成するか、既存のConfigMapを使用します。複数のPodから同じConfigMapを参照することもできます。 |
| 131 | +1. Podの定義を修正して、`.spec.volumes[]`以下にボリュームを追加します。ボリュームに任意の名前を付け、`.spec.volumes[].configMap.name`フィールドにConfigMapオブジェクトへの参照を設定します。 |
| 132 | +1. ConfigMapが必要な各コンテナに`.spec.containers[].volumeMounts[]`を追加します。`.spec.containers[].volumeMounts[].readOnly = true`を指定して、`.spec.containers[].volumeMounts[].mountPath`には、ConfigMapのデータを表示したい未使用のディレクトリ名を指定します。 |
| 133 | +1. イメージまたはコマンドラインを修正して、プログラムがそのディレクトリ内のファイルを読み込むように設定します。ConfigMapの`data`マップ内の各キーが、`mountPath`以下のファイル名になります。 |
| 134 | + |
| 135 | +以下は、ボリューム内にConfigMapをマウントするPodの例です。 |
| 136 | + |
| 137 | +```yaml |
| 138 | +apiVersion: v1 |
| 139 | +kind: Pod |
| 140 | +metadata: |
| 141 | + name: mypod |
| 142 | +spec: |
| 143 | + containers: |
| 144 | + - name: mypod |
| 145 | + image: redis |
| 146 | + volumeMounts: |
| 147 | + - name: foo |
| 148 | + mountPath: "/etc/foo" |
| 149 | + readOnly: true |
| 150 | + volumes: |
| 151 | + - name: foo |
| 152 | + configMap: |
| 153 | + name: myconfigmap |
| 154 | +``` |
| 155 | + |
| 156 | +使用したいそれぞれのConfigMapごとに、`.spec.volumes`内で参照する必要があります。 |
| 157 | + |
| 158 | +Pod内に複数のコンテナが存在する場合、各コンテナにそれぞれ別の`volumeMounts`のブロックが必要ですが、`.spec.volumes`はConfigMapごとに1つしか必要ありません。 |
| 159 | + |
| 160 | +#### マウントしたConfigMapの自動的な更新 |
| 161 | + |
| 162 | +ボリューム内で現在使用中のConfigMapが更新されると、射影されたキーも最終的に(eventually)更新されます。kubeletは定期的な同期のたびにマウントされたConfigMapが新しいかどうか確認します。しかし、kubeletが現在のConfigMapの値を取得するときにはローカルキャッシュを使用します。キャッシュの種類は、[KubeletConfiguration構造体](https://github.com/kubernetes/kubernetes/blob/{{< param "docsbranch" >}}/staging/src/k8s.io/kubelet/config/v1beta1/types.go)の中の`ConfigMapAndSecretChangeDetectionStrategy`フィールドで設定可能です。ConfigMapは、監視(デフォルト)、ttlベース、またはすべてのリクエストを直接APIサーバーへ単純にリダイレクトする方法のいずれかによって伝搬されます。その結果、ConfigMapが更新された瞬間から、新しいキーがPodに射影されるまでの遅延の合計は、最長でkubeletの同期期間+キャッシュの伝搬遅延になります。ここで、キャッシュの伝搬遅延は選択したキャッシュの種類に依存します(監視の伝搬遅延、キャッシュのttl、または0に等しくなります)。 |
| 163 | + |
| 164 | +{{< feature-state for_k8s_version="v1.18" state="alpha" >}} |
| 165 | + |
| 166 | +Kubernetesのアルファ版の機能である _イミュータブルなSecretおよびConfigMap_ は、個別のSecretやConfigMapをイミュータブルに設定するオプションを提供します。ConfigMapを広範に使用している(少なくとも数万のConfigMapがPodにマウントされている)クラスターでは、データの変更を防ぐことにより、以下のような利点が得られます。 |
| 167 | + |
| 168 | +- アプリケーションの停止を引き起こす可能性のある予想外の(または望まない)変更を防ぐことができる |
| 169 | +- ConfigMapをイミュータブルにマークして監視を停止することにより、kube-apiserverへの負荷を大幅に削減し、クラスターの性能が向上する |
| 170 | + |
| 171 | +この機能を使用するには、`ImmutableEmphemeralVolumes`[フィーチャーゲート](/ja/docs/reference/command-line-tools-reference/feature-gates/)を有効にして、SecretやConfigMapの`immutable`フィールドを`true`に設定してください。次に例を示します。 |
| 172 | + |
| 173 | +```yaml |
| 174 | +apiVersion: v1 |
| 175 | +kind: ConfigMap |
| 176 | +metadata: |
| 177 | + ... |
| 178 | +data: |
| 179 | + ... |
| 180 | +immutable: true |
| 181 | +``` |
| 182 | + |
| 183 | +{{< note >}} |
| 184 | +一度ConfigMapやSecretがイミュータブルに設定すると、この変更を元に戻したり、`data`フィールドのコンテンツを変更することは*できません*。既存のPodは削除されたConfigMapのマウントポイントを保持するため、こうしたPodは再作成することをおすすめします。 |
| 185 | +{{< /note >}} |
| 186 | + |
| 187 | +## {{% heading "whatsnext" %}} |
| 188 | + |
| 189 | +* [Secret](/docs/concepts/configuration/secret/)について読む。 |
| 190 | +* [Podを構成してConfigMapを使用する](/ja/docs/tasks/configure-pod-container/configure-pod-configmap/)を読む。 |
| 191 | +* コードを設定から分離する動機を理解するために[The Twelve-Factor App](https://12factor.net/ja/)を読む。 |
0 commit comments