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への移行を早めに行っておくべきでしょう。