第11章:ConfigMapで設定を外出しする🧩
この章は「コードを書き換えずに設定だけ差し替える」を、Kubernetes流でサクッと体験する回です 😄✨ (環境ごとの差分に強くなる=運用っぽさが一気に出ます💪)
この章のゴール🎯
- ConfigMapが「何者」か、ざっくり言える 🗣️
- Node/TSアプリに ConfigMap(環境変数 or ファイル) を注入できる 🔌
- 更新したときの挙動(勝手に変わる / 変わらない)を体験できる 🔁
- “設計超入門”として、どれをConfigMapにして、どれは別にするかが判断できる 🧠
1) ConfigMapってなに?📦(一言で)
ConfigMapは、「秘密じゃない設定」をキーと値で持つ入れ物です 🧺 Podはそれを 環境変数・コマンド引数・設定ファイル(Volume) として使えます。(Kubernetes)
⚠️ 逆に、**秘密情報(パスワード等)**には向きません。秘密はSecretへ、が鉄則です 🔐(Kubernetes)
さらに現実的な制約👇
- ConfigMapは巨大データ置き場じゃない(上限 1MiB)📏(Kubernetes)
- 文字列は
data、バイナリはbinaryDataに入れられるよ 🧾🧱(Kubernetes)
2) 「設定を外出し」すると何が嬉しい?🌱
たとえばこんな設定、コードにベタ書きしてると詰みやすいです 😇💥
- ログレベル(devはdebug、prodはinfo)🪵
- 機能フラグ(新機能ON/OFF)🚩
- APIの挨拶文 / 表示名 / タイムアウト ⏱️
- 外部サービスのURL(ただし秘密は入れない!)🌐
ConfigMapにすると、
- イメージは同じのまま、環境差だけ変えられる 🧊➡️🔥
- 設定変更で、再ビルド不要になってスピードUP ⚡
- 「設定ミスった」時も、差し戻しがラク 😌🔙
3) ハンズオン🧪:Node/TS APIにConfigMapを刺す🔌
ここでは、次の2つを同時にやります👇
- 環境変数で刺す(シンプルでよく使う)🌟
- ファイルで刺す(設定ファイル派に強い)📄
重要:ConfigMapは “Linuxの
/etc的なもの” と思うとイメージしやすいです 🐧📁(Kubernetes)
3-1) Node/TS側:設定を読むコード(最小)🍔
ポイントは「envがあればenv優先、なければ ファイル、それもなければ デフォルト」です ✅
// src/config.ts
import fs from "node:fs";
type AppConfig = {
greeting: string;
logLevel: "debug" | "info" | "warn" | "error";
featureNewEndpoint: boolean;
};
function readJson(path: string): Partial<AppConfig> {
try {
return JSON.parse(fs.readFileSync(path, "utf8"));
} catch {
return {};
}
}
export function loadConfig(): AppConfig {
const fileCfg = readJson("/app/config/app-config.json");
const greeting = process.env.GREETING ?? fileCfg.greeting ?? "Hello 👋";
const logLevel = (process.env.LOG_LEVEL ?? fileCfg.logLevel ?? "info") as AppConfig["logLevel"];
const featureNewEndpoint =
(process.env.FEATURE_NEW_ENDPOINT ?? String(fileCfg.featureNewEndpoint ?? false)) === "true";
return { greeting, logLevel, featureNewEndpoint };
}
で、エンドポイントは「毎回読む」方式(学習用に分かりやすい)👇 ※本番はキャッシュ+リロードとかにするけど、まずはこれでOKです 😄
// src/app.ts (例)
import express from "express";
import { loadConfig } from "./config";
const app = express();
app.get("/hello", (_req, res) => {
const cfg = loadConfig();
res.json({
greeting: cfg.greeting,
logLevel: cfg.logLevel,
featureNewEndpoint: cfg.featureNewEndpoint,
});
});
export default app;
3-2) ConfigMapを作る(env用・ファイル用を分ける)✂️📦
なぜ分けるの?🤔
ConfigMapのキーは - _ . など色々OKですが(Kubernetes)、環境変数名には向かない文字もあるので(例:app-config.json)
env用はenv用、ファイル用はファイル用にしておくと事故りにくいです 🧯
(A) env用 ConfigMap(文字列のキー/値)🌿
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-api-env
data:
GREETING: "こんにちは from ConfigMap 👋"
LOG_LEVEL: "debug"
FEATURE_NEW_ENDPOINT: "true"
(B) ファイル用 ConfigMap(設定ファイルを1枚入れる)📄
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-api-file
data:
app-config.json: |
{
"greeting": "こんにちは from JSON 📄✨",
"logLevel": "info",
"featureNewEndpoint": false
}
3-3) Deploymentに注入する(envFrom + volume)🚀
- envは
envFromでまとめて注入(楽ちん)🧺 - ファイルは volumeで
/app/configにマウント 📁
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-api
spec:
replicas: 1
selector:
matchLabels:
app: demo-api
template:
metadata:
labels:
app: demo-api
spec:
containers:
- name: api
image: your-registry/demo-api:1.0.0
ports:
- containerPort: 3000
# ✅ env注入(まとめて)
envFrom:
- configMapRef:
name: demo-api-env
# ✅ ファイル注入(/app/config/app-config.json)
volumeMounts:
- name: app-config
mountPath: /app/config
readOnly: true
volumes:
- name: app-config
configMap:
name: demo-api-file
items:
- key: app-config.json
path: app-config.json
適用はまとめて👇(ファイル分割してOK)
kubectl apply -f demo-api-env.yaml
kubectl apply -f demo-api-file.yaml
kubectl apply -f demo-api-deploy.yaml
3-4) 動作確認👀(ポートフォワードでOK)
kubectl port-forward deploy/demo-api 8080:3000
PowerShellなら👇(どっちでもOK)
Invoke-RestMethod http://localhost:8080/hello
結果の greeting や featureNewEndpoint が ConfigMap由来になってたら勝ちです 🎉✨
4) ここが超大事🔥:ConfigMap更新は「どこまで自動」?🔁
結論👇(ここテストでめっちゃ出るやつです📝)
4-1) env(環境変数)で読んでる場合🌿
ConfigMapを更新しても、環境変数は自動で更新されません。Pod再起動が必要です。(Kubernetes)
つまり👇
- ✅ ConfigMapを更新
- ❌ でもコンテナ内の
process.envは変わらない - ✅ 反映させるには ロールアウト再起動(またはPod再作成)
kubectl rollout restart deploy/demo-api
4-2) ファイル(Volumeマウント)で読んでる場合📄
ConfigMapをVolumeで使ってると、反映は「いずれ」されます(即時じゃない)⏳ kubeletが周期的に同期して、遅延は最大で「同期周期+キャッシュ遅延」みたいな世界です。(Kubernetes)
さらに、すぐ反映させたい時は、Podのアノテーション更新で即時リフレッシュを促せます。(Kubernetes)
(例:PowerShellで“今だ!”って印を付ける)👇
$pod = (kubectl get pod -l app=demo-api -o jsonpath="{.items[0].metadata.name}")
kubectl annotate pod $pod config-refresh=(Get-Date -Format o) --overwrite
4-3) 罠⚠️:subPathを使うと更新されない😇💥
ConfigMapを subPath でマウントしてると、更新が届きません。(Kubernetes) 「設定を差し替えたい!」目的なら subPath は避けるのが無難です 🙅♂️
5) “設計超入門”ポイント🧠:何をConfigMapに入れる?
入れてOK(だいたい安全)✅
- ログレベル、フラグ、表示文言、URL(公開して問題ないもの)🪵🚩🗣️🌐
- “環境差があるけど秘密じゃない”設定 🌱
入れない(Secretや別の仕組みへ)❌🔐
- パスワード、APIキー、トークン ConfigMapは秘密を守る仕組みじゃないです。(Kubernetes)
“大きい設定ファイル”も注意⚠️
ConfigMapは 1MiB制限があるので(Kubernetes)、巨大JSONをドカンはやめようね…!📦💦
6) 便利機能:immutable ConfigMap(固める)🧊
ConfigMapには immutable を付けて「作ったら変更禁止」にできます(v1.19〜)🧊🔒(Kubernetes)
用途はこんな感じ👇
- 「勝手に設定が変わって事故る」を防ぐ 🧯
- 更新を“差し替え方式(新しいConfigMap名に切替)”に寄せられる 🔁
イメージ:
demo-api-env-v1を作るDeploymentがそれを参照- 変更したい時は
demo-api-env-v2を作って参照を切替 → “変更履歴”が残って強い 💪📜
7) トラブルシュート道場🥋🧯(困ったらここ)
(A) Podが起動しない / 変なエラーになる😵
まずはこれ👇(最強セット)
kubectl get pod -l app=demo-api
kubectl describe pod -l app=demo-api
kubectl logs -l app=demo-api --tail=200
「ConfigMapが存在しない」「キーがない」系は describe の Events に出がちです 🔎
※ConfigMap参照は optional にできて、存在しない場合に空扱いにする等も可能です。(Kubernetes)
(B) 変更したのに反映されない😇
- envで読んでる → 再起動必要(rollout restart)(Kubernetes)
- volumeで読んでる → 少し待つ or Podアノテーション更新(Kubernetes)
- subPath使ってる → 更新来ない(Kubernetes)
(C) ConfigMapの作り方が分からない📦
kubectl create configmap で ファイル/ディレクトリ/リテラルから作れます。(Kubernetes)
ただし学習と運用の両面で、最終的には YAMLで管理(apply) が扱いやすいです 🧠📄
8) AIで楽するコツ🤖✨(Copilot/Codex向け)
使えるプロンプト例👇(貼ってOK)
- 「このDeploymentにConfigMapをenvFromで注入して、キー不足時はoptionalにして」🧩✅
- 「ConfigMapをファイルとして
/app/config/app-config.jsonにマウントするYAMLを作って」📄📁 - 「ConfigMap更新がenvに反映されない理由を、超初心者向けに3行で」🧠📝
- 「subPathを使うと更新されないケースがある?対策もセットで教えて」⚠️🛡️
9) 小テスト📝(サクッと確認)
- ConfigMapは何を入れる箱?🔐はOK?
- envで注入した値は、ConfigMap更新で自動更新される?
- Volumeマウントは更新される?どれくらい遅れることがある?
- subPathを使うと何が起きる?
まとめ🎉
- ConfigMapは 秘密じゃない設定を外出しする箱 📦(Kubernetes)
- env注入は 更新されない → 反映は再起動 🔁(Kubernetes)
- volume注入は いずれ更新される(遅延あり)⏳(Kubernetes)
- subPathは 更新が届かない罠 ⚠️(Kubernetes)
- 迷ったら「秘密はSecret」「ConfigはConfigMap」で分離!🔐✅(Kubernetes)
次の章(Secret)に行く前に、もしよければ👇 「この章のハンズオン用に、今使ってるデモAPIのDeployment/ServiceのYAML(貼れる範囲でOK)」を出してくれたら、そのまま“あなたの構成に合わせて”ConfigMap注入パッチを作りますよ 💪😄