TT Lab
はじめる
学ぶ 学習パス コース

CKA — Kubernetes管理者

壊してから直す

TT Labで続きを見る

目標

実際の現場で最もよく出会う5つの障害を、自分で作って、自分で直しながら、症状から原因へ下りていく順序を、体に刻みます。

なぜ重要なのか

トラブルシューティングは、CKAの配点の30%で、最も大きなドメインです。しかし、直したものだけを見ても、学べることはありません。そのため、このラボは、壊れた状態を受講生が作り、症状をファイルに残し、そのあとに直す順序で設計しました。各ステップの採点は、直った結果だけでなく、壊れていたという証拠もあわせて見ます。

症状を残す習慣そのものが、実務の技術です。障害が終われば、証拠は消えます。原因をあとで説明するには、その瞬間のイベントと状態を残しておく必要があります。

前のステップで作ったクラスターの状態(cordonされたノード、テイントされたノード)は、あとのステップにもそのまま残ります。最後の問題は、その状態を正確に覚えていてはじめて解けます。

ステップ

  1. ネームスペースcka-brokenを作成し、Deploymentweb(レプリカ2)を、イメージnginx:1.99-nonexistentで作成してください。その誤ったイメージタグが見える出力を/root/cka-broken/bad-image.txtに保存したあと、イメージをnginx:1.27に入れ替えて、2/2 Readyにしてください。Deploymentは削除せず、イメージだけを直してください。
  2. Podheavy(イメージnginx:1.27)を、requestscpu: 500、memory: 2000Giで作成してください。Pendingになることを確認して、その理由が含まれた出力を/root/cka-broken/pending.txtに保存してください。heavyは削除せずに残したまま、Deploymentheavy-fixed(レプリカ1、イメージnginx:1.27、requestscpu: 500m、memory: 2000Mi)を作成して、1/1 Readyにしてください。
  3. サービスapi-svc(セレクターapp=api、port 80)を作成し、Deploymentapiを、Podラベルとセレクターをapp=api-v2と間違えて作成してください。api-svcのエンドポイントが空であることを/root/cka-broken/svc-before.txtに保存したあと、apiをラベルapp=apiに正して、レプリカ2をReadyにしてください。サービスのセレクターはapp=apiのままにしてください。
  4. ネームスペースcka-broken-quotaを作成し、ResourceQuotacka-quotaをpods: "2"、requests.cpu: "1"で作成してください。Deploymentq-app(レプリカ4、イメージnginx:1.27、requestscpu: 200m)を作成すると、一部だけが起動します。exceeded quotaが見えるイベントを/root/cka-broken/quota.txtに保存したあと、クォータのpodsを5に上げて、4/4 Readyにしてください。
  5. cka-brokenにDeploymentcritical(レプリカ2、イメージnginx:1.27、Podラベルapp=critical)とPDBcritical-pdb(セレクターapp=critical、minAvailable: 2)を作成してください。lab-node-2をdrainしてみて、塞がれるメッセージを/root/cka-broken/pdb.txtに保存したあと、minAvailableを1に下げて、lab-node-2をcordon + drainして完全に空にしてください。
  6. lab-node-0に、ラベルdisktype=ssdとテイントmaintenance=true:NoScheduleを設定してください。Podneeds-toleration(イメージnginx:1.27、nodeSelectordisktype=ssd、トレラレーションなし)を作成してPendingを確認し、理由を/root/cka-broken/taint.txtに保存してください。needs-tolerationは残したまま、Podneeds-toleration-fixedを、同じnodeSelectorにトレラレーションまで付けて作成し、lab-node-0に配置してください。
  7. Poddata-app(イメージnginx:1.27)が、PVCapp-dataを/dataにマウントするように作成してください。PVCがまだなく、起動できない理由を/root/cka-broken/pvc.txtに保存したあと、PVcka-fix-pv(1Gi、RWO、storageClassNamecka-fix、hostPath/mnt/cka-fix)とPVCapp-data(1Gi、RWO、cka-fix)を作成してBoundさせ、data-appがRunningになるようにしてください。
  8. Deploymentrecovered(レプリカ4、イメージnginx:1.27、Podラベルapp=recovered)をcka-brokenに作成してください。requestsはcpu: 100m、memory: 128Mi、maintenance=true:NoScheduleのトレラレーション、topologySpreadConstraintsはmaxSkew 1 / topologyKeykubernetes.io/hostname / whenUnsatisfiableScheduleAnyway / labelSelectorapp=recoveredです。4/4 Readyにして、直した5つの問題を/root/cka-broken/summary.mdにまとめてください。このファイルには、image、taint、selector、quota、pdbの5つの語がすべて入っている必要があります。

参考

誤ったイメージタグ

ネームスペースcka-brokenを作成し、Deploymentweb(レプリカ2)を、イメージnginx:1.99-nonexistentで作成してください。その誤ったイメージタグが見える出力を/root/cka-broken/bad-image.txtに保存したあと、イメージをnginx:1.27に入れ替えて、2/2 Readyにしてください。Deploymentは削除せず、イメージだけを直してください。

まず、誤ったタグで作成して証拠を残してから、イメージだけを入れ替えてください。Deploymentを削除して作り直すと、問題のリビジョンが消えて、採点で引っかかります。

リソース要求の単位のミス

Podheavy(イメージnginx:1.27)を、requestscpu: 500、memory: 2000Giで作成してください。Pendingになることを確認して、その理由が含まれた出力を/root/cka-broken/pending.txtに保存してください。heavyは削除せずに残したまま、Deploymentheavy-fixed(レプリカ1、イメージnginx:1.27、requestscpu: 500m、memory: 2000Mi)を作成して、1/1 Readyにしてください。

cpuの値でmを抜かすと、ミリコアではなくコアになります。describeのEventsの節に、スケジューラーがなぜ失敗したかが、そのまま出ます。

サービスとラベルがずれたDeployment

サービスapi-svc(セレクターapp=api、port 80)を作成し、Deploymentapiを、Podラベルとセレクターをapp=api-v2と間違えて作成してください。api-svcのエンドポイントが空であることを/root/cka-broken/svc-before.txtに保存したあと、apiをラベルapp=apiに正して、レプリカ2をReadyにしてください。サービスのセレクターはapp=apiのままにしてください。

Deploymentのspec.selectorは不変です。間違って作成したなら、修正ではなく作り直す必要があります。サービス側のセレクターには、触れないでください。

ResourceQuotaの超過

ネームスペースcka-broken-quotaを作成し、ResourceQuotacka-quotaをpods: "2"、requests.cpu: "1"で作成してください。Deploymentq-app(レプリカ4、イメージnginx:1.27、requestscpu: 200m)を作成すると、一部だけが起動します。exceeded quotaが見えるイベントを/root/cka-broken/quota.txtに保存したあと、クォータのpodsを5に上げて、4/4 Readyにしてください。

クォータに引っかかったPodは、Podではなく、ReplicaSetのイベントとして現れます。クォータを上げる前に、そのイベントを先に保存してください。

PDBで塞がれたdrain

cka-brokenにDeploymentcritical(レプリカ2、イメージnginx:1.27、Podラベルapp=critical)とPDBcritical-pdb(セレクターapp=critical、minAvailable: 2)を作成してください。lab-node-2をdrainしてみて、塞がれるメッセージを/root/cka-broken/pdb.txtに保存したあと、minAvailableを1に下げて、lab-node-2をcordon + drainして完全に空にしてください。

レプリカ2でminAvailable 2なら、1つも外せません。--forceで押し切る代わりに、PDBが何を守ろうとしているのかを、もう一度計算してください。

トレラレーションの欠落

lab-node-0に、ラベルdisktype=ssdとテイントmaintenance=true:NoScheduleを設定してください。Podneeds-toleration(イメージnginx:1.27、nodeSelectordisktype=ssd、トレラレーションなし)を作成してPendingを確認し、理由を/root/cka-broken/taint.txtに保存してください。needs-tolerationは残したまま、Podneeds-toleration-fixedを、同じnodeSelectorにトレラレーションまで付けて作成し、lab-node-0に配置してください。

NoScheduleテイントは、新しいPodだけを防ぎ、すでに起動しているPodには手を触れません。問題のPodは削除せず、残しておいてください。

存在しないPVC

Poddata-app(イメージnginx:1.27)が、PVCapp-dataを/dataにマウントするように作成してください。PVCがまだなく、起動できない理由を/root/cka-broken/pvc.txtに保存したあと、PVcka-fix-pv(1Gi、RWO、storageClassNamecka-fix、hostPath/mnt/cka-fix)とPVCapp-data(1Gi、RWO、cka-fix)を作成してBoundさせ、data-appがRunningになるようにしてください。

先にPodを作成して失敗を確認してから、ボリュームを作成してください。PVCが結び付くと、スケジューラーがそのPodを再び試すので、少し待てばよいです。

総合: 残ったクラスターで復旧デプロイをする

Deploymentrecovered(レプリカ4、イメージnginx:1.27、Podラベルapp=recovered)をcka-brokenに作成してください。requestsはcpu: 100m、memory: 128Mi、maintenance=true:NoScheduleのトレラレーション、topologySpreadConstraintsはmaxSkew 1 / topologyKeykubernetes.io/hostname / whenUnsatisfiableScheduleAnyway / labelSelectorapp=recoveredです。4/4 Readyにして、直した5つの問題を/root/cka-broken/summary.mdにまとめてください。このファイルには、image、taint、selector、quota、pdbの5つの語がすべて入っている必要があります。

今このクラスターには、cordonされたノードとテイントされたノードが、1つずつあります。どちらかを使うには何が必要かを計算してから、デプロイしてください。