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