昇格の手順と、ポリシーなしで済むこと
目標
ポリシーを観察から強制へ引き上げる手順をマニフェストとスクリプトで実装し、同じ種類の統制をポリシーエンジンなしでPSAラベルだけで立てて、2つのアプローチの境界を確認します。
なぜ重要なのか
ポリシーツールを使いこなすことと、ポリシーをうまく運用することは、別の技術です。運用で重要なのは、ルールの精巧さではなく、「今このルールを強制に上げてよいか」を判断する手順です。その判断はレポートから出てきますし、手順はスクリプトとして固めておけば、人が変わっても維持されます。同時に、反対側の問いも必要です。Podのセキュリティレベルのように標準化された検査は、ネームスペースのラベル2行で終わるので、そうしたものまでポリシーエンジンに入れると、運用するコンポーネントが増えるだけです。このラボで2つの方式を並べて立ててみると、その境界がはっきりします。
ステップ
/root/kca-ops/ディレクトリを作成し、policy-baseline.yamlにkindとしてClusterPolicy、metadata.nameとしてkca-baselineを書いてください。spec.validationFailureActionはAuditにし、spec.validationFailureActionOverridesに、Enforceでkca-prod、Auditでkca-devを指定する2つの項目を入れてください。ルールも少なくとも1つ以上必要です。- 同じファイルで
spec.webhookConfiguration.timeoutSecondsを20、spec.webhookConfiguration.failurePolicyをIgnoreにしてください。非推奨(deprecated)のspec.webhookTimeoutSecondsとspec.failurePolicyは使わないでください。 - 同じファイルで
spec.backgroundをtrue、spec.admissionをtrue、spec.applyRulesをAllにし、ルールを2つ以上にしてください。 /root/kca-ops/policyexception.yamlにapiVersionとしてkyverno.io/v2beta1、kindとしてPolicyException、metadata.nameとしてkca-allow-monitoringを書いてください。spec.exceptions[0].policyNameはkca-baseline、ruleNamesにはステップ1で作ったルール名を入れ、spec.match.any[0].resources.namespacesにkca-monitoring、namesにprometheus-*を入れてください。/root/kca-ops/promote.shを、実行権限のあるシェルスクリプトとして作成してください。中には、kyverno applyと--resourceを使うローカル検証、PolicyReportの確認、Webhook登録またはUpdateRequestの確認、Enforceに上げるステップ、そして失敗時に0以外のコードで終了する処理が、すべて入っていなければなりません。- クラスターにネームスペース
kca-prodを作成し、ラベルpod-security.kubernetes.io/enforce=restrictedとpod-security.kubernetes.io/enforce-versionを付けてください。ネームスペースkca-devにはpod-security.kubernetes.io/warn=baselineだけを付け、enforceラベルは付けないでください。 - ネームスペース
kca-prodにDeploymentkca-helloを実際に作成してください。PodレベルのsecurityContext.runAsNonRootはtrue、securityContext.seccompProfile.typeはRuntimeDefault、コンテナレベルのsecurityContext.allowPrivilegeEscalationはfalseで、capabilities.dropにはALLが入っている必要があります。そして、ネームスペースkca-monitoringを、ラベルpod-security.kubernetes.io/enforce=privilegedを付けて作成してください。
参考
kubectl label ns kca-prod pod-security.kubernetes.io/enforce=restricted pod-security.kubernetes.io/enforce-version=latestで、2つのラベルを一度に付けられます。- スクリプトの検査は、
bash -n /root/kca-ops/promote.shで事前に行ってみてください。 - よくある間違い1: PolicyExceptionをネームスペース全体に広く開けること。名前のパターンまで絞ってはじめて、例外が例外のままになります。
- よくある間違い2: PSAラベルでバージョンを固定しないこと。クラスターのアップグレードがポリシーの内容を変えてしまいます。
ネームスペースごとに差をつけた適用
/root/kca-ops/ディレクトリを作成し、policy-baseline.yamlにkindとしてClusterPolicy、metadata.nameとしてkca-baselineを書いてください。spec.validationFailureActionはAuditにし、spec.validationFailureActionOverridesに、Enforceでkca-prod、Auditでkca-devを指定する2つの項目を入れてください。ルールも少なくとも1つ以上必要です。
ポリシー全体のデフォルトは観察モードにしておき、オーバーライドの配列で、ネームスペースごとに違う動作を指定します。actionとnamespacesの2つのフィールドが1つの項目になります。
webhookConfigurationへの移行
同じファイルでspec.webhookConfiguration.timeoutSecondsを20、spec.webhookConfiguration.failurePolicyをIgnoreにしてください。非推奨(deprecated)のspec.webhookTimeoutSecondsとspec.failurePolicyは使わないでください。
タイムアウトと失敗ポリシーは、1.13から1段下のブロックに移りました。以前の場所のフィールドは残しておいてはいけません。観察段階のポリシーがクラスターを止めないようにするには、失敗ポリシーをどちらにするかを考えてみてください。
background・admission・applyRules
同じファイルでspec.backgroundをtrue、spec.admissionをtrue、spec.applyRulesをAllにし、ルールを2つ以上にしてください。
3つのフラグは、それぞれ既存リソースのスキャン、アドミッションでの適用、ルールを適用する数を決めます。ルールを複数並べたのに後ろのものが動かないという問題を作るのが、最後のフィールドです。
PolicyExceptionによる正当な例外
/root/kca-ops/policyexception.yamlにapiVersionとしてkyverno.io/v2beta1、kindとしてPolicyException、metadata.nameとしてkca-allow-monitoringを書いてください。spec.exceptions[0].policyNameはkca-baseline、ruleNamesにはステップ1で作ったルール名を入れ、spec.match.any[0].resources.namespacesにkca-monitoring、namesにprometheus-*を入れてください。
例外は、ポリシー名とルール名を一緒に指定します。ネームスペースだけを書いて丸ごと除外する代わりに、名前のパターンまで絞ってください。
プロモーションのチェックリストスクリプト
/root/kca-ops/promote.shを、実行権限のあるシェルスクリプトとして作成してください。中には、kyverno applyと--resourceを使うローカル検証、PolicyReportの確認、Webhook登録またはUpdateRequestの確認、Enforceに上げるステップ、そして失敗時に0以外のコードで終了する処理が、すべて入っていなければなりません。
ローカル検証、レポートの確認、診断、そして失敗時の0以外の終了がすべて入ってはじめて、CIゲートとして使えます。実行権限も忘れないでください。
PSAラベルで2つの等級を作る
クラスターにネームスペースkca-prodを作成し、ラベルpod-security.kubernetes.io/enforce=restrictedとpod-security.kubernetes.io/enforce-versionを付けてください。ネームスペースkca-devにはpod-security.kubernetes.io/warn=baselineだけを付け、enforceラベルは付けないでください。
ここからは実際のクラスターです。Pod Security Admissionはネームスペースのラベルで動作し、モードはenforce・audit・warnの3つです。バージョンラベルも一緒に固定する理由も考えてみてください。
restrictedを通過するワークロード
ネームスペースkca-prodにDeployment kca-helloを実際に作成してください。PodレベルのsecurityContext.runAsNonRootはtrue、securityContext.seccompProfile.typeはRuntimeDefault、コンテナレベルのsecurityContext.allowPrivilegeEscalationはfalseで、capabilities.dropにはALLが入っている必要があります。そして、ネームスペースkca-monitoringを、ラベルpod-security.kubernetes.io/enforce=privilegedを付けて作成してください。
restrictedの等級は、4つを要求します。root以外での実行、権限昇格の禁止、すべてのケーパビリティの削除、そしてseccompプロファイルです。例外の対象になるネームスペースも一緒に作成してください。