Pod Securityは、新しいPodが作成されたときにKubernetes Pod Security Standardsに対するチェックを実行するアドミッションコントローラーです。 端的にいうと、Podを作成するときのセキュリティ上のルールを定義して、それに従わせるためのものです。Pod Securityを適切に使うことで、Kubernetesクラスターの安全性がより高まります。
前回は特定の名前空間でのみ適用されるPod Security Standardsを試しましたが、今回はチュートリアル「Apply Pod Security Standards at Cluster level」をもとに、クラスター内のすべての名前空間に標準構成を適用するクラスターレベルでPod Security Standardsを適用するのを試してみます。
ポリシーについておさらい
Pod Security Standardsで設定できるポリシーについては、次にまとめられています。
特権(Privileged)、ベースライン、制限(Restricted)と言うポリシーがあり、特権(Privileged)は何も制限がかけられていないポリシー、ベースラインは容易に適用しやすく、かつ既知の特権昇格を防ぐことを意図するようなポリシーが定義されています。制限(Restricted)は柔軟性を犠牲にして、できるかぎりセキュリティを担保するためのポリシーのようです。
ちなみにベースラインのSELinuxやAppArmorについては、それぞれがホストで実行されるOSで一般的に使える状態でないと利用できないと思われます。例えばDebianやUbuntuなどではAppArmor、RHELやRHELクローンではSELinuxが設定できます。
ポリシーを定義する
今回はベースラインは強制し、制限(Restricted)は警告とAuditログを出力する設定をクラスターに行ってみます。 これらの仕様でPod Security Standardsを実装するために、Podセキュリティアドミッションコントローラの設定ファイルを作成します。
$ mkdir -p /tmp/pss $ cat <<EOF > /tmp/pss/cluster-level-pss.yaml apiVersion: apiserver.config.k8s.io/v1 kind: AdmissionConfiguration plugins: - name: PodSecurity configuration: apiVersion: pod-security.admission.config.k8s.io/v1beta1 kind: PodSecurityConfiguration defaults: enforce: "baseline" enforce-version: "latest" audit: "restricted" audit-version: "latest" warn: "restricted" warn-version: "latest" exemptions: usernames: [] runtimeClasses: [] namespaces: [kube-system] EOF
公式チュートリアルに説明が特にありませんが、exemptionsで例外を設定できます。クラスタレベルでPod Security Standardsを設定するのにあたり、Kubernetesシステムにこの影響が出ないようにするため、Kubernetesシステムが主に動く名前空間kube-system
を除外しています。
Kindクラスター作成マニフェストの作成
Kindでクラスターを作成するため、次のようなマニフェストファイルを作成します。前回とは異なり、色々な設定を仕込んでいます。
cat <<EOF > /tmp/pss/cluster-config.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane image: kindest/node:v1.23.6@sha256:b1fa224cc6c7ff32455e0b1fd9cbfd3d3bc87ecaa8fcb06961ed1afb3db0f9ae #バージョンを指定 kubeadmConfigPatches: #以下APIの設定変更 - | kind: ClusterConfiguration apiServer: extraArgs: admission-control-config-file: /etc/config/cluster-level-pss.yaml extraVolumes: - name: accf hostPath: /etc/config mountPath: /etc/config readOnly: false pathType: "DirectoryOrCreate" extraMounts: - hostPath: /tmp/pss containerPath: /etc/config # optional: if set, the mount is read-only. # default false readOnly: false # optional: if set, the mount needs SELinux relabeling. # default false selinuxRelabel: false # optional: set propagation mode (None, HostToContainer or Bidirectional) # see https://kubernetes.io/docs/concepts/storage/volumes/#mount-propagation # default None propagation: None EOF
KindでKubernrtesクラスターの作成
まずはクラスターを作成します。
$ kind create cluster --name psa-with-cluster-pss --config /tmp/pss/cluster-config.yaml Creating cluster "psa-with-cluster-pss" ... ✓ Ensuring node image (kindest/node:v1.23.6) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-psa-with-cluster-pss" You can now use your cluster with: kubectl cluster-info --context kind-psa-with-cluster-pss Have a nice day! 👋
Podの作成
前の記事でも使ったマニフェストを使ってPodを作成します。
$ cat <<EOF > /tmp/pss/nginx-pod.yaml apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - image: nginx name: nginx ports: - containerPort: 80 EOF
Podを作ると警告が表示されるがPodは作成されます。
$ kubectl apply -n default -f /tmp/pss/nginx-pod.yaml Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") pod/nginx created $ kubectl get po -n default NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 131m
名前空間test
でPodを作っても同様になります。これにより、クラスタレベルのPod Security Standardsが設定されていることが確認できました。
$ kubectl create ns test namespace/test created $ kubectl apply -n test -f /tmp/pss/nginx-pod.yaml Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") pod/nginx created $ kubectl get po -n test NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 131m
本番環境ではPod Security Standardsは設定したほうが良いと感じました。Pod Security Policiesを現在導入しているクラスターについてはKubernetes 1.25で機能が削除されるので、現在のKubernetesクラスターのバージョンがサポートされている間にPod Security Standardsへの移行を早めに行っておくべきでしょう。