在 OpenShift 上以 root 权限启动 pod

问题描述

我有一个需要 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

请注意,我已经创建了一个名为“scc-admin”的 SCC 来运行我正在使用任何 UID 处理的项目中的 pod,因为我知道 OpenShift 认不允许 pod 以 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 上,我在上面提供的部署文件中遇到了这些错误

错误创建:pods“xyz-7966f58588-”被禁止:无法针对任何安全上下文约束进行验证:[spec.containers[0].securityContext.securityContext.runAsUser:无效值:0:必须在以下范围内: [1000140000,1000149999] capabilities.add: 无效值: "ALL": 不能添加能力]

这意味着我必须删除

          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

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

虽然最好的做法是避免使用特权容器。除非有充分的理由,否则您不应该以 root 身份运行进程 - 这在 OCI 之前很久就是如此。

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

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

,

这是我解决问题并解决它的方法:

我使用

在调试模式下启动了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,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