Skip to main content

第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.jsonenv用は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

結果の greetingfeatureNewEndpoint が 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) 小テスト📝(サクッと確認)

  1. ConfigMapは何を入れる箱?🔐はOK?
  2. envで注入した値は、ConfigMap更新で自動更新される?
  3. Volumeマウントは更新される?どれくらい遅れることがある?
  4. subPathを使うと何が起きる?

まとめ🎉

  • ConfigMapは 秘密じゃない設定を外出しする箱 📦(Kubernetes)
  • env注入は 更新されない → 反映は再起動 🔁(Kubernetes)
  • volume注入は いずれ更新される(遅延あり)⏳(Kubernetes)
  • subPathは 更新が届かない罠 ⚠️(Kubernetes)
  • 迷ったら「秘密はSecret」「ConfigはConfigMap」で分離!🔐✅(Kubernetes)

次の章(Secret)に行く前に、もしよければ👇 「この章のハンズオン用に、今使ってるデモAPIのDeployment/ServiceのYAML(貼れる範囲でOK)」を出してくれたら、そのまま“あなたの構成に合わせて”ConfigMap注入パッチを作りますよ 💪😄