Kubernetes特集 | 第3章(Day 4 / 6)
Deployment・Service・ConfigMap・Probe・requests/limits。昨日のDeploymentに部品を足していくと、
「Runningになった」ではなく「止めずに更新して、戻せる」状態をつくれます。
4日目です。昨日の第2章では、API Serverの台帳を、Controller・Scheduler・kubeletが読んで差を埋めていく流れを追いました。今日は、その上で動かす"中身"の話です。昨日と同じDeployment api を作り直し、Service、ConfigMapとSecret、Probe、requests/limitsを1つずつ足して、複数台のWebアプリを止めずに更新し、戻せるところまで進めます。
昨日の最後に lab は片付けたので、今日も作るところから始めます。第2章を読んでいない方は、「Controllerは差を埋め続ける」だけ先に読んでおくと、ローリングアップデートの動きが追いやすくなります。
💡 通常のステートレスなWebアプリは、Podを直接作らず Deployment で管理します。DeploymentはReplicaSetを通じてPod数と更新履歴を持ち、Service は入れ替わるPodに安定した名前と仮想IPを渡します。設定はConfigMap、秘密情報はSecret、終わる処理はJob/CronJob、固有の名前とディスクが要る処理はStatefulSet、Nodeごとのエージェントは DaemonSet。運用の要点は、「起動したか」ではなく 「トラフィックを受けられるか」をProbeで表す こと、requests/limitsを測った値で決めること、更新とロールバックを事前に試すことです。
この章で手に入れてほしいのは、Running という表示を信用しすぎない目です。Podが動いていても、通信を受けられるとは限りません。Ready、EndpointSliceの中身、更新の進み具合を順に見て、「使える」を自分で確かめます。
kubectl diff → apply → rollout status → rollout undo の順で、更新して戻せる今日は3つのYAMLファイルを作ります。中心の deploy.yaml は、章の途中で3回に分けて書き足します。最終的に図3-1の形になります。
図3-1: 今日つくる構成。Deploymentを中心に、Service・ConfigMap/Secret・Probe・リソース値を足していく。
| ファイル | 中身 | 作る節 |
|---|---|---|
deploy.yaml | Deployment。3段階で書き足す | Deployment/ConfigMapとSecret/Probe |
svc.yaml | Service | Serviceとラベル選択 |
config.yaml | ConfigMapとSecret | ConfigMapとSecret |
fail-job.yaml・cron.yaml | Job・CronJob(後半) | JobとCronJob/わざと壊す演習 |
昨日と同じく、まずContextを確かめて lab を作ります。
kubectl config current-context # kind-xxx / minikube / docker-desktop などが出ればOK
kubectl create namespace lab
Podは、作り直されることが前提の一時的な実行単位です。ReplicaSetは指定した数のPodを維持しますが、通常は直接触りません。DeploymentがReplicaSetを作り、更新の履歴を持ちます。新しいイメージを適用すると、新しいReplicaSetを少しずつ増やし、古いReplicaSetを減らしていきます。第2章で見た親子関係(Deployment → ReplicaSet → Pod)の続きです。
まず、昨日のDeploymentを3台にして、更新のしかたを書き足した版を作ります。
# deploy.yaml(第1版)― 3台で動かし、更新中も3台を下回らせない
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
labels:
app.kubernetes.io/name: api
spec:
replicas: 3
minReadySeconds: 5 # Readyになってから5秒続いたら「使える」とみなす
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0 # 更新中に減ってよい数(0 = 常に3台を確保)
maxSurge: 1 # 更新中に一時的に増やしてよい数
selector:
matchLabels:
app.kubernetes.io/name: api
template:
metadata:
labels:
app.kubernetes.io/name: api
spec:
containers:
- name: api
image: nginx:stable
ports:
- name: http # 名前付きポート。Serviceから名前で指せる
containerPort: 80
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 500m
memory: 128Mi
このYAMLを適用すると、裏で起きること
api-<ハッシュ> を1つ作るrequests の空きを見てNodeを決め、kubeletが起動する(第2章の6ステップと同じ)kubectl -n lab apply -f deploy.yaml
kubectl -n lab rollout status deployment/api # deployment "api" successfully rolled out
kubectl -n lab get deploy,rs,pod
maxUnavailable: 0 は、全レプリカを常に使える状態にしておく前提です。Nodeの空きが少ないと、増やす1台が置けず、更新が進まないことがあります。何も書かなければ、maxSurge と maxUnavailable はどちらも既定で25%です。
⚠️ YAMLの中身は、本番ではそのまま使えません。 レジストリ、タグ、CPU、メモリの値はすべて例です。タグが存在し、Nodeがそのレジストリからイメージを取得できるかを、先に確認してください。nginx:stable のような動き続けるタグは学習用です。本番では、日付やコミットIDなど、中身が変わらないタグを使います。
PodのIPは、作り直すと変わります。だからクライアントは、PodではなくServiceへ接続します。Serviceはselectorに一致するPodをEndpointSliceにまとめ、ClusterIPとDNS名を提供します。selectorがPodのラベルと一致しなければ、Serviceは存在しても転送先がありません。第1章の演習3と同じ症状です。
図3-2: Serviceはselectorに合うPodをEndpointSliceに集め、Readyなものにだけ通信を届ける。
# svc.yaml ― 入れ替わるPodの前に、変わらない名前を置く
apiVersion: v1
kind: Service
metadata:
name: api
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: api # Podのラベルと1文字でも違うと転送先が0になる
ports:
- name: http
port: 80 # Serviceが受ける番号
targetPort: http # Pod側。名前付きポートで指す
kubectl -n lab apply -f svc.yaml
# 転送先(EndpointSlice)を見る。Serviceが繋がらないときは、DNSより先にここを見る
kubectl -n lab get endpointslice -l kubernetes.io/service-name=api
# 1台ずつ ready かどうかまで見る
kubectl -n lab get endpointslice -l kubernetes.io/service-name=api \
-o jsonpath='{range .items[*].endpoints[*]}{.addresses[0]} ready={.conditions.ready}{"\n"}{end}'
# クラスターの中から名前で呼ぶ(使い捨てのPodを作って、終わったら消す)
kubectl -n lab run curl --image=curlimages/curl:8.10.1 --rm -i --restart=Never -- \
curl -s -o /dev/null -w '%{http_code}\n' http://api
出力の例です。名前やIPは環境によって違います。
# 出力の例
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
api-7xk2p IPv4 80 10.244.0.5,10.244.0.6,10.244.0.7 12s
10.244.0.5 ready=true
10.244.0.6 ready=true
10.244.0.7 ready=true
200
pod "curl" deleted
port はServiceが受ける番号、targetPort はPodのポートです。名前付きポートを使うと、あとで番号を変えるときも意図が読み取れます。http://api と名前だけで呼べたのは、同じNamespaceの中にいるからです。別のNamespaceからは api.lab のように名前を足します。DNSの詳しい話は、明日の第4章で扱います。
ConfigMapは、環境ごとの設定や機能フラグをイメージの外に出すためのオブジェクトです。Secretはパスワードやトークン用ですが、Base64で書けば安全になるわけではありません。保存時の暗号化、RBAC、クラウドのKMS連携、ログへの露出防止は、別に設定します。
# config.yaml ― 設定と秘密情報を、イメージの外に出す
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
data:
LOG_LEVEL: info
API_TIMEOUT: 2s
---
apiVersion: v1
kind: Secret
metadata:
name: api-secret
type: Opaque
stringData: # 保存するときにAPIがBase64へ変換する
DATABASE_URL: "REPLACE_IN_SECRET_STORE"
deploy.yaml の ports: の下に、envFrom を書き足します(第2版)。順番は configMapRef → secretRef にしてください。演習2で使います。
envFrom: # ← 第2版で追加(ports と resources の間)
- configMapRef:
name: api-config
- secretRef:
name: api-secret
kubectl -n lab apply -f config.yaml # 先に作る。参照先がないとPodが起動できない(演習2)
kubectl -n lab apply -f deploy.yaml # Podの中身が変わるので、ローリングアップデートが走る
kubectl -n lab rollout status deployment/api
kubectl -n lab exec deploy/api -- printenv LOG_LEVEL API_TIMEOUT
出力の例は info と 2s です。
Secretが「隠されていない」ことも確かめておきます。
kubectl -n lab get secret api-secret -o jsonpath='{.data.DATABASE_URL}' | base64 -d; echo
# REPLACE_IN_SECRET_STORE ← get secret の権限がある人は誰でも読める
もう1つ、変更は自動では届きません。環境変数で注入した値は、起動済みのプロセスへ自動では反映されないからです。
# config.yaml の LOG_LEVEL を debug に変えて適用
kubectl -n lab apply -f config.yaml
kubectl -n lab exec deploy/api -- printenv LOG_LEVEL # まだ info のまま
kubectl -n lab rollout restart deployment/api # Podを順番に作り直す
kubectl -n lab rollout status deployment/api
kubectl -n lab exec deploy/api -- printenv LOG_LEVEL # debug になる
⚠️ Secretの扱いは、環境で変わります。 実運用では、SecretをGitに平文で置かないよう、External Secrets、Sealed Secrets、SOPSなどを検討します。etcdでの保存時暗号化が有効かどうかは、クラスターの設定やマネージドかどうかで違います。ConfigMapをファイルとしてマウントした場合は、時間差で中身が更新されますが、アプリが読み直さなければ同じことです。
Probeは、コンテナの状態をkubeletが定期的に確かめる仕組みです。3種類あり、失敗したときに起きることがまったく違います。
| Probe | 何を表すか | 失敗したら | よくある誤り |
|---|---|---|---|
| startupProbe | 起動処理が終わったか | 終わるまで他の2つを始めない。上限まで失敗すると再起動 | 起動の遅いアプリに付けず、livenessが初期化中に殺す |
| readinessProbe | 今トラフィックを受けてよいか | EndpointSliceで ready=false になり、Serviceから外れる(再起動はしない) | 付けないと、起動直後の準備中Podに通信が届く |
| livenessProbe | 再起動が必要なほど壊れているか | kubeletがコンテナを再起動する | DBの疎通まで含め、DBの一時障害で全Podが同時に再起動する |
図3-3: 3つのProbeの役割。readinessは入口から外すだけ、livenessは再起動する。
deploy.yaml の resources: の下に、readinessとlivenessを書き足します(第3版、これが完成形)。nginxはすぐ起動するので、startupProbeは付けません。
readinessProbe: # ← 第3版で追加
httpGet:
path: /
port: http
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3
livenessProbe:
httpGet:
path: /
port: http
periodSeconds: 10
failureThreshold: 3
書き足したあとの完成形です。以降の演習は、この deploy.yaml を使います。
# deploy.yaml(完成形)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
labels:
app.kubernetes.io/name: api
spec:
replicas: 3
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: api
template:
metadata:
labels:
app.kubernetes.io/name: api
spec:
containers:
- name: api
image: nginx:stable
ports:
- name: http
containerPort: 80
envFrom:
- configMapRef:
name: api-config
- secretRef:
name: api-secret
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 500m
memory: 128Mi
readinessProbe:
httpGet:
path: /
port: http
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3
livenessProbe:
httpGet:
path: /
port: http
periodSeconds: 10
failureThreshold: 3
kubectl -n lab apply -f deploy.yaml
kubectl -n lab rollout status deployment/api
kubectl -n lab get pods # READY 1/1 が3つ
kubectl -n lab describe pod -l app.kubernetes.io/name=api | grep -E 'Readiness|Liveness'
アプリ側に用途別のエンドポイントを用意できるなら、本番では次のような形になります。
startupProbe:
httpGet:
path: /startup
port: http
failureThreshold: 30
periodSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: http
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: http
periodSeconds: 10
failureThreshold: 3
📌 エンドポイントは、依存先全体の疎通を単純に返さず、readinessとlivenessの意味を分けます。DBが一時的に遅いだけでlivenessが失敗し、全Podが同時に再起動する設計は危険です。初期遅延・タイムアウト・成功回数・失敗回数は、負荷試験と障害訓練で調整します。
requests はSchedulerが配置を決めるときに使う予約量、limits はコンテナが使える上限です。第2章で見たとおり、Schedulerが見るのは実際の使用量ではなく、requestsの合計でした。requestsが小さすぎるとNodeに詰め込みすぎ、limitsが小さすぎるとCPUを絞られたり、OOMKilledで落ちたりします。値は希望ではなく、平常時とピーク時のメトリクスから決めます。
図3-4: requestsは置き場所を決めるための予約、limitsは超えたときの扱いが決まる上限。
| 症状 | 原因の候補 | 見る場所 |
|---|---|---|
Pending(Insufficient cpu/memory) | requestsが大きすぎる、Nodeの空き不足 | describe pod のEvents、describe node の Allocated resources |
| 遅いのに落ちない | CPU limitsに当たって絞られている | メトリクス(kubectl top pod など) |
再起動が増える・OOMKilled | メモリlimitsを超えた | describe pod の Last State: Terminated、Reason: OOMKilled、Exit Code: 137 |
作ったPodが、どのQoSクラスになっているかも見られます。
kubectl -n lab get pod -l app.kubernetes.io/name=api \
-o custom-columns=NAME:.metadata.name,QOS:.status.qosClass
# requests < limits なので Burstable。requests と limits を全部同じにすると Guaranteed になる
kubectl -n lab top pod # metrics-server がないと error になる(下の注記)
⚠️ JavaやNode.jsは、コンテナのメモリ制限を認識するか確認してください。 limitを超えると、アプリが自分でエラーを返す前に終了することがあります。NamespaceにResourceQuotaやLimitRangeを設定する場合は、開発用のデフォルト値が本番の性能を歪めないよう、適用範囲を明記します。なお kubectl top には metrics-server が必要です。kind には既定で入っていません(minikube は minikube addons enable metrics-server)。
更新の前に、kubectl diff で差分を見て、対象のContextをもう一度確かめます。適用したら rollout status とアプリのメトリクスを見ます。失敗したら rollout history で履歴を確認し、原因を記録してから戻します。
図3-5: maxSurge 1・maxUnavailable 0 のローリングアップデート。新しいPodがReadyになってから、古いPodを1つ減らす。
deploy.yaml の image: nginx:stable を nginx:mainline に書き換えてから、次の順で進めます。
kubectl config current-context # 対象を再確認
kubectl -n lab diff -f deploy.yaml # image の行が変わることを見る(generation の行も変わります)
kubectl -n lab apply -f deploy.yaml
kubectl -n lab rollout status deployment/api --timeout=5m
kubectl -n lab annotate deployment/api kubernetes.io/change-cause="nginx:mainline へ更新" --overwrite
kubectl -n lab rollout history deployment/api
kubectl -n lab get rs # 旧ReplicaSetが DESIRED 0 で残っている
rollout history の出力の例です。番号は、ここまでの操作の回数で変わります。
# 出力の例
deployment.apps/api
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
4 <none>
5 nginx:mainline へ更新
1は第1版、2は envFrom の追加、3は ConfigMap を反映させた rollout restart、4はProbeの追加です。
戻すときは次のとおりです。
kubectl -n lab rollout undo deployment/api # 1つ前の版へ
kubectl -n lab rollout status deployment/api
kubectl -n lab rollout history deployment/api # 戻した版は、新しい番号で末尾に付く
# 特定の版へ: kubectl -n lab rollout undo deployment/api --to-revision=4(番号は history で確かめてから)
rollout undo が戻すのはクラスターの中だけで、手元の deploy.yaml は mainline のままです。次に apply すると、また mainline になります。戻したら、ファイル(Git)も戻してください。古いReplicaSetは、revisionHistoryLimit(既定10)の数まで残ります。
📌 ロールバックしても、DBのスキーマ変更が不可逆なら、アプリだけは戻せません。後方互換のマイグレーション、段階的なフラグ、旧アプリでも読めるカラム、バックアップからの復旧手順まで含めて、リリースを設計します。
Jobは、指定した回数だけ正常に終わることを目指すワークロードです。データ移行、画像の一括処理、バックフィルなどに使います。CronJobは、スケジュールに従ってJobを作ります。定期処理が重なっても安全か、前回が長引いたらどうするか、履歴を何件残すかを、先に決めておきます。
# cron.yaml ― 毎時15分にレポートを作る(学習用)
apiVersion: batch/v1
kind: CronJob
metadata:
name: report
spec:
schedule: "15 * * * *"
timeZone: "Asia/Tokyo" # 省略するとkube-controller-managerのタイムゾーンで解釈
concurrencyPolicy: Forbid # 前回が終わっていなければ、今回は作らない
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 2 # 失敗したら2回まで作り直す
template:
spec:
restartPolicy: Never
containers:
- name: report
image: busybox:1.36
command: ["sh", "-c", "date; echo generate report"]
kubectl -n lab apply -f cron.yaml
kubectl -n lab get cronjob
# 15分を待たずに、CronJobの型から1回だけJobを作る
kubectl -n lab create job report-now --from=cronjob/report
kubectl -n lab get job report-now # COMPLETIONS 1/1
kubectl -n lab logs job/report-now # 日時と generate report
| 項目 | 決めること |
|---|---|
backoffLimit | 何回まで作り直すか(既定6) |
concurrencyPolicy | 重なったときの扱い。Allow(既定)・Forbid・Replace |
successfulJobsHistoryLimit・failedJobsHistoryLimit | 終了後のJobを何件残すか |
restartPolicy | Jobでは Never か OnFailure のみ |
Jobは再実行されるので、処理はできるだけ冪等にします。外部APIへ二重送信する処理なら、実行IDを記録して、重複を検出できるようにしてください。終了後のJobを消す運用にするなら、ログを外部へ転送して、失敗の履歴を追える保持期間を確保します。
⚠️ CronJobのスケジュールは、環境の影響を受けます。 クラスターのタイムゾーン、Kubernetesのバージョン、コントロールプレーンが止まっていたときの挙動に注意してください。timeZone が使えないバージョンやマネージド環境もあるので、自分のクラスターで kubectl explain cronjob.spec.timeZone を確かめます。
StatefulSetは、Podごとに安定した名前と順序、PVCとの対応が必要な、DBやキューなどに使います。ただし、StatefulSetを使えばDBが安全になるわけではありません。レプリケーション、フェイルオーバー、バックアップ、クォーラム、ストレージの性能は、自分で設計します。
DaemonSetは、各Node(または条件に合うNode)に1つずつPodを置きます。ログエージェント、Node監視、ネットワークプラグインが典型です。Nodeが増えればPodも増えるので、外部サービスへの接続数やログ量が増える影響を見積もります。特定のNodeだけに置くなら、Node label、Taint、Tolerationを組み合わせます。
| Deployment | StatefulSet | DaemonSet | |
|---|---|---|---|
| Podの名前 | ランダム | db-0、db-1 の連番 | Nodeごとに1つ |
| ディスク | 共有か、なし | Podごとに専用のPVC | 基本はなし。Nodeのパスを使うことも |
| 数の決め方 | replicas | replicas | Nodeの数 |
| 典型 | Web API | DB・キュー | ログ収集・監視・CNI |
DaemonSetは、観察だけしておきましょう。作る必要はありません。
kubectl get daemonset -A # kube-system に kube-proxy や CNI のDaemonSetが見える
名前は環境によって違います(kind なら kindnet など)。StatefulSetとPVCは、第4章で実際に作ります。
完成形の api(Service・設定・Probe付き)を使って、3つ壊します。壊すたびに、利用者に影響が出ているかをEndpointSliceで確かめてから直してください。
readinessProbeのパスを、nginxにない /ready に変えます。YAMLではなく、パッチで変えます。
# readinessProbe のパスを、nginxにない /ready に変える
kubectl -n lab patch deployment api --type=json \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/path","value":"/ready"}]'
kubectl -n lab rollout status deployment/api --timeout=60s
kubectl -n lab get pods
新しいPodが1つだけ作られ、READY 0/1(STATUSはRunning)になります。古い3つは 1/1 のままです。rollout status は Waiting for deployment "api" rollout to finish: 1 out of 3 new replicas have been updated... と表示したあと、error: timed out waiting for the condition で終わります。
kubectl -n lab describe pod <READY 0/1 のPod名> # Events
# Warning Unhealthy ... Readiness probe failed: HTTP probe failed with statuscode: 404
kubectl -n lab get endpointslice -l kubernetes.io/service-name=api \
-o jsonpath='{range .items[*].endpoints[*]}{.addresses[0]} ready={.conditions.ready}{"\n"}{end}'
# 新しいPodだけ ready=false。通信は古い3台にだけ届いている
maxUnavailable が0なので、古いPodは減りません。利用者への影響はありません。Runningでも、Readyでなければ「使える」とは言えません。
kubectl -n lab rollout undo deployment/api
kubectl -n lab rollout status deployment/api
パッチはファイルの外で行った変更なので、deploy.yaml はそのままで構いません。
envFrom の1つ目、ConfigMapの名前を打ち間違えた状態を作ります。
kubectl -n lab patch deployment api --type=json \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/envFrom/0/configMapRef/name","value":"api-confg"}]'
kubectl -n lab get pods
patch自体は成功します。API Serverは、参照先が存在するかどうかを確かめないからです。新しいPodは CreateContainerConfigError になり、Eventsに Error: configmap "api-confg" not found と出ます。古い3台は、Running・Readyのままです。第2章の言い方では、kubeletの層で止まっています。
kubectl -n lab rollout undo deployment/api
kubectl -n lab rollout status deployment/api
必ず exit 1 で終わるJobを作ります。
# fail-job.yaml ― 必ず exit 1 で終わる
apiVersion: batch/v1
kind: Job
metadata:
name: fail-once
spec:
backoffLimit: 2
template:
spec:
restartPolicy: Never
containers:
- name: task
image: busybox:1.36
command: ["sh", "-c", "echo start; exit 1"]
kubectl -n lab apply -f fail-job.yaml
kubectl -n lab get pods -l job-name=fail-once -w # 1分ほどで Error のPodが3つ(最初の1回+作り直し2回)。Ctrl+Cで終了
kubectl -n lab describe job fail-once # Warning BackoffLimitExceeded Job has reached the specified backoff limit
kubectl -n lab logs job/fail-once # start
作り直しの間隔は、少しずつ長くなります。同じ処理が最大3回走るので、二重に計上しない作り(冪等性)が要ります。直すときは、Jobのtemplateが作成後に書き換えられないため、一度消してから作り直します。
kubectl -n lab delete job fail-once
# fail-job.yaml の command を "echo start; exit 0" に変えて、もう一度
kubectl -n lab apply -f fail-job.yaml
kubectl -n lab get job fail-once # COMPLETIONS 1/1
第1章・第2章と同じ6項目です。今日は、「利用者に影響があったか」を修正の欄に添えてください。
# 演習メモの例
日時/Context : 2026-10-22 21:30 / kind-kind(Namespace: lab)
症状 : patch 後、rollout status が60秒で timed out。新Podが READY 0/1
最初に見たもの: describe pod → Readiness probe failed: statuscode 404
原因 : readinessProbe のパスが存在しない /ready。止まった層は kubelet(Probe)
修正 : rollout undo。EndpointSlice は古い3台のみ ready=true で、利用者への影響なし
再発防止 : Probeのパスはアプリの実装と一緒にレビューし、ステージングで rollout status まで確認する
リソースを選ぶときは、まずプロセスの寿命と更新の単位を決めます。迷ったら、図3-6を上から順に質問してください。リソース名からではなく、処理の寿命とデータから決めます。
図3-6: 迷ったら上から質問する。リソース名からではなく、処理の寿命とデータから決める。
| 処理の性質 | 候補 |
|---|---|
| 常時稼働・ステートレスなHTTP API | Deployment |
| 完了して結果を残す | Job |
| 定刻に起動する | CronJob |
| Nodeごとに1つ必要なエージェント | DaemonSet |
| 識別子と専用ボリュームが必要なデータサービス | StatefulSet |
迷ったままDeploymentでDBを動かすと、Podの再作成や順序の入れ替わりが、データの前提と合わなくなります。迷ったときは、3つの質問が役に立ちます。失敗したとき、同じPodを復元できるか。処理を再実行できるか。識別子とデータを保持する必要があるか。この答えを言えれば、選んだ理由も説明しやすくなります。
今日作ったものを、まとめて確認するコマンドです。
kubectl -n lab get deploy,statefulset,daemonset,job,cronjob
kubectl -n lab describe deployment api
kubectl -n lab get pod -o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[*].ready,RESTARTS:.status.containerStatuses[*].restartCount'
kubectl -n lab rollout history deployment/api
更新の前に、Readyの判定、止めてよい数、ロールバックの条件、データの互換性を、言葉にして決めておきます。PodがRunningになっただけで成功とはせず、利用者のリクエストとバックグラウンド処理まで確認します。
| 決めること | この章で対応する設定・確認 |
|---|---|
| Readyの判定 | readinessProbe・minReadySeconds |
| 止めてよい数 | maxUnavailable・maxSurge |
| ロールバック条件 | rollout status のタイムアウト、エラー率などのメトリクス、rollout undo |
| データの互換性 | 後方互換のマイグレーション、旧アプリでも読めるカラム、バックアップ |
kubectl delete namespace lab
kubectl get namespaces # lab が消えたことを確認
今日も、ロードバランサーやディスクは作っていません。CronJobも、Namespaceごと消えます。
🔖 明日10月23日(金)、第4章「ネットワークとストレージ」を公開します。 今日作ったServiceが名前でどう引かれるか、外から届く経路(IngressとGateway API)、NetworkPolicyでの通信の制限、PV/PVCとバックアップを扱います。
この特集は10月24日まで、毎日1ページずつ増えていきます。新しい章へのリンクは、すべて特集トップに追加されます。章ごとにブックマークしなくても、特集トップを1つ保存しておけば迷いません。
毎日の公開は、X(@BusinessHub413)でもお知らせします。
※本章の記述は2026年10月時点の公式ドキュメントに基づきます。イベントの文言、kubectl の出力形式、CronJobの timeZone などは、Kubernetesのバージョンや学習環境によって少し異なることがあります。
「うちはKubernetesが要るのか」「ECSやCloud Runで足りるのか」から、
クラスター設計・運用体制づくりまで、30分の無料相談で承ります。