TL;DR
您可以使用anyuid
安全上下文来运行 pod,以避免 OpenShift 分配任意 UID,并将卷上的权限设置为用户的已知 UID。
OpenShift 将覆盖图像本身可能指定的用户 ID 来运行:
用户 ID 实际上并不是完全随机的,而是分配给您的项目的唯一用户 ID。事实上,您的项目被分配了一系列可以运行应用程序的用户 ID。用户 ID 集不会与其他项目重叠。您可以通过在项目上运行 oc describe 来查看分配给项目的范围。
为每个项目分配不同范围的用户 ID 的目的是,在多租户环境中,来自不同项目的应用程序永远不会以相同的用户 ID 运行。使用持久存储时,应用程序创建的任何文件在文件系统中也将具有不同的所有权。
...这是一个祝福和诅咒,例如,当使用共享持久卷声明时(例如 PVC 安装在ReadWriteMany多个 pod 读取/写入数据 - 由于文件所有权和权限不正确,一个 pod 创建的文件将无法被另一 pod 访问。
解决这个问题的一种方法是使用anyuid安全上下文“提供受限 SCC 的所有功能,但允许用户使用任何 UID 和任何 GID 运行”。
当使用anyuid
在安全上下文中,我们知道 pod 将运行的用户和组 ID,并且我们可以提前设置共享卷的权限。例如,所有 Pod 都以restricted
默认安全上下文:
当运行 pod 时anyuid
在安全上下文中,OpenShift 不会从为命名空间分配的 UID 范围中分配任意 UID:
这只是举例,但使用具有固定 UID 和 GID 的非 root 用户构建的映像(例如1000:1000
)将作为该用户在 OpenShift 中运行,文件将以该用户的所有权创建(例如1000:1000
),可以在 PVC 上将权限设置为设置运行服务的用户的已知 UID 和 GID。例如,我们可以创建一个新的 PVC:
cat <<EOF |kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
namespace: k8s
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi
storageClassName: portworx-shared-sc
EOF
...然后将其安装在 Pod 中:
kubectl run -i --rm --tty ansible --image=lazybit/ansible:v4.0.0 --restart=Never -n k8s --overrides='
{
"apiVersion": "v1",
"kind": "Pod",
"spec": {
"serviceAccountName": "default",
"containers": [
{
"name": "nginx",
"imagePullPolicy": "Always",
"image": "lazybit/ansible:v4.0.0",
"command": ["ash"],
"stdin": true,
"stdinOnce": true,
"tty": true,
"env": [
{
"name": "POD_NAME",
"valueFrom": {
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "metadata.name"
}
}
}
],
"volumeMounts": [
{
"mountPath": "/data",
"name": "data"
}
]
}
],
"volumes": [
{
"name": "data",
"persistentVolumeClaim": {
"claimName": "data"
}
}
]
}
}'
...并在 PVC 中创建文件作为USER在 Dockerfile 中设置.