首页 > 解决方案 > 为什么我的 Pod 安全策略没有停止在 pod 中使用 root 用户?

问题描述

我正在尝试部署一个受限制的 psp,它应该禁止在 pod 中使用 root 用户:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: unprivilegedpolicy
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    - 'persistentVolumeClaim'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  supplementalGroups:
    rule: 'MustRunAs'
    ranges:
      - min: 1
        max: 65535
  fsGroup:
    rule: 'MustRunAs'
    ranges:
      - min: 1
        max: 65535
  readOnlyRootFilesystem: false

我已将此 psp 添加到 ClusterRole 并将其绑定到命名空间hello-world

Name:         UnPrivilegedClusterRole
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources                   Non-Resource URLs  Resource Names        Verbs
  ---------                   -----------------  --------------        -----
  podsecuritypolicies.policy  []                 [unprivilegedpolicy]  [use]

[root@master01 ~]# kubectl describe clusterrolebindings.rbac.authorization.k8s.io HelloWorldRoleBinding
Name:         HelloWorldRoleBinding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  UnPrivilegedClusterRole
Subjects:
  Kind   Name                    Namespace
  ----   ----                    ---------
  Group  system:serviceaccounts  hello-world

但是,如果我尝试使用kubectl run --name=nginx hello-world容器成功运行 ngnix 容器,则以 root 用户身份运行。部署通过 ServiceAccount 进行部署。

PodSecurityPolicy 准入控制器已启用。

有人对此有解决方案吗?

标签: kubernetes

解决方案


首先:

$ kubectl run --name=nginx hello-world

您没有指定 pod 的图像名称。正确的语法应该是:

$ kubectl run --image=nginx NAME_OF_DEPLOYMENT

如上所述,命令将尝试创建部署


您遇到的问题很可能与

  • 不工作/打开准入控制器

在打开pod 安全策略的新创建的 Kubernetes 集群上,无论您的权限如何,您都应该无法生成任何 pod。

Pod 安全策略控制被实现为可选(但推荐)准入控制器。PodSecurityPolicies 是通过启用准入控制器来强制执行的,但是在没有授权任何策略的情况下这样做会阻止在集群中创建任何 Pod。

-- Kubernetes.io:启用 pod 安全策略

准入控制器以及 pod 安全策略和 RBAC 与您正在使用的解决方案密切相关。您应该参考特定于您的案例的文档。

例如:

  • 新创建的 GKE 集群启用了 pod 安全且未配置任何PSP配置,不会创建 pod。它将显示一条消息:Unable to validate against any pod security policy: []

警告:如果您在未先定义和授权任何实际策略的情况下启用 PodSecurityPolicy 控制器,则任何用户、控制器或服务帐户都无法创建或更新 Pod。如果您正在使用现有集群,则应 在 启用控制器之前定义授权 策略 。

-- GKE:Pod 安全策略以及如何启用/禁用它

  • 新创建的 Kubernetes 集群kubespray(在 Ubuntu 上配置和运行时将 pod 安全策略变量设置为 true)将PSP创建一个限制性文件,并且MustRunAsNonRootPSP.

NGINXpod还有另一个问题。NGINX图像将尝试root在 pod 内以用户身份运行。准入控制器PSP配置有:

runAsUser:
  rule: MustRunAsNonRoot

会用消息否认:Error: container has runAsNonRoot and image will run as root根据PSP

要使用此策略运行NGINXpod,您需要:

  • 创建一个PSP(允许在 pod 内以 root 用户身份运行):
  runAsUser:
    rule: RunAsAny
  • 创建NGINX以允许NGINX以非 root 用户身份运行的方式配置的自己的映像。

下面这种 pod 的示例:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: non-root-nginx
  name: non-root-nginx
spec:
  securityContext:
    runAsUser: 101
    fsGroup: 101
  containers:
  - image: nginx
    name: non-root-nginx
    volumeMounts:
    - mountPath: /var/cache/nginx
      name: edir
    - mountPath: /var/run
      name: varun
    - mountPath: /etc/nginx/conf.d/default.conf
      name: default-conf
      subPath: default.conf
  dnsPolicy: ClusterFirst
  restartPolicy: Never
  volumes:
  - name: edir
    emptyDir: {}
  - name: varun
    emptyDir: {}
  - name: default-conf
    configMap:
      name: nginx8080
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx8080
  namespace: default
data:
  default.conf: |+
    server {
        listen       8080;
        server_name  localhost;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }

推荐阅读