💨
PodSecurityPolicy から組み込み PodSecurity Admission Controller への移行
これはなに?
PodSecurityPolicy (PSP) は Kubernetes バージョン 1.21 で非推奨となり、Kubernetes 1.25 で削除されるため代替手段となる PodSecurity Admission Controller (PSA) への移行方法をまとめたものである。
手順
ネームスペースに対して以下のラベルを設定していく。
- pod-security.kubernetes.io/audit
- pod-security.kubernetes.io/enforce
- pod-security.kubernetes.io/warn
PSA は、privileged
、baseline
、およびrestricted
の3つのポリシーレベルを提供するため、ドライランを利用しながらポリシーレベルを調整していくと良い。
ここでは、kube-system ネームスペースに対してドライラン後に更新を実施してみる。
ドライラン
ポリシーレベルは restricted -> baseline -> privileged の順に検証する。
# restricted or baseline or privileged
$ LEVEL="privileged"
$ NAMESPACE="kube-system"
$ kubectl label --dry-run=server --overwrite ns $NAMESPACE pod-security.kubernetes.io/enforce=$LEVEL
namespace/kube-system labeled
上記の様にワーニングが出力されなければ問題ない。
更新
ドライランが問題なければ以下のコマンドで更新をかけていく。
$ kubectl label --overwrite ns $NAMESPACE pod-security.kubernetes.io/audit=$LEVEL
namespace/kube-system labeled
$ kubectl label --overwrite ns $NAMESPACE pod-security.kubernetes.io/enforce=$LEVEL
namespace/kube-system labeled
$ kubectl label --overwrite ns $NAMESPACE pod-security.kubernetes.io/warn=$LEVEL
namespace/kube-system labeled
確認
ネームスペースのラベルが正しく設定されているか確認する。
以下のラベルが設定されていること。
- pod-security.kubernetes.io/audit
- pod-security.kubernetes.io/enforce
- pod-security.kubernetes.io/warn
$ kubectl get ns --show-labels
NAME STATUS AGE LABELS
...
kube-system Active 2y240d kubernetes.io/metadata.name=kube-system,pod-security.kubernetes.io/audit=privileged,pod-security.kubernetes.io/enforce=privileged,pod-security.kubernetes.io/warn=privileged
...
さらに、ログ等でエラーが出力されていないか確認しておくとよい。
動作確認
テスト用のネームスペースを作成後、そのネームスペース内で Pod を作成し、PodSecurityAdmission ポリシーが適用されていることを検証する。
$ echo 'apiVersion: v1
kind: Namespace
metadata:
name: test-psa
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: baseline
pod-security.kubernetes.io/warn: baseline
' > test-psa.yaml
$ kubectl apply -f test-psa.yaml
namespace/test-psa created
$ kubectl get ns test-psa --show-labels
NAME STATUS AGE LABELS
test-psa Active 28s kubernetes.io/metadata.name=test-psa,pod-security.kubernetes.io/audit=baseline,pod-security.kubernetes.io/enforce=baseline,pod-security.kubernetes.io/warn=baseline
$ echo 'apiVersion: v1
kind: Pod
metadata:
labels:
app: test-pod
name: test-pod
namespace: test-psa
spec:
containers:
- name: test-container
image: nginx
' > test-pod.yaml
$ kubectl apply -f test-pod.yaml
pod/test-pod created
$ kubectl get pod -n test-psa -l app=test-pod
NAME READY STATUS RESTARTS AGE
test-pod 1/1 Running 0 12s
$ echo 'apiVersion: v1
kind: Pod
metadata:
labels:
app: test-pod2
name: test-pod2
namespace: test-psa
spec:
containers:
- name: test-container2
image: nginx
securityContext:
privileged: true
' > test-pod2.yaml
$ kubectl apply -f test-pod2.yaml
Error from server (Forbidden): error when creating "test-pod2.yaml": pods "test-pod2" is forbidden: violates PodSecurity "baseline:latest": privileged (container "test-container2" must not set securityContext.privileged=true)
-> baseline に違反するのでPodは作成されないはず
$ kubectl delete -f test-pod.yaml
pod "test-pod" deleted
$ kubectl delete -f test-psa.yaml
namespace "test-psa" deleted
$ rm test-psa.yaml
$ rm test-pod*.yaml
Discussion