在 OpenShift 上以 root 权限启动 pod

start pod with root privilege on OpenShift

我有一个映像需要 root 权限才能启动。

现在我正在尝试将它部署到 OpenShift 上。

这是我用来部署它的部署yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: xyz
  annotations:
   k8s.v1.cni.cncf.io/networks: macvlan-conf
spec:
  selector:
    matchLabels:
      name: xyz
  template:
    metadata:
      labels:
        name: xyz
    spec:
      containers:
      - name: xyz
        image: 172.30.1.1:5000/myproject/xyz@sha256:bf3d219941ec0de7f52f6babbca23e03cc2611d327552b08f530ead9ec627ec2
        imagePullPolicy: Always
        securityContext:
          capabilities:
            add:
              - ALL
          privileged: false
          allowPrivilegeEscalation: false
          runAsUser: 0
        serviceAccount: runasanyuid
        serviceAccountName: runasanyuid
        hostNetwork: true
        resources:
          limits:
            memory: "12000Mi"
          requests:
            memory: "6000Mi"
        ports:
        - containerPort: 2102
        command:
        - /usr/sbin/sshd -D

请注意,我已经在项目中使用任何 UID 创建了一个名为 'scc-admin' 到 运行 pods 的 SCC,因为我知道 OpenShift 不会t 允许 pods 默认以 root 权限启动。

kind: SecurityContextConstraints
apiVersion: v1
metadata:
  name: scc-admin
allowPrivilegedContainer: true
runAsUser:
  type: RunAsAny
seLinuxContext:
  type: RunAsAny
fsGroup:
  type: RunAsAny
supplementalGroups:
  type: RunAsAny
users:
- developer
groups:
- developer

这是我在互联网上找到的解决我的问题的方法,但我想它并没有起作用:(

[root@centos72_base ~]# oc get scc
NAME               PRIV      CAPS      SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY   READONLYROOTFS   VOLUMES
anyuid             true      []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    10         false            [configMap downwardAPI emptyDir hostPath persistentVolumeClaim projected secret]
hostaccess         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <none>     false            [configMap downwardAPI emptyDir hostPath persistentVolumeClaim projected secret]
hostmount-anyuid   false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    <none>     false            [configMap downwardAPI emptyDir hostPath nfs persistentVolumeClaim projected secret]
hostnetwork        false     []        MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
nonroot            false     []        MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
privileged         true      [*]       RunAsAny    RunAsAny           RunAsAny    RunAsAny    <none>     false            [*]
restricted         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
scc-admin          true      []        RunAsAny    RunAsAny           RunAsAny    RunAsAny    <none>     false            [awsElasticBlockStore azureDisk azureFile cephFS cinder configMap downwardAPI emptyDir fc flexVolume flocker gcePersistentDisk gitRepo glusterfs iscsi nfs persistentVolumeClaim photonPersistentDisk portworxVolume projected quobyte rbd scaleIO secret storageOS vsphere]
[root@centos72_base ~]#

另请注意,使用下面的命令

,这张图片在 docker 下效果很好
docker run -d --network host --privileged --cap-add=ALL --security-opt seccomp=unconfined --name xyz 172.30.1.1:5000/myproject/xyz /usr/sbin/sshd -D
[root@centos72_base ~]# docker ps | grep xyz
793e339ff732   172.30.1.1:5000/myproject/xyz              "/usr/sbin/sshd -D"      About a minute ago   Up About a minute             xyz

在 OpenShift 上,我在上面提供的部署文件中遇到了这些错误

Error creating: pods "xyz-7966f58588-" is forbidden: unable to validate against any security context constraint: [spec.containers[0].securityContext.securityContext.runAsUser: Invalid value: 0: must be in the ranges: [1000140000, 1000149999] capabilities.add: Invalid value: "ALL": capability may not be added]

这意味着我必须删除

          capabilities:
            add:
              - ALL

          runAsUser: 0

启动 pod

当我从 yaml 文件中删除它们时,我从 pod 中收到崩溃环回错误

所以任何人都可以帮助我

您创建的 SCC 当前适用于用户 developer 和组 developer

您的部署使用 ServiceAccount runasanyuid

您需要编辑您的 SecurityContextConstraint,允许 ServiceAccount:

[...]
users:
- developer
- system:serviceaccount:<namespace-for-your-deployment>:runasanyuid
groups:
- developer

作为旁注,如果您只需要 运行 一个特权容器,而不是创建您自己的 SCC,OpenShift 附带 anyuid 一个您可以重新使用的容器 - 只是将您的 SA 添加到其用户列表中。

虽然最佳做法是避免使用特权容器。除非有充分的理由,否则您不应该 运行 以 root 身份进行处理 - 这在 OCI 出现很久之前就已经是事实了。

如果您的应用程序需要在某个地方写入内容,您可以使用一些 emptyDir 卷。如果您的应用程序试图绑定特权端口,您应该能够重新配置它。如果您的应用程序抱怨无法为其 UID 解析用户名,您可以查看 nsswrapper。使用 SecurityContextConstraints 或 PodSecurityPolicies 授予权限不是常态,它们应该是例外,请仔细考虑。

如果您的 Pod 在 运行非 root 身份时崩溃,请尝试检查其日志。如果这没有帮助,请尝试 oc debug -n <namespace> pod/<podname>,这应该会启动一个新的 Pod,在其中打开一个 shell,您可以在其中自己执行其入口点,也许可以尝试另一组选项,稍微更改您的配置,...直到您做对为止。您甚至可以从您的工作站 docker run --user=12435679 xxx 尝试:传递一个随机 UID 并查看您的 container/application 如何处理它。

这是我解决问题的方法:

我使用

在调试模式下启动了 pod
[root@centos72_base ~]# oc debug -n myproject pod/xyz-5b4875f8d7-n7m2g
Defaulting container name to xyz.
Use 'oc describe pod/xyz-5b4875f8d7-n7m2g-debug -n myproject' to see all of the containers in this pod.

Debugging with pod/xyz-5b4875f8d7-n7m2g-debug, original command: /usr/sbin/sshd -D
Waiting for pod to start ...
If you don't see a command prompt, try pressing enter.
sh-4.2# whoami
whoami: cannot find name for user ID 1000140000
sh-4.2$ 

我认为 pod 没有 运行 root 权限。

我必须检查我的 pod 正在使用的 SCC,所以我执行了

[root@centos72_base ~]# oc get pod xyz-5b4875f8d7-n7m2g -o yaml | grep openshift.io/scc
    openshift.io/scc: restricted

我看到我的 pod 仍处于受限 SCC 中,因此我不得不使用

更改集群的默认 SCC
[root@centos72_base ~]# oc adm policy add-scc-to-group privileged system:authenticated
scc "privileged" added to groups: ["system:authenticated"]
[root@centos72_base ~]# 

现在我可以看到它已更改为特权(我知道这不是最佳做法,但我只是想确保 pod 会 运行,最佳做法是 运行 具有非root权限的pod)

并且在 运行再次部署之后,我再次检查 SCC,我发现它现在是 运行 特权 SCC

[root@centos72_base ~]# oc get pod xyz-5b4875f8d7-n7m2g -o yaml | grep openshift.io/scc
    openshift.io/scc: privileged

然后我以调试模式进入 pod 以检查我是否正在 运行使用 root 用户连接 pod

[root@centos72_base ~]# oc debug -n myproject pod/xyz-5b4875f8d7-n7m2g
Defaulting container name to xyz.
Use 'oc describe pod/xyz-5b4875f8d7-n7m2g-debug -n myproject' to see all of the containers in this pod.

Debugging with pod/xyz-5b4875f8d7-n7m2g-debug, original command: /usr/sbin/sshd -D
Waiting for pod to start ...
If you don't see a command prompt, try pressing enter.
sh-4.2# whoami
root
sh-4.2# 

我不建议将其用作此问题的默认解决方案,我只是将其用于测试并确保我的应用程序在 OpenShift 上运行

以下是对我有帮助的命令列表: 运行 pod 处于调试模式:

oc debug -n <project-name> pod/<pod-name>

运行 具有 root 权限的处于调试模式的 pod:

oc debug deployment/<deployment-name> --as-root -n <project-name>

列出您的安全上下文:

oc get scc

打开 pod 的 yaml 文件:

oc get pod <pod-name> -o yaml 

列出其 scc:

oc get pod <pod-name> -o yaml | grep openshift.io/scc

设置默认scc:

oc adm policy add-scc-to-group <scc-name> system:authenticated