implementing-pod-security-admission-controller について
Pod Security Admission(PSA)の設定やトラブルシューティングを行う Kubernetes 管理者向けのセキュリティスキルです。Namespace ポリシー、クラスタ既定値、例外、テスト、監視、PodSecurityPolicy からの移行を扱います。
主な機能
- 01Namespace の PSA ラベル設定
- 02クラスタ全体の Admission 既定値設定
- 03Namespace とアカウントの例外管理
- 04サーバー dry-run によるポリシーテスト
- 05PSA 違反の監視
- 06PodSecurityPolicy からの移行
活用シーン
- 01Kubernetes クラスタへの PSA 導入
- 02audit と warn による段階的な適用
- 03Pod の拒否や適用漏れの調査
- 04PodSecurityPolicy から PSA への移行
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill implementing-pod-security-admission-controllerインストール後、Claude Code で/implementing-pod-security-admission-controllerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py詳細
Pod Security Admission コントローラーの実装
概要
Pod Security Admission(PSA)は、Kubernetes に組み込まれたアドミッションコントローラー(v1.25 以降で安定版)で、名前空間単位で Pod Security Standards を適用します。非推奨となった PodSecurityPolicy(PSP)の代替であり、Privileged、Baseline、Restricted の 3 つのセキュリティプロファイルと、enforce、audit、warn の 3 つの適用モードを提供します。
使用するタイミング
- クラスターで PSA を初めて設定するとき
AdmissionConfigurationでクラスター全体のデフォルトの適用設定を行うとき- システム名前空間、サービスアカウント、またはランタイムクラスを適用対象から除外するとき
- Pod が拒否された理由や、適用が検出されない理由をデバッグするとき
warnとauditを先に使い、違反がゼロになってからenforceへ移行する安全な展開を行うとき- kube-apiserver の監査ログから PSA 違反を抽出するとき
このスキルの対象外: ワークロードがどのプロファイルで実行されるべきかの判断や、Restricted が要求する securityContext の変更内容。その場合は implementing-kubernetes-pod-security-standards を使用してください。
前提条件
- Kubernetes v1.25 以降(PSA は安定版/GA)
- cluster-admin 権限を持つ kubectl
- 外部ツールへの依存なし。PSA は kube-apiserver に組み込まれています
Pod Security Standards
Privileged プロファイル
- 無制限: 制限は一切適用されません
- ユースケース: システムレベルの Pod(kube-system、監視など)
Baseline プロファイル
- 最小限の制限: 既知の権限昇格を防止します
- ブロック対象: 特権コンテナ、hostPID、hostIPC、hostNetwork、hostPorts、一部のボリュームタイプ、ランタイムのデフォルトを超える capabilities の追加
Restricted プロファイル
- 厳格な制限: セキュリティのベストプラクティスに従います
- 要求事項: 非 root での実行、ALL capabilities の削除、seccomp RuntimeDefault、読み取り専用のルートファイルシステムの考慮
- ブロック対象: Baseline でブロックされるものすべてに加え、root での実行、権限昇格、承認されていないボリュームタイプ
適用モード
| モード | 動作 | ユースケース |
|---|---|---|
| enforce | ポリシーに違反する Pod を拒否 | 本番環境での適用 |
| audit | 違反を監査ログに記録 | 適用前の評価 |
| warn | ユーザーに警告を表示 | 開発者へのフィードバック |
実装
ラベルによる名前空間への適用
# Restricted enforcement with audit and warn
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.28
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: v1.28
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: v1.28
# Baseline enforcement for staging
apiVersion: v1
kind: Namespace
metadata:
name: staging
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: v1.28
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: v1.28
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: v1.28
# Privileged for system namespaces
apiVersion: v1
kind: Namespace
metadata:
name: kube-system
labels:
pod-security.kubernetes.io/enforce: privileged
kubectl でのラベル適用
# Set restricted enforcement
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=v1.28 \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
# Set baseline enforcement
kubectl label namespace staging \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
# Check current labels
kubectl get namespace production -o jsonpath='{.metadata.labels}' | jq .
ドライラン によるテスト
# Test what would happen with restricted policy on a namespace
kubectl label --dry-run=server --overwrite namespace staging \
pod-security.kubernetes.io/enforce=restricted
# Output shows existing pods that would violate the policy
# Warning: existing pods in namespace "staging" violate the new PodSecurity enforce level "restricted:latest"
クラスター全体のデフォルト設定(AdmissionConfiguration)
# /etc/kubernetes/psa-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1
kind: PodSecurityConfiguration
defaults:
enforce: baseline
enforce-version: latest
audit: restricted
audit-version: latest
warn: restricted
warn-version: latest
exemptions:
usernames: []
runtimeClasses: []
namespaces:
- kube-system
- kube-public
- kube-node-lease
- calico-system
- gatekeeper-system
- monitoring
- falco
API サーバーへの適用
# Add to kube-apiserver manifests
# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --admission-control-config-file=/etc/kubernetes/psa-config.yaml
volumeMounts:
- name: psa-config
mountPath: /etc/kubernetes/psa-config.yaml
readOnly: true
volumes:
- name: psa-config
hostPath:
path: /etc/kubernetes/psa-config.yaml
type: File
準拠した Pod の例
Restricted に準拠した Pod
apiVersion: v1
kind: Pod
metadata:
name: restricted-pod
namespace: production
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
automountServiceAccountToken: false
containers:
- name: app
image: myregistry/myapp:v1.0.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
Baseline に準拠した Pod
apiVersion: v1
kind: Pod
metadata:
name: baseline-pod
namespace: staging
spec:
containers:
- name: app
image: myregistry/myapp:v1.0.0
securityContext:
allowPrivilegeEscalation: false
resources:
limits:
cpu: 500m
memory: 256Mi
PodSecurityPolicy からの移行
ステップ 1: 現在の状態の監査
# Check existing PSPs
kubectl get psp
# Check which service accounts use which PSP
kubectl get clusterrolebinding -o json | \
jq '.items[] | select(.roleRef.name | startswith("psp-")) | {name: .metadata.name, subjects: .subjects}'
ステップ 2: PSP を PSA プロファイルにマッピング
# For each namespace, determine required PSA level
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
echo "Namespace: $ns"
kubectl label --dry-run=server namespace $ns \
pod-security.kubernetes.io/enforce=restricted 2>&1 | head -5
done
ステップ 3: PSA ラベルの適用(まず監査)
# Start with audit mode
kubectl label namespace production \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
ステップ 4: 違反の確認と修正
# Check audit logs for violations
kubectl get events --field-selector reason=FailedCreate -A
ステップ 5: 適用(enforce)の有効化
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted
監視
# Check PSA violations in events
kubectl get events --all-namespaces --field-selector reason=FailedCreate
# Check audit logs
kubectl logs -n kube-system kube-apiserver-* | grep "pod-security.kubernetes.io"
# List namespace PSA labels
kubectl get namespaces -L pod-security.kubernetes.io/enforce
ベストプラクティス
- enforce の前に audit+warn から開始し、影響を評価する
- ドライラン を使用して、適用前に enforce の動作をテストする
- クラスターのデフォルト設定でシステム名前空間(kube-system、monitoring)を除外する
- 予測可能な動作をアップグレード後も保つため、バージョンを固定(enforce-version)する
- クラスター全体のベースラインをデフォルトとして設定し、特定の名前空間をさらに制限する
- PSA の範囲を超える追加のカスタムポリシーには Gatekeeper を組み合わせる
- 本番環境のすべてのワークロードで restricted プロファイルを使用する
- 除外設定には、明確な理由を添えてドキュメント化する
コメント
Markdown 対応