当前位置:  首页>> 技术小册>> Kubernetes中文教程(六)

本教程仅适用于新集群。

Pod 安全准入(PSA)在 v1.23 及更高版本默认启用,
因为它已[进阶为 Beta]。
Pod 安全准入是在创建 Pod 时应用
[Pod 安全标准]的准入控制器。
本教程将向你展示如何在集群级别实施 baseline Pod 安全标准,
该标准将标准配置应用于集群中的所有名字空间。

要将 Pod 安全标准应用于特定名字空间,
请参阅[在名字空间级别应用 Pod 安全标准]。

如果你正在运行 v 以外的 Kubernetes 版本,
请查阅该版本的文档。

在你的工作站中安装以下内容:

  • [KinD]
  • [kubectl]

本教程演示了你可以对完全由你控制的 Kubernetes 集群所配置的内容。
如果你正在学习如何为一个无法配置控制平面的托管集群配置 Pod 安全准入,
请参阅[在名字空间级别应用 Pod 安全标准]。

正确选择要应用的 Pod 安全标准

[Pod 安全准入]
允许你使用以下模式应用内置的
[Pod 安全标准]:
enforceauditwarn

要收集信息以便选择最适合你的配置的 Pod 安全标准,请执行以下操作:

  1. 创建一个没有应用 Pod 安全标准的集群:

    1. kind create cluster --name psa-wo-cluster-pss

输出类似于:

  1. Creating cluster "psa-wo-cluster-pss" ...
  2. Ensuring node image
  3. Preparing nodes
  4. Writing configuration
  5. Starting control-plane
  6. Installing CNI
  7. Installing StorageClass
  8. Set kubectl context to "kind-psa-wo-cluster-pss"
  9. You can now use your cluster with:
  10. kubectl cluster-info --context kind-psa-wo-cluster-pss
  11. Thanks for using kind!
  1. 将 kubectl 上下文设置为新集群:

    1. kubectl cluster-info --context kind-psa-wo-cluster-pss

输出类似于:

  1. Kubernetes control plane is running at https://127.0.0.1:61350
  2. CoreDNS is running at https://127.0.0.1:61350/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
  3. To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
  1. 获取集群中的名字空间列表:

    1. kubectl get ns

输出类似于:

  1. NAME STATUS AGE
  2. default Active 9m30s
  3. kube-node-lease Active 9m32s
  4. kube-public Active 9m32s
  5. kube-system Active 9m32s
  6. local-path-storage Active 9m26s
  1. 使用 --dry-run=server 来了解应用不同的 Pod 安全标准时会发生什么:

    1. Privileged
      1. kubectl label --dry-run=server --overwrite ns --all \
      2. pod-security.kubernetes.io/enforce=privileged
  1. 输出类似于:
  2. ```
  3. namespace/default labeled
  4. namespace/kube-node-lease labeled
  5. namespace/kube-public labeled
  6. namespace/kube-system labeled
  7. namespace/local-path-storage labeled
  8. ```
  1. Baseline
    1. kubectl label --dry-run=server --overwrite ns --all \
    2. pod-security.kubernetes.io/enforce=baseline
  1. 输出类似于:
  2. ```
  3. namespace/default labeled
  4. namespace/kube-node-lease labeled
  5. namespace/kube-public labeled
  6. Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "baseline:latest"
  7. Warning: etcd-psa-wo-cluster-pss-control-plane : host namespaces, hostPath volumes
  8. Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes
  9. Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged
  10. namespace/kube-system labeled
  11. namespace/local-path-storage labeled
  12. ```
  1. Restricted
    1. kubectl label --dry-run=server --overwrite ns --all \
    2. pod-security.kubernetes.io/enforce=restricted
  1. 输出类似于:
  2. ```
  3. namespace/default labeled
  4. namespace/kube-node-lease labeled
  5. namespace/kube-public labeled
  6. Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "restricted:latest"
  7. Warning: coredns-7bb9c7b568-hsptc : unrestricted capabilities, runAsNonRoot != true, seccompProfile
  8. Warning: etcd-psa-wo-cluster-pss-control-plane : host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true
  9. Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
  10. Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
  11. namespace/kube-system labeled
  12. Warning: existing pods in namespace "local-path-storage" violate the new PodSecurity enforce level "restricted:latest"
  13. Warning: local-path-provisioner-d6d9f7ffc-lw9lh: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
  14. namespace/local-path-storage labeled
  15. ```

从前面的输出中,你会注意到应用 privileged Pod 安全标准不会显示任何名字空间的警告。
然而,baselinerestricted 标准都有警告,特别是在 kube-system 名字空间中。

设置模式、版本和标准

在本节中,你将以下 Pod 安全标准应用于最新(latest)版本:

  • enforce 模式下的 baseline 标准。
  • warnaudit 模式下的 restricted 标准。

baseline Pod 安全标准提供了一个方便的中间立场,能够保持豁免列表简短并防止已知的特权升级。

此外,为了防止 kube-system 中的 Pod 失败,你将免除该名字空间应用 Pod 安全标准。

在你自己的环境中实施 Pod 安全准入时,请考虑以下事项:

  1. 根据应用于集群的风险状况,更严格的 Pod 安全标准(如 restricted)可能是更好的选择。
  2. kube-system 名字空间进行赦免会允许 Pod 在其中以 privileged 模式运行。
    对于实际使用,Kubernetes 项目强烈建议你应用严格的 RBAC 策略来限制对 kube-system 的访问,
    遵循最小特权原则。
  3. 创建一个配置文件,Pod 安全准入控制器可以使用该文件来实现这些 Pod 安全标准:

    1. mkdir -p /tmp/pss
    2. cat <<EOF > /tmp/pss/cluster-level-pss.yaml
    3. apiVersion: apiserver.config.k8s.io/v1
    4. kind: AdmissionConfiguration
    5. plugins:
    6. - name: PodSecurity
    7. configuration:
    8. apiVersion: pod-security.admission.config.k8s.io/v1
    9. kind: PodSecurityConfiguration
    10. defaults:
    11. enforce: "baseline"
    12. enforce-version: "latest"
    13. audit: "restricted"
    14. audit-version: "latest"
    15. warn: "restricted"
    16. warn-version: "latest"
    17. exemptions:
    18. usernames: []
    19. runtimeClasses: []
    20. namespaces: [kube-system]
    21. EOF

pod-security.admission.config.k8s.io/v1 配置需要 v1.25+。
对于 v1.23 和 v1.24,使用 [v1beta1]。
对于 v1.22,使用 [v1alpha1]。

  1. 在创建集群时配置 API 服务器使用此文件:

    1. cat <<EOF > /tmp/pss/cluster-config.yaml
    2. kind: Cluster
    3. apiVersion: kind.x-k8s.io/v1alpha4
    4. nodes:
    5. - role: control-plane
    6. kubeadmConfigPatches:
    7. - |
    8. kind: ClusterConfiguration
    9. apiServer:
    10. extraArgs:
    11. admission-control-config-file: /etc/config/cluster-level-pss.yaml
    12. extraVolumes:
    13. - name: accf
    14. hostPath: /etc/config
    15. mountPath: /etc/config
    16. readOnly: false
    17. pathType: "DirectoryOrCreate"
    18. extraMounts:
    19. - hostPath: /tmp/pss
    20. containerPath: /etc/config
    21. # optional: if set, the mount is read-only.
    22. # default false
    23. readOnly: false
    24. # optional: if set, the mount needs SELinux relabeling.
    25. # default false
    26. selinuxRelabel: false
    27. # optional: set propagation mode
    28. # see https://kubernetes.io/docs/concepts/storage/volumes/#mount-propagation
    29. # default None
    30. propagation: None
    31. EOF

如果你在 macOS 上使用 Docker Desktop 和 KinD,
你可以在菜单项 Preferences > Resources > File Sharing
下添加 /tmp 作为共享目录。

  1. 创建一个使用 Pod 安全准入的集群来应用这些 Pod 安全标准:

    1. kind create cluster --name psa-with-cluster-pss --config /tmp/pss/cluster-config.yaml

输出类似于:

  1. Creating cluster "psa-with-cluster-pss" ...
  2. Ensuring node image
  3. Preparing nodes
  4. Writing configuration
  5. Starting control-plane
  6. Installing CNI
  7. Installing StorageClass
  8. Set kubectl context to "kind-psa-with-cluster-pss"
  9. You can now use your cluster with:
  10. kubectl cluster-info --context kind-psa-with-cluster-pss
  11. Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community
  1. 将 kubectl 指向集群

    1. kubectl cluster-info --context kind-psa-with-cluster-pss

输出类似于:

  1. Kubernetes control plane is running at https://127.0.0.1:63855
  2. CoreDNS is running at https://127.0.0.1:63855/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
  3. To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
  1. 在 default 名字空间下创建一个 Pod:

    1. cat <<EOF > /tmp/pss/nginx-pod.yaml
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: nginx
    6. spec:
    7. containers:
    8. - image: nginx
    9. name: nginx
    10. ports:
    11. - containerPort: 80
    12. EOF
  2. 在集群中创建 Pod:

    1. kubectl apply -f https://k8s.io/examples/security/example-baseline-pod.yaml

这个 Pod 正常启动,但输出包含警告:

  1. Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false , unrestricted capabilities , runAsNonRoot != true , seccompProfile
  2. pod/nginx created

清理

现在通过运行以下命令删除你上面创建的集群:

  1. kind delete cluster --name psa-with-cluster-pss
  1. kind delete cluster --name psa-wo-cluster-pss

  • 运行一个 [shell 脚本]
    一次执行前面的所有步骤:
    1. 创建一个基于 Pod 安全标准的集群级别配置
    2. 创建一个文件让 API 服务器消费这个配置
    3. 创建一个集群,用这个配置创建一个 API 服务器
    4. 设置 kubectl 上下文为这个新集群
    5. 创建一个最小的 Pod yaml 文件
    6. 应用这个文件,在新集群中创建一个 Pod
  • [Pod 安全准入]
  • [Pod 安全标准]
  • [在名字空间级别应用 Pod 安全标准]

该分类下的相关小册推荐: