1 - クラスターレベルでのPodセキュリティの標準の適用
Note
このチュートリアルは、新しいクラスターにのみ適用されます。Podセキュリティアドミッション(PSA)は、ベータへ進み、v1.23以降でデフォルトで有効になっています。
Podセキュリティアドミッションは、Podが作成される際に、Podセキュリティの標準の適用の認可を制御するものです。
このチュートリアルでは、クラスター内の全ての名前空間に標準設定を適用することで、クラスターレベルでbaseline
Podセキュリティの標準を強制する方法を示します。
Podセキュリティの標準を特定の名前空間に適用するには、名前空間レベルでのPodセキュリティの標準の適用を参照してください。
v1.30以外のKubernetesバージョンを実行している場合は、そのバージョンのドキュメントを確認してください。
始める前に
ワークステーションに以下をインストールしてください:
このチュートリアルでは、完全な制御下にあるKubernetesクラスターの何を設定できるかをデモンストレーションします。 コントロールプレーンを設定できない管理されたクラスターのPodセキュリティアドミッションに対しての設定方法を知りたいのであれば、名前空間レベルでのPodセキュリティの標準の適用を参照してください。
適用する正しいPodセキュリティの標準の選択
Podのセキュリティアドミッションは、以下のモードでビルトインのPodセキュリティの標準の適用を促します: enforce
、audit
、warn
。
設定に最適なPodセキュリティの標準を選択するにあたって助けになる情報を収集するために、以下を行ってください:
-
Podセキュリティの標準を適用していないクラスターを作成します:
kind create cluster --name psa-wo-cluster-pss
出力は次のようになります:
Creating cluster "psa-wo-cluster-pss" ... ✓ Ensuring node image (kindest/node:v1.30.0) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-psa-wo-cluster-pss" You can now use your cluster with: kubectl cluster-info --context kind-psa-wo-cluster-pss Thanks for using kind! 😊
-
kubectl contextを新しいクラスターにセットします:
kubectl cluster-info --context kind-psa-wo-cluster-pss
出力は次のようになります:
Kubernetes control plane is running at https://127.0.0.1:61350 CoreDNS is running at https://127.0.0.1:61350/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
-
クラスター内の名前空間の一覧を取得します:
kubectl get ns
出力は次のようになります:
NAME STATUS AGE default Active 9m30s kube-node-lease Active 9m32s kube-public Active 9m32s kube-system Active 9m32s local-path-storage Active 9m26s
-
異なるPodセキュリティの標準が適用されたときに何が起きるかを理解するために、
-dry-run=server
を使います:-
privileged
kubectl label --dry-run=server --overwrite ns --all \ pod-security.kubernetes.io/enforce=privileged
出力は次のようになります:
namespace/default labeled namespace/kube-node-lease labeled namespace/kube-public labeled namespace/kube-system labeled namespace/local-path-storage labeled
-
baseline
kubectl label --dry-run=server --overwrite ns --all \ pod-security.kubernetes.io/enforce=baseline
出力は次のようになります:
namespace/default labeled namespace/kube-node-lease labeled namespace/kube-public labeled Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "baseline:latest" Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged namespace/kube-system labeled namespace/local-path-storage labeled
-
restricted
kubectl label --dry-run=server --overwrite ns --all \ pod-security.kubernetes.io/enforce=restricted
出力は次のようになります:
namespace/default labeled namespace/kube-node-lease labeled namespace/kube-public labeled Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "restricted:latest" Warning: coredns-7bb9c7b568-hsptc (and 1 other pod): unrestricted capabilities, runAsNonRoot != true, seccompProfile Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile namespace/kube-system labeled Warning: existing pods in namespace "local-path-storage" violate the new PodSecurity enforce level "restricted:latest" Warning: local-path-provisioner-d6d9f7ffc-lw9lh: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile namespace/local-path-storage labeled
-
この出力から、privileged
Podセキュリティの標準を適用すると、名前空間のどれにも警告が示されないことに気付くでしょう。
これに対し、baseline
とrestrict
の標準ではどちらも、とりわけkube-system
名前空間に対して警告が示されています。
モード、バージョン、標準のセット
このセクションでは、latest
バージョンに以下のPodセキュリティの標準を適用します:
enforce
モードでbaseline
標準。warn
およびaudit
モードでrestricted
標準。
baseline
Podセキュリティの標準は、免除リストを短く保てて、かつ既知の特権昇格を防ぐような、利便性のある中庸を提供します。
加えて、kube-system
内の失敗からPodを守るために、適用されるPodセキュリティの標準の対象から名前空間を免除します。
環境にPodセキュリティアドミッションを実装する際には、以下の点を考慮してください:
-
クラスターに適用されるリスク状況に基づくと、
restricted
のようにより厳格なPodセキュリティの標準のほうが、より良い選択肢かもしれません。 -
kube-ssytem
名前空間の免除は、Podがその名前空間でprivileged
として実行するのを許容することになります。 実世界で使うにあたっては、以下の最小権限の原則に従ってkube-system
へのアクセスを制限する厳格なRBACポリシーを適用することを、Kubernetesプロジェクトは強く推奨します。 上記の標準を実装するには、次のようにします: -
目的のPodセキュリティの標準を実装するために、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/v1 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
-
クラスターの作成中にこのファイルを取り込むAPIサーバーを設定します:
cat <<EOF > /tmp/pss/cluster-config.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane kubeadmConfigPatches: - | 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
備考: macOSでDocker Desktopとkindを利用している場合は、Preferences > Resources > File Sharingのメニュー項目からShared Directoryとして/tmp
を追加できます。 -
目的のPodセキュリティの標準を適用するために、Podセキュリティアドミッションを使うクラスターを作成します:
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.30.0) 🖼 ✓ 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 question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
-
kubectlをこのクラスターに向けます:
kubectl cluster-info --context kind-psa-with-cluster-pss
出力は次のようになります:
Kubernetes control plane is running at https://127.0.0.1:63855 CoreDNS is running at https://127.0.0.1:63855/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
-
デフォルトの名前空間にPodを作成します:
kubectl apply -f https://k8s.io/examples/security/example-baseline-pod.yaml
Podは正常に開始されますが、出力には警告が含まれます:
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
後片付け
では、上記で作成したクラスターを、以下のコマンドを実行して削除します:
kind delete cluster --name psa-with-cluster-pss
kind delete cluster --name psa-wo-cluster-pss
次の項目
- 前出の一連の手順を一度に全て行うためにシェルスクリプトを実行します:
- クラスターレベルの設定に基づきPodセキュリティの標準を作成します。
- APIサーバーでこの設定を取り込むようにファイルを作成します。
- この設定のAPIサーバーを立てるクラスターを作成します。
- この新しいクラスターにkubectl contextをセットします。
- 最小限のPod YAMLファイルを作成します。
- 新しいクラスター内でPodを作成するために、このファイルを適用します。
- Podのセキュリティアドミッション
- Podセキュリティの標準
- 名前空間レベルでのPodセキュリティの標準の適用
2 - 名前空間レベルでのPodセキュリティの標準の適用
Note
このチュートリアルは、新しいクラスターにのみ適用されます。Podセキュリティアドミッション(PSA)は、ベータへ進み、v1.23以降でデフォルトで有効になっています。
Podセキュリティアドミッションは、Podが作成される際に、Podセキュリティの標準の適用の認可を制御するものです。
このチュートリアルでは、一度に1つの名前空間でbaseline
Podセキュリティ標準を強制します。
Podセキュリティの標準を複数の名前空間に一度にクラスターレベルで適用することもできます。やり方についてはクラスターレベルでのPodセキュリティの標準の適用を参照してください。
始める前に
ワークステーションに以下をインストールしてください:
クラスターの作成
-
以下のように
KinD
クラスターを作成します。kind create cluster --name psa-ns-level
出力は次のようになります:
Creating cluster "psa-ns-level" ... ✓ Ensuring node image (kindest/node:v%!f(string=1.).0) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-psa-ns-level" You can now use your cluster with: kubectl cluster-info --context kind-psa-ns-level Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
-
kubectl のコンテキストを新しいクラスターにセットします:
kubectl cluster-info --context kind-psa-ns-level
出力は次のようになります:
Kubernetes control plane is running at https://127.0.0.1:50996 CoreDNS is running at https://127.0.0.1:50996/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
名前空間の作成
example
と呼ぶ新しい名前空間を作成します:
kubectl create ns example
出力は次のようになります:
namespace/example created
名前空間へのPodセキュリティの標準チェックの有効化
-
ビルトインのPod Security Admissionでサポートされているラベルを使って、この名前空間のPodセキュリティの標準を有効にします。 このステップでは、baseline Podセキュリティの標準の最新バージョンに合わないPodについて警告するチェックを設定します。
kubectl label --overwrite ns example \ pod-security.kubernetes.io/warn=baseline \ pod-security.kubernetes.io/warn-version=latest
-
ラベルを使って、任意の名前空間に対して複数のPodセキュリティの標準チェックを設定できます。 以下のコマンドは、
baseline
Podセキュリティの標準をenforce
(強制)としますが、restricted
Podセキュリティの標準には最新バージョンに準じてwarn
(警告)およびaudit
(監査)とします(デフォルト値)。kubectl label --overwrite ns example \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/enforce-version=latest \ pod-security.kubernetes.io/warn=restricted \ pod-security.kubernetes.io/warn-version=latest \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/audit-version=latest
Podセキュリティの標準の強制の実証
-
example
名前空間内にbaseline
Podを作成します:kubectl apply -n example -f https://k8s.io/examples/security/example-baseline-pod.yaml
Podは正常に起動しますが、出力には警告が含まれています。例えば:
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
-
default
名前空間内にbaseline
Podを作成します:kubectl apply -n default -f https://k8s.io/examples/security/example-baseline-pod.yaml
出力は次のようになります:
pod/nginx created
example
名前空間にだけ、Podセキュリティの標準のenforceと警告の設定が適用されました。
default
名前空間内では、警告なしに同じPodを作成できました。
後片付け
では、上記で作成したクラスターを、以下のコマンドを実行して削除します:
kind delete cluster --name psa-ns-level
次の項目
-
前出の一連の手順を一度に全て行うためにシェルスクリプトを実行します。
- KinDクラスターを作成します。
- 新しい名前空間を作成します。
enforce
モードではbaseline
Podセキュリティの標準を適用し、warn
およびaudit
モードではrestricted
Podセキュリティの標準を適用します。- これらのPodセキュリティの標準を適用した新しいPodを作成します。