はじめに
Kubernetes 1.25 での PodSecurityPolicy (PSP) の廃止に伴って、
PSP は PodSecurity Admission (PSA) および Pod Security Standards (PSS) に置き換えられます。
本記事では、Amazon EKS における次の2点について記載しています。
- PSPの削除手順
- PSA / PSS の移行手順
EKS クラスタ自体のアップグレードに関する手順、マネコン操作の解説は省略させていただきます。
PodSecurityPolicy (PSP) とは
Kubernetes アドミッション コントローラであり、Pod レベルでのセキュリティ制御を行い、
デプロイされたワークロードのセキュリティ構成を細かく制御することができました。
PSP は Kubernetes 1.21 から非推奨となり、1.25 で廃止となります。
EKS クラスタを 1.25 にアップグレードする際には
後述の PodSecurity Admission (PSA) に置き換える必要があります。
PodSecurity Admission (PSA) とは
PSA は Kubernetes 1.21 から使用できるようになり、1.25 から必須となる Pod レベルの制御方法です。
Pod Security Standards (PSS) に基づいて Pod の Security Context 設定をチェックし、
必要に応じて Warning メッセージや Audit ログを出力させたり、PSS に違反した Pod の作成を停止することも可能です。
MODE と LEVEL を組み合わせ、Namespace もしくは Pod ごとにラベルを設定します。
PSA の MODE
Pod Security Admission labels for namespaces
MODE | 説明 |
enforce | ポリシーに違反した場合、Podの起動は拒否されます。 |
audit | ポリシーに違反した場合、監査ログに記録されるイベントに監査アノテーションを追加するトリガーとなりますが、それ以外は許可されます。 |
warn | ポリシーに違反した場合、ユーザーへの警告がトリガーされますが、それ以外は許可されます。 |
PSA の LEVEL
Profile | 説明 |
privileged | 無制限のポリシー。可能な限り幅広いレベルの権限を提供します。 このポリシーでは、既知の権限昇格が許可されます。 |
baseline | 既知の権限昇格を防ぐ最小限の制限ポリシー。 デフォルトの (最小限に指定された) Pod 構成を許可します。 |
restricted | 現在のPod 強化のベストプラクティスに従って、厳しく制限されたポリシー。 |
PSP の利用状況確認
現在稼働中の EKS クラスタバージョンと、Worker Node の稼働状況を確認します。
EKS Server (クラスタ)バージョンは 1.24 で稼働しており、1台の Worker Node が起動しています。
$ kubectl version --short Flag --short has been deprecated, and will be removed in the future. The --short output will become the default. Client Version: v1.25.4 Kustomize Version: v4.5.7 Server Version: v1.24.17-eks-f8587cb
$ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME ip-192-168-24-79.ap-northeast-1.compute.internal Ready <none> 4d21h v1.24.13-eks-0a21954 192.168.24.79 13.231.201.233 Amazon Linux 2 5.10.179-168.710.amzn2.x86_64 containerd://1.6.19
検証のための環境では以下の Pod が稼働しています。
$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE cert-manager cert-manager-795d7f859d-bjqkw 1/1 Running 0 129d cert-manager cert-manager-cainjector-5fcddc948c-7t8rx 1/1 Running 0 15h cert-manager cert-manager-webhook-5b64f87794-8bzq9 1/1 Running 0 129d default common-squid-6ff4d9b67f-crmx5 1/1 Running 0 129d default common-squid-6ff4d9b67f-cxdlk 1/1 Running 0 129d default external-dns-f7dcdf675-7tdsc 1/1 Running 0 129d kube-system aws-load-balancer-controller-7897cc48d7-sfl6s 1/1 Running 0 129d kube-system aws-node-m9c9t 1/1 Running 0 4d21h kube-system common-fluentd-cvb44 1/1 Running 0 4d21h kube-system coredns-69769bcfc6-4gvcn 1/1 Running 0 129d kube-system coredns-69769bcfc6-t5gsf 1/1 Running 0 129d kube-system ebs-csi-controller-84f59985bb-pq9t6 6/6 Running 0 129d kube-system ebs-csi-controller-84f59985bb-tqx57 6/6 Running 0 129d kube-system ebs-csi-node-g2pdd 3/3 Running 0 4d21h kube-system kube-proxy-snxh7 1/1 Running 0 4d21h kube-system kube2iam-9vx5c 1/1 Running 0 4d21h kube-system metrics-server-6fc695f67c-l889k 1/1 Running 1 (4d21h ago) 129d
続いて、現在 PSP でセキュリティ制御している namespace を確認します。
ポッドセキュリティポリシー (PSP) の削除に関するよくある質問
クラスター内の PSPs が影響を与えている Pods を確認するには、次のコマンドを実行します。このコマンドは Pod 名、名前空間、PSPs を出力します。
kubectl get pod -A -o jsonpath='{range.items[?(@.metadata.annotations.kubernetes\.io/psp)]}{.metadata.name}{“\t”}{.metadata.namespace}{“\t”}{.metadata.annotations.kubernetes\.io/psp}{“\n”}’
以下の結果から3つの namespace で PSP を使用していることがわかります。
- default
- cert-manager
- kube-system
$ kubectl get pod -A -o jsonpath='{range.items[?(@.metadata.annotations.kubernetes\.io/psp)]}{.metadata.name}{"\t"}{.metadata.namespace}{"\t"}{.metadata.annotations.kubernetes\.io/psp}{"\n"}' cert-manager-795d7f859d-bjqkw cert-manager eks.privileged cert-manager-cainjector-5fcddc948c-7t8rx cert-manager eks.privileged cert-manager-webhook-5b64f87794-8bzq9 cert-manager eks.privileged common-squid-6ff4d9b67f-crmx5 default eks.privileged common-squid-6ff4d9b67f-cxdlk default eks.privileged external-dns-f7dcdf675-7tdsc default eks.privileged aws-load-balancer-controller-7897cc48d7-sfl6s kube-system eks.privileged aws-node-m9c9t kube-system eks.privileged common-fluentd-cvb44 kube-system eks.privileged coredns-69769bcfc6-4gvcn kube-system eks.privileged coredns-69769bcfc6-t5gsf kube-system eks.privileged ebs-csi-controller-84f59985bb-pq9t6 kube-system eks.privileged ebs-csi-controller-84f59985bb-tqx57 kube-system eks.privileged ebs-csi-node-g2pdd kube-system eks.privileged kube-proxy-snxh7 kube-system eks.privileged kube2iam-9vx5c kube-system eks.privileged metrics-server-6fc695f67c-l889k kube-system eks.privileged
namespace default について詳細情報を取得すると、Allow Privileged が true であり、
namespace ごとに PSP が設定されていることがわかります。
同様に -n オプションで cert-manager と kube-system を指定し、それぞれ確認することが可能です。
$ kubectl describe -n default psp eks.privileged Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ Name: eks.privileged Settings: Allow Privileged: true Allow Privilege Escalation: true Default Add Capabilities: <none> Required Drop Capabilities: <none> Allowed Capabilities: * Allowed Volume Types: * Allow Host Network: true Allow Host Ports: 0-65535 Allow Host PID: true Allow Host IPC: true Read Only Root Filesystem: false SELinux Context Strategy: RunAsAny User: <none> Role: <none> Type: <none> Level: <none> Run As User Strategy: RunAsAny Ranges: <none> FSGroup Strategy: RunAsAny Ranges: <none> Supplemental Groups Strategy: RunAsAny Ranges: <none>
PSP の削除
デフォルトの Amazon EKS Pod セキュリティポリシーを削除する
AWS 公式のドキュメントを参考に、privileged-podsecuritypolicy.yaml というファイル名で
マニフェストを作成し、作業ディレクトリに配置します。
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: eks.privileged annotations: kubernetes.io/description: 'privileged allows full unrestricted access to Pod features, as if the PodSecurityPolicy controller was not enabled.' seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' labels: kubernetes.io/cluster-service: "true" eks.amazonaws.com/component: pod-security-policy spec: privileged: true allowPrivilegeEscalation: true allowedCapabilities: - '*' volumes: - '*' hostNetwork: true hostPorts: - min: 0 max: 65535 hostIPC: true hostPID: true runAsUser: rule: 'RunAsAny' seLinux: rule: 'RunAsAny' supplementalGroups: rule: 'RunAsAny' fsGroup: rule: 'RunAsAny' readOnlyRootFilesystem: false --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: eks:podsecuritypolicy:privileged labels: kubernetes.io/cluster-service: "true" eks.amazonaws.com/component: pod-security-policy rules: - apiGroups: - policy resourceNames: - eks.privileged resources: - podsecuritypolicies verbs: - use --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: eks:podsecuritypolicy:authenticated annotations: kubernetes.io/description: 'Allow all authenticated users to create privileged Pods.' labels: kubernetes.io/cluster-service: "true" eks.amazonaws.com/component: pod-security-policy roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: eks:podsecuritypolicy:privileged subjects: - kind: Group apiGroup: rbac.authorization.k8s.io name: system:authenticated</blockquote>
namespace default を指定し、以下コマンドにて PSP 削除します。
$ kubectl delete -n default -f privileged-podsecuritypolicy.yaml warning: deleting cluster-scoped resources, not scoped to the provided namespace Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy "eks.privileged" deleted clusterrole.rbac.authorization.k8s.io "eks:podsecuritypolicy:privileged" deleted clusterrolebinding.rbac.authorization.k8s.io "eks:podsecuritypolicy:authenticated" deleted
再度、default について詳細情報を取得すると、PSP の利用が無いことを確認できます。
コマンド記載は省略しますが、同様に namespace cert-manager と kube-system でも PSP を削除します。
$ kubectl describe -n default psp eks.privileged Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ Error from server (NotFound): podsecuritypolicies.policy "eks.privileged" not found
PSP を削除したことで EKS クラスタのバージョンを 1.25 にアップグレードする準備が整いました。
PSA / PSS の動作確認
EKS クラスタバージョンを 1.25 にアップグレードし、バージョン情報と Pod の稼働状態を確認します。
$ kubectl version --short Flag --short has been deprecated, and will be removed in the future. The --short output will become the default. Client Version: v1.24.17-eks-43840fb Kustomize Version: v4.5.4 Server Version: v1.25.15-eks-4f4795d
PSA / PSS は何もせずとも標準的に動作し、すべての Pod が正常に起動しています。
pod-security のラベル未設定状態では PSS Level privileged、つまり権限昇格が許可されています。
$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE cert-manager cert-manager-795d7f859d-zlshs 1/1 Running 0 11m cert-manager cert-manager-cainjector-5fcddc948c-97vcb 1/1 Running 0 11m cert-manager cert-manager-webhook-5b64f87794-7jfnc 1/1 Running 0 11m default common-squid-6ff4d9b67f-crjdh 1/1 Running 0 11m default common-squid-6ff4d9b67f-l7n8t 1/1 Running 0 11m default external-dns-f7dcdf675-dw9bs 1/1 Running 0 11m kube-system aws-load-balancer-controller-7897cc48d7-4lwtf 1/1 Running 0 11m kube-system aws-node-2jckq 1/1 Running 0 13m kube-system aws-node-l5hrp 1/1 Running 0 12m kube-system common-fluentd-6k9gn 1/1 Running 0 12m kube-system common-fluentd-p2hf5 1/1 Running 0 13m kube-system coredns-5857dd7484-n6kqd 1/1 Running 0 11m kube-system coredns-5857dd7484-p65jf 1/1 Running 0 11m kube-system ebs-csi-controller-84f59985bb-dlj98 6/6 Running 0 11m kube-system ebs-csi-controller-84f59985bb-wts49 6/6 Running 0 10m kube-system ebs-csi-node-bkqv7 3/3 Running 0 12m kube-system ebs-csi-node-htt85 3/3 Running 0 13m kube-system kube-proxy-bbzjr 1/1 Running 0 13m kube-system kube-proxy-hrrpx 1/1 Running 0 12m kube-system kube2iam-5xglw 1/1 Running 0 12m kube-system kube2iam-r6f65 1/1 Running 0 13m kube-system metrics-server-6fc695f67c-gkrg7 1/1 Running 1 (11m ago) 11m
namespace ごとのラベルを確認すると、デフォルトでは pod-security のラベルがついていません。
$ kubectl get ns --show-labels NAME STATUS AGE LABELS cert-manager Active 139d kubernetes.io/metadata.name=cert-manager default Active 139d kubernetes.io/metadata.name=default kube-node-lease Active 139d kubernetes.io/metadata.name=kube-node-lease kube-public Active 139d kubernetes.io/metadata.name=kube-public kube-system Active 139d kubernetes.io/metadata.name=kube-system
前述の通り、pod-security のラベルはつけなくとも暗黙的に PSS Level privileged で動作しますが、
個人的には運用中の混乱を避けるため、明示的につけた方が良いと考えます。
namespace kube-system に PSS Level privileged を設定します。
$ kubectl label --overwrite ns kube-system pod-security.kubernetes.io/enforce=privileged namespace/kube-system labeled
カンマ区切りで kube-system にラベルが付与されたことが確認できます。
$ kubectl get ns --show-labels NAME STATUS AGE LABELS cert-manager Active 139d kubernetes.io/metadata.name=cert-manager default Active 139d kubernetes.io/metadata.name=default kube-node-lease Active 139d kubernetes.io/metadata.name=kube-node-lease kube-public Active 139d kubernetes.io/metadata.name=kube-public kube-system Active 139d kubernetes.io/metadata.name=kube-system,pod-security.kubernetes.io/enforce=privileged
pod-security の削除について
PSS MODE や Level を変えて、Pod が起動拒否される、されない、
audit ログを見たい、いや warnだけでいい等、検証したいこともあるかと思います。
検証していたところ、ラベルは PSS MODE 違いで複数付与できたので
MODE enforce と MODE warn のラベルを同時付与することもできてしまいます。
その場合どちらの MODE で動作しているかよくわからなくなってしまうので、
一度付与したラベルは次のコマンドで削除します。
$ kubectl label ns kube-system pod-security.kubernetes.io/enforce- $ kubectl label ns kube-system pod-security.kubernetes.io/audit- $ kubectl label ns kube-system pod-security.kubernetes.io/warn-