k8s ConfigMapで設定管理を効率化!仕組みと使い方の詳細
はじめに:コンテナ化時代の設定管理の課題
現代のアプリケーション開発において、コンテナ技術、特にKubernetes (k8s) は不可欠な存在となりました。コンテナは、アプリケーションとその依存関係をパッケージ化し、どの環境でも一貫した実行を可能にします。しかし、アプリケーションをコンテナ化し、それをKubernetes上でオーケストレーションする際には、避けて通れない重要な課題があります。それが「設定管理」です。
アプリケーションの設定とは、データベースの接続情報、APIキー、ログレベル、外部サービスのエンドポイント、アプリケーション固有の各種パラメータなど、実行環境やデプロイメントの種類によって変更される可能性のある情報全般を指します。
従来のモノリシックなアプリケーション開発では、設定情報はアプリケーションのコード内にハードコードされたり、設定ファイルとしてアプリケーションと一緒にデプロイされたりすることが一般的でした。しかし、この方法には多くの問題が伴います。
- 環境間の差異への対応の困難さ: 開発環境、ステージング環境、本番環境では、データベースのURLや外部サービスのキーなどが異なります。環境ごとに設定ファイルを修正し、ビルドやデプロイをやり直すのは手間がかかり、設定ミスによる障害のリスクを高めます。
- コンテナイメージの不変性(Immutability)の原則との矛盾: コンテナの大きな利点は「一度ビルドしたイメージはどの環境でも同じように動作する」という不変性です。設定情報がイメージ内に含まれていると、環境ごとに異なるイメージをビルドする必要が生じ、不変性の原則が破られます。これは、イメージのテストや検証プロセスを複雑にし、デプロイメントの信頼性を低下させます。
- 設定変更のための再デプロイ: 設定情報だけを変更したい場合でも、アプリケーションコードと一緒にパッケージ化されていると、アプリケーション全体の再ビルド、再デプロイが必要になります。これは、設定変更のサイクルを遅くし、ダウンタイムのリスクを伴います。
- 機密情報の漏洩リスク: データベースパスワードやAPIキーなどの機密情報が設定ファイルとしてアプリケーションと一緒に扱われると、ソースコードリポジトリへの誤コミットや、コンテナイメージの漏洩などによる情報漏洩のリスクが高まります。
Kubernetesは、このような課題を解決するために、設定情報をアプリケーションのコンテナイメージから分離し、独立して管理するためのメカニズムを提供しています。その中心的な役割を担うのが、今回詳細に解説するConfigMapと、機密情報を扱うためのSecretです。
本記事では、特に非機密な設定情報を扱うConfigMapに焦点を当て、その仕組み、作成方法、Podでの多様な利用方法、そしてより高度な活用パターンや運用上の考慮事項まで、徹底的に掘り下げて解説します。ConfigMapを効果的に使いこなすことで、Kubernetes環境における設定管理を効率化し、アプリケーションのポータビリティ、スケーラビリティ、運用性を大幅に向上させることができます。
ConfigMapとは?
ConfigMapはKubernetesのAPIオブジェクトの一つで、キー-バリューペアの形式で非機密な設定データを保持するために使用されます。その主な目的は、アプリケーションコードやコンテナイメージから設定情報を分離することです。これにより、前述の課題を解決し、コンテナイメージの不変性を保ちつつ、柔軟な設定管理を実現します。
ConfigMapは、アプリケーションが必要とする設定パラメータ、構成ファイル全体、またはJSON/YAML/プロパティファイルなどの構造化された設定データを格納することができます。これらのデータは、後述するようにPod内のコンテナに環境変数として、またはボリュームとしてマウントされたファイルとして公開されます。
ConfigMapが解決する問題:
ConfigMapは、コンテナイメージと設定の密結合を解消します。アプリケーションの設定は、イメージビルド時ではなく、Kubernetes上でPodが作成される際にConfigMapから取得されます。これにより、同じコンテナイメージを異なる環境や異なる設定で実行することが可能になります。例えば、同じWebサーバーイメージを使って、開発環境ではデバッグログを有効にした設定で、本番環境ではパフォーマンス最適化された設定で実行するといったことが容易になります。
ConfigMapの基本的な構造:
ConfigMapオブジェクトは、主に以下の部分で構成されます。
apiVersion
: Kubernetes APIのバージョン (v1
など)kind
: オブジェクトの種類 (ConfigMap
)metadata
: オブジェクトのメタデータ (name
,namespace
,labels
,annotations
など)data
: キー-バリューペア形式の非構造化データ。キーとバリューは両方とも文字列である必要があります。binaryData
: キー-バイナリデータペア形式のデータ。バイナリデータはBase64エンコードされますが、Kubernetes API上ではバイナリとして扱われます。ConfigMapが大きなバイナリデータを扱うことは推奨されませんが、テキストファイルとして扱いにくいバイナリデータを含める場合に使用できます。
例:ConfigMapのYAML定義
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
namespace: default
data:
# キー1: 単一のパラメータ
log_level: INFO
# キー2: 複数行の文字列
database_url: postgres://user:password@db-service:5432/mydatabase
# キー3: ファイル全体を文字列として格納
my-config.properties: |
server.port=8080
server.contextPath=/app
feature.enabled=true
binaryData:
# キー4: バイナリデータ (Base64エンコード)
# 例: 秘密鍵など、バイナリで扱うべきデータ。ただし、機密情報はSecretを使うべきです。
# この例は概念的なものであり、実際のバイナリデータはここに Base64 エンコードして記述します。
some-binary-key: QWxsIGJpbmFyeSBkYXRhIGhlcmUuLi4= # これは Base64 エンコードされた "All binary data here..." です
data
フィールドのバリューは、YAMLのマルチライン記法 (|
または >
) を使って複数行の文字列を格納することもできます。これは、設定ファイル全体をConfigMapの単一のキーに関連付けて格納する場合に非常に便利です。
Secretとの違い:
ConfigMapとSecretは、どちらもキー-バリューペア形式で設定データを格納し、Podに公開するという点で似ています。しかし、決定的な違いは扱うデータの「機密性」です。
- ConfigMap: 非機密な設定情報(ログレベル、エンドポイントURL、設定フラグなど)を扱います。データはBase64エンコードされずに保存および転送されます(API上はエンコードされないが、内部的には etcd にはエンコードされて保存される場合があるが、ユーザーからは平文で見える)。
- Secret: 機密情報(パスワード、APIキー、証明書、SSHキーなど)を扱います。データはBase64エンコードされて保存され、Kubernetesクラスター内の適切なセキュリティ対策(etcdの暗号化など)と組み合わせることで、より安全に管理されます。
機密情報をConfigMapに格納することはセキュリティ上のリスクがあるため、絶対に避けるべきです。用途に応じてConfigMapとSecretを適切に使い分けることが重要です。
ConfigMapの作成方法
ConfigMapを作成する方法はいくつかあります。用途や管理のしやすさに応じて選択できます。主な作成方法は以下の通りです。
- YAMLファイルによる作成: ConfigMapのマニフェストをYAMLファイルとして記述し、
kubectl apply -f
コマンドで適用する方法です。最も一般的で推奨される方法であり、設定のバージョン管理が容易になります。 kubectl create configmap
コマンドによる作成:kubectl
コマンドラインツールを使って、ファイルやリテラル値から直接ConfigMapを作成する方法です。簡単なConfigMapを作成する場合や、スクリプトで自動生成する場合などに便利です。
それぞれの方法を詳しく見ていきましょう。
1. YAMLファイルによる作成
これは最も宣言的な方法であり、Infrastructure as Code (IaC) の原則に沿っています。設定内容をコードとして管理できるため、Gitなどのバージョン管理システムと組み合わせて変更履歴を追跡し、レビュープロセスを導入することが容易になります。
基本的なYAMLファイルの構造は前述の通りです。data
フィールドに、必要なキーとバリューを記述します。
例1: 単純なキー-バリューペアを持つConfigMap
my-simple-config.yaml
ファイル:
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-simple-config
data:
message: Hello from ConfigMap!
timeout_seconds: "30" # 数値も文字列として扱われる
このファイルを作成したら、以下のコマンドでKubernetesクラスターに適用します。
bash
kubectl apply -f my-simple-config.yaml
例2: 設定ファイル全体を格納するConfigMap
アプリケーションが特定のパスに設定ファイルを期待する場合、そのファイルの内容全体をConfigMapの単一のキーのバリューとして格納し、Podにファイルとしてマウントするのが一般的なパターンです。
app-settings.properties
ファイルの内容:
properties
database.host=mydb.example.com
database.port=5432
database.name=appdb
log.level=DEBUG
これを格納するConfigMapのYAMLファイル (app-config-file.yaml
):
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-file
data:
# キー名は何でも良いですが、Podでマウントする際のファイル名として使うことが多い
application.properties: |
database.host=mydb.example.com
database.port=5432
database.name=appdb
log.level=DEBUG
|
(パイプ) は、YAMLで複数行の文字列リテラルを記述するための記法です。各行のインデントは維持されます。
bash
kubectl apply -f app-config-file.yaml
例3: バイナリデータを含むConfigMap (非推奨だが記法として)
機密情報でなければバイナリデータも格納できますが、ConfigMapのサイズ制限(デフォルト1MB)や管理の複雑さから推奨されません。どうしても必要な場合はbinaryData
フィールドを使用します。バリューはBase64でエンコードする必要があります。
my-binary-config.yaml
:
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-binary-config
binaryData:
# "This is some binary data" を Base64 エンコードしたもの
config.dat: VGhpcyBpcyBzb21lIGJpbmFyeSBkYXRh
bash
kubectl apply -f my-binary-config.yaml
YAMLファイルでConfigMapを作成する方法は、設定をコードとして管理できるため、最も推奨されるアプローチです。
2. kubectl create configmap
コマンドによる作成
kubectl create configmap
コマンドを使うと、シェルから直接ConfigMapを作成できます。これは、CI/CDパイプラインでの自動化や、簡単な設定を一時的に作成する場合などに便利です。主に以下のオプションがあります。
--from-literal
: コマンドラインで直接指定したキー-バリューペアから作成します。--from-file
: 指定したファイルまたはディレクトリからキー-バリューペアを作成します。ファイル名またはディレクトリ名がキーとなり、ファイルの内容がバリューとなります。--from-env-file
: Java properties形式のような環境変数形式のファイルからキー-バリューペアを作成します。
例4: --from-literal
を使用して作成
複数のキー-バリューペアを指定できます。
bash
kubectl create configmap my-config-literal \
--from-literal=app.name=MyApp \
--from-literal=app.version=1.0 \
--from-literal=feature.flag=enabled
このコマンドは、my-config-literal
という名前のConfigMapを作成し、app.name
, app.version
, feature.flag
の3つのキーとそれぞれのバリューを格納します。
例5: --from-file
を使用して作成 (単一ファイル)
指定したファイルの内容をバリューとして、ファイル名をキーとしてConfigMapを作成します。
まず、ファイルを作成します。
settings.properties
ファイル:
properties
database.host=localhost
database.port=5432
次に、コマンドを実行します。
bash
kubectl create configmap my-config-file-single \
--from-file=settings.properties
これにより、data
フィールドに settings.properties: | ...ファイルの内容...
というキー-バリューペアを持つConfigMapが作成されます。
例6: --from-file
を使用して作成 (複数ファイル)
複数の --from-file
オプションを指定することで、複数のファイルをConfigMapに含めることができます。
まず、ファイルを作成します。
config1.yaml
:
yaml
param1: value1
config2.json
:
json
{
"param2": "value2"
}
次に、コマンドを実行します。
bash
kubectl create configmap my-config-file-multiple \
--from-file=config1.yaml \
--from-file=config2.json
これにより、data
フィールドに config1.yaml: | ...内容...
と config2.json: | ...内容...
の2つのキー-バリューペアを持つConfigMapが作成されます。
キー名を変更したい場合は、--from-file=<new_key_name>=<file_path>
の形式で指定します。
bash
kubectl create configmap my-config-file-renamed \
--from-file=app-config=settings.properties
これにより、data
フィールドに app-config: | ...ファイルの内容...
というキー-バリューペアを持つConfigMapが作成されます。
例7: --from-file
を使用して作成 (ディレクトリ)
ディレクトリを指定すると、そのディレクトリ内の各ファイルが ConfigMap のキーとして、ファイルの内容がバリューとして含まれます。サブディレクトリは含まれません。
configs/
ディレクトリを作成し、その中にファイルを作成します。
configs/
├── app.conf
└── db.conf
configs/app.conf
の内容:
server { listen 80; }
configs/db.conf
の内容:
user=admin
次に、コマンドを実行します。
bash
kubectl create configmap my-config-file-directory \
--from-file=configs/
これにより、data
フィールドに app.conf: | ...内容...
と db.conf: | ...内容...
の2つのキー-バリューペアを持つConfigMapが作成されます。
例8: --from-env-file
を使用して作成
Java properties ファイルのような形式のファイルから、キー-バリューペアをまとめてConfigMapに格納できます。
app.env
ファイル:
“`properties
Environment variables for the application
APP_NAME=MySuperApp
MAX_CONNECTIONS=100
DEBUG_MODE=false
“`
次に、コマンドを実行します。
bash
kubectl create configmap my-config-env-file \
--from-env-file=app.env
これにより、data
フィールドに APP_NAME: MySuperApp
, MAX_CONNECTIONS: 100
, DEBUG_MODE: false
の3つのキー-バリューペアを持つConfigMapが作成されます。コメント行や空行は無視されます。
各種作成方法の使い分け:
- YAMLファイル: 最も推奨される方法です。宣言的であり、Gitなどでのバージョン管理、レビュー、自動化との連携が容易です。複雑な設定や複数行の設定ファイルを扱うのに適しています。
kubectl create configmap --from-literal
: 簡単なキー-バリューペアをその場で作成したい場合や、スクリプトで動的に生成する場合に便利です。kubectl create configmap --from-file
: 既存の設定ファイルをそのままConfigMapに取り込みたい場合に便利です。特にディレクトリから一括で取り込めるのは手間が省けます。ただし、ファイル名がそのままキーになるため、後でPodで使用する際に少し不便を感じることもあります(ファイル名とConfigMap内のキー名を揃えたい場合など)。kubectl create configmap --from-env-file
: 環境変数形式の設定ファイルが既にある場合に、それをConfigMapに変換するのに便利です。
特別な理由がない限り、設定の可読性、管理性、そしてKubernetesの宣言的な性質を活かすために、YAMLファイルでの作成を第一の選択肢とすることをお勧めします。
ConfigMapをPodで使用する方法
作成したConfigMapは、Podの定義の中で参照することで、Pod内のコンテナに設定情報を渡すことができます。ConfigMapを使用する方法は主に以下の2つです。
- 環境変数として使用: ConfigMapのキー-バリューペアを、コンテナの環境変数として設定します。
- ボリュームとしてマウント: ConfigMapの各キーをファイルとして、またはConfigMap全体をディレクトリとして、Podのボリュームにマウントします。
これらの方法を使い分けることで、アプリケーションが設定情報をどのように読み込むかに柔軟に対応できます。
1. 環境変数として使用
アプリケーションが設定を環境変数から読み込むように設計されている場合に適しています。ConfigMapを環境変数としてPodに注入するには、主に2つの方法があります。
- 特定のキーを単一の環境変数に設定:
valueFrom.configMapKeyRef
を使用します。 - ConfigMap全体のキー-バリューペアをまとめて環境変数に設定:
envFrom.configMapRef
を使用します。
例9: valueFrom.configMapKeyRef
を使用して単一の環境変数を設定
ConfigMap my-app-config
が存在すると仮定します。
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
data:
log_level: INFO
database_url: postgres://user:password@db-service:5432/mydatabase
このConfigMapの log_level
キーのバリューを、Pod内のコンテナの LOG_LEVEL
という環境変数に設定するPodの定義です。
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-env-single
spec:
containers:
- name: my-app-container
image: my-app-image:latest
env:
- name: LOG_LEVEL # Pod内の環境変数名
valueFrom:
configMapKeyRef:
name: my-app-config # 参照するConfigMapの名前
key: log_level # ConfigMap内のキーの名前
- name: DB_CONNECTION_STRING # 別の環境変数
valueFrom:
configMapKeyRef:
name: my-app-config
key: database_url
# optional: true # キーが存在しない場合でもエラーにしない(Kubernetes 1.20+)
この方法の利点は、ConfigMap内のどのキーをどの環境変数名で公開するかを細かく制御できる点です。例えば、ConfigMapのキー名がアプリケーションの環境変数命名規則と一致しない場合でも、name
フィールドで任意の環境変数名を指定してマッピングできます。
configMapKeyRef
に optional: true
を追加すると、参照しているConfigMapまたはその中のキーが存在しない場合でもPodの起動に失敗せず、その環境変数は単に設定されません。これは、設定のオプション性を高めたい場合に便利です(Kubernetes 1.20以降で利用可能)。
例10: envFrom.configMapRef
を使用してConfigMap全体を環境変数に設定
ConfigMap my-app-settings
が存在すると仮定します。
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-settings
data:
APP_NAME: MyApp
MAX_CONNECTIONS: "100"
FEATURE_X_ENABLED: "true"
このConfigMapのすべてのキー-バリューペアを、Pod内のコンテナの環境変数として設定するPodの定義です。
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-env-entire
spec:
containers:
- name: my-app-container
image: my-app-image:latest
envFrom:
- configMapRef:
name: my-app-settings # 参照するConfigMapの名前
# optional: true # ConfigMapが存在しない場合でもエラーにしない(Kubernetes 1.20+)
この方法を使用すると、ConfigMap内のキー名がそのまま環境変数名として使用され、対応するバリューがその環境変数に設定されます。ConfigMap内のすべてのキーをまとめて環境変数にしたい場合に非常に便利で、PodのYAML定義がシンプルになります。
複数の envFrom
エントリを指定したり、env
と envFrom
を組み合わせて使用することも可能です。環境変数の競合が発生した場合(同じ名前の環境変数が複数ソースから定義された場合)、env
で定義された環境変数が優先され、次に envFrom
のリストの中で後の方に指定されたものが優先されます。
configMapRef
に optional: true
を追加すると、参照しているConfigMapが存在しない場合でもPodの起動に失敗せず、ConfigMapからロードされるはずだった環境変数は単に設定されません。これは、共通設定と環境別設定を分ける場合などに便利です。
環境変数として使用する場合の注意点:
- ConfigMapの更新: ConfigMapを更新しても、既に起動しているPodの環境変数は自動的には更新されません。環境変数はPodの起動時に一度だけ設定されるためです。設定の変更をPodに反映させるためには、通常、Podを再起動するか、Deploymentなどのコントローラーを使ってローリングアップデートを行う必要があります。
- キー名と環境変数名の有効性: ConfigMapのキー名は、Podの環境変数名として有効な形式である必要があります。無効な文字が含まれている場合、
envFrom
で参照するとエラーになる可能性があります。valueFrom
を使う場合は、name
フィールドで任意の有効な環境変数名を指定できるためこの問題は回避できます。 - サイズ制限: 環境変数として渡せるデータのサイズには実質的な制限があります(通常はOSやコンテナランタイムの制限に依存しますが、一般的にConfigMap自体のサイズ制限である1MBよりはるかに小さいデータ向けと考えられます)。大きな設定ファイル全体を環境変数として渡すのは現実的ではありません。
2. ボリュームとしてマウント
アプリケーションが設定ファイルを特定のパスから読み込むように設計されている場合に適しています。ConfigMapの内容をファイルとしてPodにマウントすることで、既存のアプリケーションコードを変更することなくKubernetes環境に移行できる場合があります。
ConfigMapをボリュームとしてマウントするには、Podの spec.volumes
フィールドで configMap
タイプを指定し、そのボリュームをコンテナの volumeMounts
フィールドでマウントします。
例11: ConfigMap全体をディレクトリとしてマウント
ConfigMap my-app-config-files
が存在すると仮定します。
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config-files
data:
app.properties: |
param1=value1
config.json: |
{ "param2": "value2" }
another.conf: |
server { listen 8080; }
このConfigMapの内容を、Pod内のコンテナの /etc/config
ディレクトリにマウントするPodの定義です。ConfigMapの各キー (app.properties
, config.json
, another.conf
) が、マウント先ディレクトリ内のファイル (/etc/config/app.properties
, /etc/config/config.json
, /etc/config/another.conf
) として作成されます。
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-volume-all
spec:
volumes:
- name: config-volume # ボリューム名 (Pod内で参照)
configMap:
name: my-app-config-files # 参照するConfigMapの名前
# optional: true # ConfigMapが存在しない場合でもエラーにしない(Kubernetes 1.20+)
containers:
- name: my-app-container
image: my-app-image:latest
volumeMounts:
- name: config-volume # マウントするボリューム名 (上記で定義したもの)
mountPath: /etc/config # コンテナ内のマウント先ディレクトリ
コンテナはこの /etc/config
ディレクトリ内のファイルを読み込むことで、ConfigMapで定義された設定情報を利用できます。
configMap
フィールドに optional: true
を追加すると、参照しているConfigMapが存在しない場合でもPodの起動に失敗せず、ボリュームはマウントされません。
例12: 特定のキーだけを特定のファイル名でマウント (items
)
ConfigMap内の特定のキーだけをマウントしたい場合や、マウント先のファイル名をConfigMapのキー名と異なる名前にしたい場合は、items
フィールドを使用します。
ConfigMap my-app-config-files
が存在すると仮定します(例11と同じ)。
このConfigMapから app.properties
キーだけを /app/settings.properties
としてマウントし、config.json
キーだけを /app/json-config.json
としてマウントするPodの定義です。
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-volume-items
spec:
volumes:
- name: config-volume
configMap:
name: my-app-config-files
items:
- key: app.properties # ConfigMap内のキー
path: settings.properties # マウント先ディレクトリ内でのファイル名
- key: config.json
path: json-config.json
containers:
- name: my-app-container
image: my-app-image:latest
volumeMounts:
- name: config-volume
mountPath: /app # マウント先ディレクトリ
この場合、コンテナ内の /app
ディレクトリには settings.properties
と json-config.json
というファイルが作成され、それぞれの内容はConfigMapの対応するキーのバリューとなります。/app/another.conf
は作成されません。
例13: 特定のキーを単一のファイルとして直接マウント (subPath
)
ConfigMap内の特定のキーだけを、ボリューム全体としてではなく、コンテナ内の単一のファイルとして直接マウントしたい場合があります。これは、アプリケーションが特定のパスにある特定のファイルしか読み込めない場合に便利です。volumeMounts
の subPath
フィールドを使用します。
ConfigMap my-app-config-files
が存在すると仮定します(例11と同じ)。
このConfigMapの app.properties
キーを、コンテナ内の /etc/app/settings.properties
ファイルとして直接マウントするPodの定義です。
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-volume-subpath
spec:
volumes:
- name: config-volume # ボリューム自体はConfigMap全体を参照
configMap:
name: my-app-config-files
containers:
- name: my-app-container
image: my-app-image:latest
volumeMounts:
- name: config-volume
mountPath: /etc/app/settings.properties # マウント先はファイルパス
subPath: app.properties # ConfigMap内のキー (ファイルとしてマウントする対象)
この方法の注意点として、subPath
を使用してマウントされたファイルは、ConfigMapが更新されても自動的に更新されません。これは、subPath
がシンボリックリンクとして実装されている場合に、元のファイル(シンボリックリンクの指す先)が更新されないためです。ConfigMapの更新を反映させるには、Podの再起動が必要です。また、readOnly: true
に設定できないという制限もあります。これらの制限から、通常は items
フィールドを使用する方が推奨されます。
例14: ファイル権限の設定 (defaultMode
)
ボリュームとしてマウントされるConfigMapファイルには、デフォルトでファイル権限が設定されます(通常は読み取り権限のみ)。defaultMode
フィールドを使って、マウントされるファイルの権限(Unix octal notation)を指定できます。
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-volume-mode
spec:
volumes:
- name: config-volume
configMap:
name: my-app-config-files
defaultMode: 0644 # 所有者に読み書き権限、グループとその他に読み取り権限
containers:
- name: my-app-container
image: my-app-image:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
items
フィールドを使用している場合、items
リスト内の各エントリに対して mode
フィールドを使って個別に権限を設定することも可能です。
ボリュームとして使用する場合の利点と注意点:
- アプリケーションの互換性: 既存のアプリケーションが設定ファイルを特定のパスから読み込むように設計されている場合、コードを変更せずにConfigMapを適用できます。
- ConfigMapの更新: ボリュームとしてマウントされたConfigMapの内容は、ConfigMapオブジェクトが更新されると自動的に(通常は数秒から数十秒以内に)更新されます。 Podを再起動する必要はありません。これは、ランタイムでの設定変更に対応できる大きな利点です。ただし、アプリケーション側でファイルの変更を検知して設定をリロードする仕組みが必要です(例えば、inotifyなどのファイル変更監視)。例外的に
subPath
でマウントした場合は自動更新されないことに注意してください。 - 複数ファイルの管理: 複数の設定ファイルをConfigMapに格納し、まとめてディレクトリとしてマウントするのに適しています。
- サイズ制限: ConfigMap全体のサイズはデフォルトで1MBに制限されています。大きな設定ファイルや多数の設定ファイルを格納する場合は注意が必要です。
3. コマンドライン引数として使用
ConfigMapの値を、Podのコンテナ起動コマンド (command
) または引数 (args
) の一部として使用することも可能です。これは、環境変数としてではなく、コマンドライン引数として特定の値を渡す必要がある場合に便利です。
環境変数として設定したConfigMapの値を、コマンドライン引数内で参照(展開)する形式が一般的です。
例15: 環境変数展開によるコマンドライン引数の設定
ConfigMap my-app-config
が存在すると仮定します(例9と同じ)。
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
data:
log_level: INFO
config_file_path: /app/config/settings.yaml
このConfigMapの値を環境変数としてPodに渡し、それをコンテナのコマンドライン引数として使用するPodの定義です。
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-args
spec:
containers:
- name: my-app-container
image: my-app-image:latest
env:
- name: APP_CONFIG_PATH
valueFrom:
configMapKeyRef:
name: my-app-config
key: config_file_path
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: my-app-config
key: log_level
command: ["/app/entrypoint.sh"] # 実行コマンド
args: [
"--config", "$(APP_CONFIG_PATH)", # 環境変数 APP_CONFIG_PATH を展開
"--log-level", "$(LOG_LEVEL)" # 環境変数 LOG_LEVEL を展開
]
コンテナ起動時、$(APP_CONFIG_PATH)
は環境変数 APP_CONFIG_PATH
の値 (/app/config/settings.yaml
) に、$(LOG_LEVEL)
は LOG_LEVEL
の値 (INFO
) にそれぞれ展開されます。結果として、コンテナは /app/entrypoint.sh --config /app/config/settings.yaml --log-level INFO
のようなコマンドで起動されます。
この方法を使用する場合も、ConfigMapの更新は環境変数に自動的には反映されないため、Podの再起動が必要になります。
ConfigMapの活用パターンと応用
ConfigMapは単に設定値を格納するだけでなく、様々なユースケースで活用することで、Kubernetes環境でのアプリケーション管理をより効率的かつ柔軟に行うことができます。
1. アプリケーション設定ファイル
最も一般的な使い方です。Webサーバー(Apache, Nginx)、アプリケーションサーバー、データベースクライアント、カスタムアプリケーションなどの設定ファイルをConfigMapとして管理し、Podにボリュームとしてマウントします。
- Nginx 設定例: Nginxの
nginx.conf
ファイルやサイト設定ファイル (default.conf
など) をConfigMapに格納し、Nginxコンテナの/etc/nginx/nginx.conf
や/etc/nginx/conf.d/default.conf
にマウントします。これにより、Nginxイメージを変更することなく、異なる設定で複数のNginx Podを実行できます。 - Java アプリケーション設定例:
application.properties
やlogback.xml
などのファイルをConfigMapに格納し、Javaアプリケーションコンテナが期待するパスにマウントします。
2. スクリプトや設定スニペット
実行可能なスクリプト(例:起動前スクリプト、ヘルスチェック用スクリプト)や、設定ファイルの一部としてインクルードされる小さな設定スニペットなどもConfigMapに格納できます。
- 起動スクリプト: アプリケーション起動前に環境設定やデータ移行などを行いたい場合、そのシェルスクリプトをConfigMapに格納し、Podにマウントして、コンテナの
command
やargs
で実行します。 - 設定スニペット: NginxやApacheの設定で、複数の設定ファイルをインクルードして最終的な設定を構築する場合、インクルードされる小さな設定ファイルをConfigMapとして管理します。
3. 複数環境(開発、ステージング、本番)での設定管理
ConfigMapは、環境ごとに異なる設定を管理するための強力なツールです。
- 名前空間による分離: 各環境を独立したKubernetes名前空間で管理し、それぞれの名前空間に同じ名前(例:
app-config
)を持つが内容が異なるConfigMapをデプロイします。Podは自身がデプロイされている名前空間内のConfigMapを参照するため、環境に応じた設定が自動的に適用されます。 - ツール(Helm, Kustomizeなど)との連携: HelmチャートやKustomizeのような構成管理ツールを使うと、環境ごとの設定ファイルをテンプレートとして定義し、デプロイ時に適切なConfigMapを自動生成・適用することが容易になります。例えば、Helmの
values.yaml
ファイルで環境ごとの設定値を定義し、ConfigMapのマニフェスト内でその値を参照するといった使い方が可能です。
4. ホットリロードへの対応
ボリュームとしてマウントされたConfigMapは、ConfigMapオブジェクトが更新されるとPod内のファイルも自動的に更新されます。この特性を利用して、アプリケーションを再起動することなく設定変更を反映させる「ホットリロード」を実現できます。
- アプリケーションによるファイル監視: アプリケーションコード内で、マウントされた設定ファイルの変更を監視する機能を実装します(例:Linuxのinotify APIを使用するライブラリ)。ファイル変更イベントを検知したら、アプリケーション内部で設定を再読み込みします。多くのミドルウェアやフレームワーク(例:Logback, Spring Boot Actuatorの一部機能など)はこの機能を持っています。
- シグナルによるリロード: 一部のアプリケーション(例:Nginx, Apache)は、特定シグナル(例:SIGHUP)を受け取ると設定ファイルをリロードする機能を持っています。ConfigMapの更新を検知して、Pod内のアプリケーションプロセスにリロードシグナルを送る外部コントローラー(例:stakater/Reloader)を利用することで、ホットリロードを自動化できます。
-
Pod再起動による反映: ホットリロードに対応していないアプリケーションの場合、ConfigMapの更新をトリガーとしてPodを再起動またはローリングアップデートさせる必要があります。Deploymentコントローラーは、Podテンプレート(具体的には
spec.template
)のハッシュ値が変更されるとローリングアップデートを開始します。ConfigMapの内容をPodテンプレートに含める簡単な方法は、ConfigMapのハッシュ値をアノテーションとしてPodテンプレートに付与することです。ConfigMapが更新されるとハッシュ値も変わり、Podテンプレートが変更されたと見なされてローリングアップデートがトリガーされます。これはkubectl rollout restart
に類似した効果ですが、自動化できます。ConfigMapのハッシュ値によるローリングアップデートトリガーの例:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
annotations:
# ConfigMapのハッシュ値をここに入れる。ツールで自動化されることが多い。
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
spec:
containers:
- name: my-app-container
image: my-app-image:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-app-config
この例はHelmテンプレートの記法を含みますが、ConfigMapのYAML内容(またはそのハッシュ値)をPodテンプレートのアノテーションに入れることで、ConfigMap更新時にDeploymentがPodを再作成する仕組みを示しています。
5. ConfigMapのイミュータビリティ(Immutability)
Kubernetes 1.18以降では、ConfigMapをimmutable(不変)としてマークできます。これにより、ConfigMapが一度作成された後は変更できなくなります。
目的と効果:
- パフォーマンスの向上: ConfigMapが不変であると宣言されると、etcd(Kubernetesのデータストア)やKubeletでの変更監視のオーバーヘッドが削減され、クラスタのパフォーマンスが向上する可能性があります。特に、大規模なクラスタで多くのConfigMapを扱う場合に効果的です。
- 信頼性の向上: 不変なConfigMapは意図しない変更から保護されます。一度デプロイされた設定は変更されないことが保証されるため、設定に関する問題のトラブルシューティングが容易になります。
- セキュリティの向上: 不変なConfigMapは、権限昇格攻撃などによって内容が不正に変更されるリスクを低減します。
有効化方法:
ConfigMapのマニフェストに immutable: true
フィールドを追加します。
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-immutable-config
data:
key1: value1
immutable: true
注意点:
- 不変なConfigMapは削除して再作成することによってのみ変更できます。既存の不変なConfigMapに対して
kubectl apply
やkubectl edit
で内容を変更しようとするとエラーになります。 - ローリングアップデート戦略と組み合わせる場合、新しい設定を持つConfigMapを新しい名前で作成し、DeploymentのPodテンプレートが新しいConfigMapを参照するように更新(そして古いConfigMapは不要になったら削除)するワークフローが一般的です。Helmのようなツールはこのワークフローをサポートします。
6. ConfigMapのサイズ制限と代替手段
ConfigMapのサイズは、デフォルトで1MBに制限されています。これはetcdのキーバリューサイズ制限に起因します。ほとんどのアプリケーション設定には十分なサイズですが、非常に大きな設定ファイルや多数の設定ファイルをConfigMapに格納しようとすると、この制限に達する可能性があります。
代替手段:
ConfigMapのサイズ制限を超える、またはより高度な設定管理機能(バージョン管理、アクセス制御、動的な値の生成など)が必要な場合は、Kubernetesの外部にある設定ストアを利用することも検討できます。
- 外部設定ストア:
- Consul: 分散キーバリューストア、サービスディスカバリ、コンフィグレーションなどの機能を提供します。
- etcd: Kubernetes自体もデータストアとして使用している分散キーバリューストアです。ConfigMapよりも低レベルなアクセスが可能です。
- ZooKeeper: 多くの分散システムで利用されているコーディネーションサービスです。
- HashiCorp Vault: 機密情報管理に特化していますが、一般的な設定情報も管理できます。動的なシークレット生成などの高度な機能も提供します。
これらの外部ストアを利用する場合、アプリケーションは起動時にこれらのストアに直接接続して設定情報を取得するか、ConfigMapと連携させて設定情報をPodに注入するサイドカーコンテナパターンなどを検討する必要があります。例えば、外部ストアから設定を取得してファイルとして書き出し、アプリケーションコンテナと共有ボリュームでそのファイルを共有するといったアーキテクチャが考えられます。
ConfigMapの管理と運用
ConfigMapはKubernetesオブジェクトとして、他のオブジェクトと同様に管理、監視、トラブルシューティングを行う必要があります。
1. ConfigMapの参照・確認
- 一覧表示: 現在の名前空間にあるConfigMapの一覧を表示します。
bash
kubectl get configmaps
# または省略形
kubectl get cm - 詳細表示: 特定のConfigMapの詳細を表示します。メタデータ、データ、イベントなどを確認できます。特にデータの内容を確認したい場合に便利です。
bash
kubectl describe configmap my-app-config
# または
kubectl describe cm my-app-config
describe
コマンドの出力には、Data
セクションにConfigMapの内容が表示されます。 - 内容の取得 (YAML/JSON): ConfigMapの完全なYAMLまたはJSON定義を取得します。これにより、ConfigMapの構造やすべてのキー-バリューペアをプログラム的に処理したり、バックアップしたりできます。
bash
kubectl get configmap my-app-config -o yaml
kubectl get configmap my-app-config -o json
2. ConfigMapの更新
ConfigMapを更新するには、通常、元のYAMLファイルを編集し、kubectl apply -f
コマンドで再適用します。
“`bash
my-app-config.yaml を編集して内容を変更する
vi my-app-config.yaml
変更を適用する
kubectl apply -f my-app-config.yaml
“`
または、kubectl edit configmap
コマンドを使用して、ライブでConfigMapオブジェクトを編集することもできます。
bash
kubectl edit configmap my-app-config
このコマンドは、ConfigMapのYAML定義をエディタで開き、保存してエディタを閉じると変更が適用されます。本番環境での手動編集はリスクが伴うため、避けるべきです。
ConfigMap更新時のPodへの反映: 前述の通り、ConfigMapの更新がPodに反映されるかどうかは、そのConfigMapがどのようにPodで使用されているか(環境変数 vs ボリュームマウント)によって異なります。環境変数の場合はPodの再起動が必要、ボリュームマウントの場合は自動更新(subPath
除く)されます。
3. ConfigMapの削除
不要になったConfigMapは削除します。
“`bash
kubectl delete configmap my-app-config
または
kubectl delete cm my-app-config
“`
ConfigMapを削除しても、それを参照しているPodはすぐには影響を受けない場合があります(特にPodが既に起動済みの場合)。しかし、ConfigMapがボリュームとしてマウントされている場合、マウントされているディレクトリやファイルへのアクセスができなくなる可能性があります。ConfigMapを削除する前に、それを参照しているPodやDeploymentがないか確認することを推奨します(kubectl get pod -o yaml | grep configMapKeyRef
や kubectl get deployment -o yaml | grep configMapKeyRef
などで確認できます)。
4. バージョニングとロールバック戦略
ConfigMap自体には組み込みのバージョン管理機能はありません。設定の変更履歴を管理し、必要に応じて過去の設定に戻せるようにするためには、以下の方法を検討します。
- GitOps: ConfigMapのYAML定義をGitリポジトリで管理します。Gitのコミット履歴が設定のバージョン履歴となり、いつでも過去のコミットに戻す(ロールバック)ことができます。Argo CDやFlux CDのようなGitOpsツールを使うと、Gitリポジトリの状態とクラスタの状態を自動的に同期させることができます。
- 名前付きバージョン: ConfigMapの名前付けにバージョン番号を含める方法です(例:
my-app-config-v1
,my-app-config-v2
)。新しいバージョンをデプロイする際は新しい名前のConfigMapを作成し、Deploymentなどのコントローラーが新しいConfigMapを参照するように更新します。ロールバックが必要な場合は、Deploymentが古いConfigMapを参照するように戻します。イミュータブルなConfigMapを使う場合、この方法が推奨されます。
5. セキュリティ上の考慮事項
ConfigMapは非機密情報を扱う設計ですが、設定内容によっては外部に漏洩することで攻撃の足がかりとなる可能性があります。
- 機密情報はSecretを使用: パスワード、APIキー、TLS証明書などの機密情報は必ずSecretを使用し、ConfigMapには格納しないでください。
- RBAC (Role-Based Access Control) の設定: ConfigMapへのアクセス権限を適切に設定します。特定のユーザーやサービスアカウントのみがConfigMapの読み取りや更新ができるように制限することで、不正アクセスによる情報漏洩や設定改ざんのリスクを低減できます。
- ConfigMapの内容に注意: 非機密情報であっても、アプリケーションの内部構造やネットワーク構成に関する詳細な情報が含まれている場合があります。公開されても問題ない情報のみを格納するように注意し、過度に詳細な情報をConfigMapに含めないように検討します。
6. 監視とトラブルシューティング
- Podの起動失敗: PodがConfigMapを参照しているにも関わらず、ConfigMapが存在しない、または参照しているキーが存在しない場合、PodはPending状態になったり起動に失敗したりすることがあります。
kubectl describe pod <pod-name>
のイベントログを確認することで、ConfigMap参照に関するエラー(例:Failed to validate ConfigMap
)を発見できます。 - 設定の不反映: ConfigMapを更新したにも関わらずアプリケーションに設定が反映されない場合、Podが再起動されていない(環境変数として使用している場合)か、アプリケーションがファイル変更を検知してリロードする仕組みを持っていない(ボリュームマウントしている場合)などが考えられます。
- ConfigMapのサイズ:
kubectl describe cm <configmap-name>
の出力で、ConfigMapのサイズを確認できます。サイズ制限(1MB)に近い、または超えている場合は、設定内容を見直すか、外部設定ストアの利用を検討する必要があります。
ConfigMapの代替または関連技術
ConfigMapはKubernetesにおける設定管理の中心ですが、他の関連技術や代替手段も存在し、それぞれ異なるユースケースに対応しています。
- Secret: ConfigMapと非常によく似ていますが、機密情報を安全に扱うために設計されています。使用方法もConfigMapとほぼ同様(環境変数またはボリュームマウント)ですが、ストレージ層での暗号化などの追加のセキュリティ対策が講じられます。機密情報と非機密情報を混在させず、適切にSecretとConfigMapを使い分けることが重要です。
- Downward API: Pod自身やその実行環境に関する情報(Pod名、名前空間、IPアドレス、ラベル、アノテーションなど)を、ConfigMapと同様に環境変数やボリュームとしてPodに公開する仕組みです。アプリケーションが自身の実行環境に関する情報を知るために使用されます。ConfigMapが静的な設定情報を扱うのに対し、Downward APIは動的なメタデータを扱います。
- Service Binding: サービス(アプリケーション)が依存する外部リソース(データベース、メッセージキュー、APIなど)への接続情報を抽象化し、アプリケーションに安全かつ標準的な方法で提供するための仕様です。ConfigMapやSecretを使って接続情報を渡す従来の方法に対し、Service Bindingはサービスディスカバリや資格情報管理の複雑さを隠蔽し、アプリケーション開発者が依存サービスの接続方法を意識することなく開発できるようにすることを目指しています。ConfigMapやSecretの代替というよりは、それらを活用しつつ依存関係管理を構造化する上位概念と言えます。
- 外部設定ストア (Consul, etcd, Vaultなど): Kubernetesの外部に独立した設定管理システムを構築するアプローチです。ConfigMapのサイズ制限を超える大規模な設定管理、より高度なアクセス制御、設定変更時の通知機能、設定の動的な生成(例: 短期間のみ有効なデータベース認証情報)など、ConfigMap単体では難しい要件に対応できます。Kubernetesとの連携には、外部ストアの内容をConfigMapに同期するコントローラーや、アプリケーションが直接外部ストアにアクセスするライブラリなどが必要になります。設定管理を一元化したい、クラスタ外のサービスとの設定を共有したいといった場合に有効な選択肢です。
これらの技術は相互排他的ではなく、組み合わせて使用されることもあります。例えば、外部設定ストアに格納された機密情報をVaultから取得し、それをKubernetes SecretとしてPodに注入するといったパターンも考えられます。
実践的な例
これまでに解説したConfigMapの作成方法と使用方法を組み合わせた、より実践的な例をいくつか見てみましょう。
例16: Nginx 設定ファイルをConfigMapで管理し、Podにマウントする
Nginxのカスタム設定ファイルを作成し、それをConfigMapに格納してNginx Podにマウントする例です。
-
Nginx 設定ファイルの作成:
nginx-custom.conf
ファイル:
“`nginx
worker_processes auto;events {
worker_connections 1024;
}http {
include /etc/nginx/mime.types;
default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log warn; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } location /status { stub_status on; allow 127.0.0.1; # localhostからのアクセスのみ許可 deny all; } }
}
``
/status` エンドポイントでNginxのステータスを表示する設定を追加しています。
このファイルは、デフォルトのNginx設定に加えて -
ConfigMapの作成 (YAML):
上記のnginx-custom.conf
をnginx-config.yaml
という名前のConfigMapに格納します。
“`yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
worker_processes auto;events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log warn; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } location /status { stub_status on; allow 127.0.0.1; # localhostからのアクセスのみ許可 deny all; } } }
``
nginx.conf` としているのは、Nginxコンテナ内のデフォルト設定ファイル名と合わせるためです。
ConfigMapのデータキーの名前をbash
kubectl apply -f nginx-config.yaml -
Nginx Podの作成:
ConfigMapnginx-config
をボリュームとしてマウントするNginx Podを定義します。
“`yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-config
labels:
app: nginx-config
spec:
containers:- name: nginx
image: nginx:latest # 公式Nginxイメージ
ports:- containerPort: 80
volumeMounts: - name: nginx-config-volume # ボリューム名を指定
mountPath: /etc/nginx/nginx.conf # マウント先はファイルパス
subPath: nginx.conf # ConfigMap内のキー (ファイルとしてマウントする対象)
readOnly: true # 読み取り専用でマウント
volumes:
- containerPort: 80
- name: nginx-config-volume # ボリューム定義
configMap:
name: nginx-config # 参照するConfigMapの名前
``
subPath
ここではを使用してConfigMapの
nginx.confキーを
/etc/nginx/nginx.conf` ファイルとして直接マウントしています。デフォルトのNginxイメージはこのパスのファイルを読み込みます。
bash
kubectl apply -f nginx-pod-config.yaml - name: nginx
-
確認:
Podが起動したら、ポートフォワーディングでPodに接続し、設定が適用されているか確認できます。
bash
kubectl port-forward nginx-pod-config 8080:80
別のターミナルでcurl http://localhost:8080/status
を実行すると、Nginxのステータス情報が表示されるはずです(ただし、/status
へのアクセスはlocalhostからのみ許可しているため、Pod内から実行するか、Podのネットワーク内からアクセスする必要があります。上記のport-forwarding経由ではアクセスできません。Pod exec で確認するか、/status
のallow
設定を一時的に 0.0.0.0/0 に変更して確認するのが現実的です)。Pod内で確認:
bash
kubectl exec -it nginx-pod-config -- curl http://localhost/status
これにより、ConfigMapで定義した設定がNginxに適用されていることが確認できます。
例17: アプリケーション設定を環境変数としてConfigMapで管理する
ConfigMapに設定値を格納し、Podに環境変数として注入する例です。アプリケーションは起動時にこれらの環境変数を読み込みます。
-
ConfigMapの作成 (YAML):
アプリケーションが使用する設定値をConfigMapに定義します。
app-env-config.yaml
:
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-env-config
data:
APP_MODE: production
API_ENDPOINT: http://api.example.com/v1
RETRY_COUNT: "5" # 環境変数にする場合、値は文字列として扱うのが一般的
bash
kubectl apply -f app-env-config.yaml -
アプリケーション Pod の作成:
上記のConfigMapから環境変数を読み込むPodを定義します。簡単のため、環境変数を標準出力するbusyboxイメージを使用します。
app-pod-env.yaml
:
“`yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod-env
spec:
containers:- name: app-container
image: busybox:latest # 環境変数を表示できるシンプルなイメージ
command: [“/bin/sh”, “-c”, “echo APP_MODE=$APP_MODE, API_ENDPOINT=$API_ENDPOINT, RETRY_COUNT=$RETRY_COUNT; sleep infinity”] # 環境変数を出力してPodを維持
envFrom:- configMapRef:
name: app-env-config # 参照するConfigMapの名前
``
envFrom
ここではを使用して、ConfigMap
app-env-config` のすべてのキー-バリューペアを環境変数として注入しています。
- configMapRef:
bash
kubectl apply -f app-pod-env.yaml - name: app-container
-
確認:
Podが起動したら、Podのログを確認します。
bash
kubectl logs app-pod-env
ログ出力には、ConfigMapから注入された環境変数の値が含まれているはずです。
APP_MODE=production, API_ENDPOINT=http://api.example.com/v1, RETRY_COUNT=5
これにより、ConfigMapの内容が正しく環境変数としてPodに渡されていることが確認できます。
例18: 複数の設定ファイルをConfigMapで管理し、まとめてマウントする
複数の異なる設定ファイルをConfigMapに格納し、Pod内の単一のディレクトリにまとめてマウントする例です。
-
設定ファイルの準備:
複数の設定ファイルを用意します。
conf.d/api-config.json
:
json
{
"api": {
"timeout_ms": 5000,
"retries": 3
}
}
conf.d/feature-flags.properties
:
properties
featureA.enabled=true
featureB.enabled=false -
ConfigMapの作成 (
kubectl create configmap --from-file
を使用):
conf.d
ディレクトリを作成し、その中に上記のファイルを作成します。
bash
mkdir conf.d
# 上記ファイルの内容をそれぞれ conf.d/api-config.json と conf.d/feature-flags.properties に保存
ディレクトリを指定してConfigMapを作成します。
bash
kubectl create configmap my-multi-config --from-file=conf.d/
これにより、api-config.json
とfeature-flags.properties
の2つのキーを持つmy-multi-config
という名前のConfigMapが作成されます。内容を確認します:
bash
kubectl describe cm my-multi-config
出力例:
“`
Name: my-multi-config
Namespace: default
Labels:
Annotations:Data
api-config.json:
{
“api”: {
“timeout_ms”: 5000,
“retries”: 3
}
}
feature-flags.properties:
featureA.enabled=true
featureB.enabled=falseEvents:
“` -
アプリケーション Pod の作成:
ConfigMapmy-multi-config
をボリュームとしてPodにマウントします。busyboxイメージを使用して、マウントされたディレクトリの内容を確認します。
app-pod-multi-volume.yaml
:
“`yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod-multi-volume
spec:
volumes:- name: config-volume
configMap:
name: my-multi-config # 参照するConfigMapの名前
containers: - name: app-container
image: busybox:latest
command: [“/bin/sh”, “-c”, “ls /etc/app-config; cat /etc/app-config/api-config.json; cat /etc/app-config/feature-flags.properties; sleep infinity”] # マウントされたディレクトリとファイルの内容を表示
volumeMounts:- name: config-volume
mountPath: /etc/app-config # マウント先ディレクトリ
readOnly: true # 読み取り専用でマウントするのが一般的
``
/etc/app-config` ディレクトリ内のファイルとしてマウントされます。
ここでは、ConfigMapのすべてのキーが
- name: config-volume
bash
kubectl apply -f app-pod-multi-volume.yaml - name: config-volume
-
確認:
Podが起動したら、Podのログを確認します。
bash
kubectl logs app-pod-multi-volume
ログ出力には、マウントされたディレクトリのファイルリストと、各ファイルの内容が表示されているはずです。
api-config.json
feature-flags.properties
{
"api": {
"timeout_ms": 5000,
"retries": 3
}
}
featureA.enabled=true
featureB.enabled=false
これにより、ConfigMapに格納された複数のファイルが、Pod内の単一ディレクトリに正しくマウントされていることが確認できます。アプリケーションはこれらのファイルを読み込むことで設定を利用できます。
これらの例を通して、ConfigMapがどのように作成され、Podでどのように利用されるかの基本的な流れと、異なるユースケースへの適用方法が理解できたかと思います。
まとめ
ConfigMapは、Kubernetes環境におけるアプリケーションの設定管理を効率化するための非常に強力なツールです。コンテナイメージから設定を分離することで、イメージの不変性を保ち、環境間の差異を吸収し、デプロイメントの柔軟性を大幅に向上させます。
ConfigMapの主なメリット:
- 設定とコードの分離: アプリケーションコードやコンテナイメージに変更を加えることなく、設定のみを変更・更新できます。
- デプロイの効率化: 同じコンテナイメージを異なる設定で様々な環境にデプロイできます。
- 環境間の差異吸収: 開発、ステージング、本番といった環境固有の設定をConfigMapとして管理し、Podが自身の環境に応じた設定を容易に参照できるようにします。
- Config as Code: 設定情報をYAMLファイルとして管理することで、バージョン管理システムを使った変更履歴の追跡、レビュー、自動化との連携が可能になります。
効果的なConfigMap利用のためのベストプラクティス:
- 機密情報と非機密情報の分離: パスワードなどの機密情報は必ずSecretを使用し、ConfigMapには非機密情報のみを格納します。
- 命名規則の統一: ConfigMapの命名規則を統一し、参照しやすいようにします(例:
app-name-config
,service-name-settings
)。 - 目的ごとのConfigMap分割: 関連性の高い設定情報ごとにConfigMapを分割することで、管理を容易にします。
- バージョン管理システムでの管理: ConfigMapのYAML定義はGitなどのバージョン管理システムで管理し、変更履歴を追跡できるようにします。
- 環境ごとのConfigMap管理: 環境ごとに異なるConfigMapを作成し、名前空間やツール(Helm, Kustomize)を活用して管理します。
- ConfigMapの更新戦略: ConfigMapの更新がPodにどのように反映されるかを理解し、必要に応じてPodの再起動やローリングアップデートをトリガーする仕組みを検討します。ボリュームマウントとホットリロード対応は、特に頻繁に変更される可能性のある設定に有効です。
- RBACによるアクセス制御: ConfigMapへのアクセス権限を適切に設定し、セキュリティリスクを低減します。
- サイズ制限の考慮: 大きすぎる設定や多数の設定を扱う場合は、ConfigMapの1MB制限に注意し、必要に応じて外部設定ストアの利用を検討します。
今後の展望:
Kubernetesのエコシステムは常に進化しており、設定管理に関する機能も改善が続けられています。Service Bindingのような新しい概念の導入や、Immutable ConfigMapのようなパフォーマンス・信頼性向上機能の追加など、より効率的でセキュアな設定管理を実現するための取り組みが進んでいます。
ConfigMapはKubernetesにおける設定管理の基礎であり、その仕組みと効果的な使い方を理解することは、Kubernetesを用いたモダンなアプリケーション開発・運用において不可欠です。本記事で解説した詳細な情報と実践例が、皆様のKubernetes活用の助けとなれば幸いです。ConfigMapを最大限に活用し、設定管理の課題を克服し、より堅牢で柔軟なアプリケーション運用を実現してください。