kuberntes には権限が与えられていないアカウントによる Pod のデプロイを防ぐためのセキュリティ機能である Pod Security Policy(通称:PSP)が存在しており、PSP が動作している環境では初期状態でまともに Pod がデプロイできない場合がある。
※PSP 自体は 1.21 から deprecated 扱いになっていて、1.25 では抹消されている。このあたりは以下の記事が参考になります。
具体的には
- Namespace を作成後、
kubectl run
などで pod を起動してもRunning
にならない-
Deployment
やStatefulSet
がいつまでたってもスケールしてくれない - 以下のようなエラーが出ている
# kubectl -n test-ns describe statefulset hoge Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedCreate 8m45s (x18 over 19m) statefulset-controller create Pod xxxxxxxxxxxxx in StatefulSet xxxxxxxxxxxxxx failed error: pods "xxxxxxxxxxxx" is forbidden: PodSecurityPolicy: unable to admit pod: []
-
原因
クラスタに PSP リソースが存在し、spec.privileged
が false
状態の PSP がデフォルト適用されている。
以下は vSphere with Tanzu の TKC 環境のもの:
# kubectl get psp
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
tanzu-system-kapp-ctrl-restricted false RunAsAny MustRunAsNonRoot MustRunAs MustRunAs false configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim
vmware-system-privileged true * RunAsAny RunAsAny RunAsAny RunAsAny false *
vmware-system-restricted false RunAsAny MustRunAsNonRoot MustRunAs MustRunAs false configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim
対処法
spec.privileged
が true
となっている PSP を作成するか、すでに存在すればその PSP を使用して当該 Namespace で使用している ServiceAccount
に割り当てる。
上記の場合は vmware-system-privileged
が privileged コンテナデプロイを許可する内容になっているため、こちらを使用する。
# kubectl get psp vmware-system-privileged -ojsonpath='{.spec.privileged}'
true
ClusterRoleBinding
で一括設定する方法もあると思うが、Namespace に対して RoleBinding
を割り当てるのがミニマム。
# kubectl create rolebinding <任意の RoleBinding 名> --namespace <対象 Namespace> --clusterrole=psp:<privileged 件がある PSP> --group=system:serviceaccounts