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

CNPA — クラウドネイティブプラットフォームエンジニアリングアソシエイト

プラットフォームの基準線を立てて上げる

TT Labで続きを見る

目標

プラットフォームが要求する最小ベースラインをネームスペースに固定し、それが実際に拒否することを確認したうえで、1段階引き上げる過程を、影響調査から例外処理まで一通り回します。

なぜ重要なのか

ベースラインを文書にしか置かなければ、何も拒否できず、拒否できないルールは、半年後には半分が破られています。逆に、最初からすべてを塞ぐと、昨日までできていたデプロイが今日塞がれ、プラットフォームが障害の原因として記憶されます。そのため実務では、「いま守れるレベルを強制し、次のレベルは警告で事前に知らせ、引き上げる前に影響を調べ、守れない側には期限付きの例外を与える」という順序で動きます。このラボは、その順序をそのまま手で踏んでいきます。準拠(conformance)を一緒に扱う理由も同じです。廃止されたAPIを残しておくと、ある日クラスターをアップグレードした瞬間に、デプロイが丸ごと止まりますが、その兆候を事前に読み取る目が、プラットフォームチームの基本スキルです。

ステップ

  1. ネームスペースplatform-baselineを作成し、ラベルを付けてください。pod-security.kubernetes.io/enforce=baseline、pod-security.kubernetes.io/enforce-version=v1.30、pod-security.kubernetes.io/warn=restricted、pod-security.kubernetes.io/warn-version=v1.30、platform.labhub.io/owner=platform-teamです。
  2. /root/cnpa-base/bad-probe.yamlに、platform-baselineネームスペースのPod bad-probeを作成してください。spec.hostPID: trueで、コンテナは名前がprobe、イメージがghcr.io/labhub/probe:1.0.0です。適用してみて、その失敗の出力を標準エラー出力も含めて/root/cnpa-base/reject.txtに保存してください。Pod bad-probeはクラスターに残っていてはいけません。
  3. /root/cnpa-base/legacy.yamlに、apiVersion: extensions/v1beta1のIngress orders-legacy(ネームスペースplatform-baseline)を作成してください。適用してみて、その失敗の出力を/root/cnpa-base/legacy-reject.txtに保存してください。
  4. /root/cnpa-base/app.yamlにapps/v1のDeployment ordersを作成して適用してください。spec.replicas: 2、メタデータラベルapp.kubernetes.io/name: ordersとapp.kubernetes.io/part-of: cnpa-platform、コンテナ名はapp、イメージはghcr.io/labhub/orders:1.4.0、コンテナポートは、名前http(8080)とmetrics(9102)の2つです。/root/cnpa-base/edge.yamlには、Service orders(セレクターapp.kubernetes.io/name: orders、ポート名httpは80から8080へ、ポート名metricsは9102から9102へ)と、networking.k8s.io/v1のIngress orders(ホストorders.labhub.internal、パス/、pathType: Prefix、バックエンドはService ordersのポート名http)を作成して適用してください。
  5. /root/cnpa-base/servicemonitor.yamlにServiceMonitor orders(ネームスペースplatform-baseline)を作成して適用してください。spec.selector.matchLabelsはapp.kubernetes.io/name: orders、spec.endpoints[0].portはmetrics、intervalは30sです。
  6. /root/cnpa-base/exception.yamlにネームスペースplatform-legacyを作成して適用してください。ラベルはpod-security.kubernetes.io/enforce: baselineとpod-security.kubernetes.io/enforce-version: v1.30、アノテーションはplatform.labhub.io/exception-expires(YYYY-MM-DD形式の期限)とplatform.labhub.io/exception-reason(理由)です。同じファイルにDeployment legacy-batch(replicas 1、イメージghcr.io/labhub/legacy-batch:0.9.0、セキュリティ設定なし)も入れてください。そのあと、このネームスペースをrestrictedに引き上げるラベル変更を、サーバーdry-runで送り、その出力を標準エラー出力も含めて/root/cnpa-base/upgrade-check.txtに保存してください。legacy-batchは修正せず、そのままにしておきます。
  7. ordersのPodテンプレートをrestrictedの基準に合わせてください。PodレベルにrunAsNonRoot: true、runAsUser: 10001、seccompProfile.type: RuntimeDefaultを、コンテナレベルにallowPrivilegeEscalation: falseとcapabilities.drop: [ALL]を入れます。再度適用してPodが新しく起動したあとで、platform-baselineのenforceラベルをrestrictedに引き上げてください。enforce-versionはv1.30のままにします。
  8. /root/cnpa-base/baseline.jsonに現状を残してください。キーはnamespace、enforce、enforce_version、deployments(そのネームスペースのDeploymentの数)、servicemonitor(名前)、exception_namespace、exception_expiresです。

参考

ベースラインのネームスペース

ネームスペースplatform-baselineを作成し、ラベルを付けてください。pod-security.kubernetes.io/enforce=baseline、pod-security.kubernetes.io/enforce-version=v1.30、pod-security.kubernetes.io/warn=restricted、pod-security.kubernetes.io/warn-version=v1.30、platform.labhub.io/owner=platform-teamです。

Pod Security Admissionは、ネームスペースのラベルだけで動作します。いま守れるレベルはenforceに、次に引き上げるレベルはwarnに設定します。レベルごとに、バージョンのラベルも一緒に固定してください。

本当に拒否するかを確認する

/root/cnpa-base/bad-probe.yamlに、platform-baselineネームスペースのPod bad-probeを作成してください。spec.hostPID: trueで、コンテナは名前がprobe、イメージがghcr.io/labhub/probe:1.0.0です。適用してみて、その失敗の出力を標準エラー出力も含めて/root/cnpa-base/reject.txtに保存してください。Pod bad-probeはクラスターに残っていてはいけません。

ラベルを付けただけでポリシーが動くわけではありません。ホストの名前空間を要求するPodを作成してみて、そのとき出る拒否メッセージを、標準エラー出力も含めてファイルに残してください。

廃止されたAPIはなぜ拒否されるのか

/root/cnpa-base/legacy.yamlに、apiVersion: extensions/v1beta1のIngress orders-legacy(ネームスペースplatform-baseline)を作成してください。適用してみて、その失敗の出力を/root/cnpa-base/legacy-reject.txtに保存してください。

廃止されたグループで書かれたマニフェストは、文法エラーではなくマッピング失敗で落ちます。そのメッセージをそのまま残し、本当にそのグループが提供されていないかを、クラスターに確認してみてください。

上位バージョンのAPIに移行して適用する

/root/cnpa-base/app.yamlにapps/v1のDeployment ordersを作成して適用してください。spec.replicas: 2、メタデータラベルapp.kubernetes.io/name: ordersとapp.kubernetes.io/part-of: cnpa-platform、コンテナ名はapp、イメージはghcr.io/labhub/orders:1.4.0、コンテナポートは、名前http(8080)とmetrics(9102)の2つです。/root/cnpa-base/edge.yamlには、Service orders(セレクターapp.kubernetes.io/name: orders、ポート名httpは80から8080へ、ポート名metricsは9102から9102へ)と、networking.k8s.io/v1のIngress orders(ホストorders.labhub.internal、パス/、pathType: Prefix、バックエンドはService ordersのポート名http)を作成して適用してください。

Deploymentはapps/v1、Ingressはnetworking.k8s.io/v1です。v1のIngressはパスごとにpathTypeを要求し、バックエンドはServiceの名前とポートを別々に指定します。ポートを番号ではなく名前で指定すると、Serviceとずれません。

スクレイプの契約を結ぶ

/root/cnpa-base/servicemonitor.yamlにServiceMonitor orders(ネームスペースplatform-baseline)を作成して適用してください。spec.selector.matchLabelsはapp.kubernetes.io/name: orders、spec.endpoints[0].portはmetrics、intervalは30sです。

ServiceMonitorはServiceをラベルで選び、ポートは番号ではなくServiceのポート名で指定します。作成したあとは、そのセレクターが本当に何を選んだかを、kubectlで問い合わせて確認してください。

例外と、引き上げの影響調査

/root/cnpa-base/exception.yamlにネームスペースplatform-legacyを作成して適用してください。ラベルはpod-security.kubernetes.io/enforce: baselineとpod-security.kubernetes.io/enforce-version: v1.30、アノテーションはplatform.labhub.io/exception-expires(YYYY-MM-DD形式の期限)とplatform.labhub.io/exception-reason(理由)です。同じファイルにDeployment legacy-batch(replicas 1、イメージghcr.io/labhub/legacy-batch:0.9.0、セキュリティ設定なし)も入れてください。そのあと、このネームスペースをrestrictedに引き上げるラベル変更を、サーバーdry-runで送り、その出力を標準エラー出力も含めて/root/cnpa-base/upgrade-check.txtに保存してください。legacy-batchは修正せず、そのままにしておきます。

ラベル変更をサーバーdry-runで送ると、いま動いているPodを新しいレベルで評価した警告が返ってきます。警告は標準エラー出力に出るので、一緒に保存してください。例外ネームスペースのワークロードは、わざと修正せずそのままにしておきます。

ワークロードを合わせてレベルを引き上げる

ordersのPodテンプレートをrestrictedの基準に合わせてください。PodレベルにrunAsNonRoot: true、runAsUser: 10001、seccompProfile.type: RuntimeDefaultを、コンテナレベルにallowPrivilegeEscalation: falseとcapabilities.drop: [ALL]を入れます。再度適用してPodが新しく起動したあとで、platform-baselineのenforceラベルをrestrictedに引き上げてください。enforce-versionはv1.30のままにします。

restrictedは4つを要求します。rootで動かないこと、seccompのデフォルトプロファイル、権限昇格の禁止、capabilityをすべて捨てることです。前の2つはPodレベルに、後ろの2つはコンテナレベルに書きます。ワークロードを先に直し、レベルはあとで引き上げます。

ベースラインの現状を値として残す

/root/cnpa-base/baseline.jsonに現状を残してください。キーはnamespace、enforce、enforce_version、deployments(そのネームスペースのDeploymentの数)、servicemonitor(名前)、exception_namespace、exception_expiresです。

レポートの数字は、すべてクラスターで数え直せるものである必要があります。ネームスペースのラベル、Deploymentの数、ServiceMonitorの名前、例外の期限を、それぞれ取得して埋めてください。