如何在 Kubernetes Pod 中挂载具有特定 UID 的卷?

srk*_*Z84 23 permissions disk-volume pv kubernetes

所以,我试图让 Nexus 基于Kubernetes 中的这个图像运行,但它失败了:

mkdir: cannot create directory '../sonatype-work/nexus3/log': Permission denied
mkdir: cannot create directory '../sonatype-work/nexus3/tmp': Permission denied
Java HotSpot(TM) 64-Bit Server VM warning: Cannot open file ../sonatype-work/nexus3/log/jvm.log due to No such file or directory
Run Code Online (Sandbox Code Playgroud)

从文档中可以看出该进程使用 UID 200 运行,并且必须使用这些权限安装卷:

A persistent directory, /nexus-data, is used for configuration,
logs, and storage. This directory needs to be writable by the Nexus
process, which runs as UID 200.
Run Code Online (Sandbox Code Playgroud)

我试图搜索文档以找到一种使用这些权限安装卷的方法,但是,我找不到任何方法来做到这一点。

有谁知道您是否可以在 PVC/PV 或 Deployment 的配置中指定用于安装卷的 UID?如果是这样,如何?

小智 40

没有办法设置UIDusing 的定义Pod,但是 Kubernetes 保存了UID源卷的 。

因此,您可以设置在主容器之前启动的UIDby InitContainer,只需将其添加到 的containers路径中Deployment

initContainers:
- name: volume-mount-hack
  image: busybox
  command: ["sh", "-c", "chown -R 200:200 /nexus"]
  volumeMounts:
  - name: <your nexus volume>
    mountPath: /nexus
Run Code Online (Sandbox Code Playgroud)

  • 但是,这对 ConfigMaps 和 Secrets 没有帮助。 (2认同)

小智 10

就像Anton说的,虽然我们不能使用Pod的定义来设置UID。这是该主题的另一种解决方法。

请参考Kubernetes官方文档Configure a Security Context for a Pod or Container

我使用的 pod 定义:

apiVersion: v1
kind: Pod
metadata:
  name: nexus3
  labels:
    app: nexus3
spec:
  securityContext:
    fsGroup: 200
  volumes:
  - name: nexus-data-vol
    emptyDir: {}
  containers:
  - name: nexus3-container
    image: sonatype/nexus3
    volumeMounts:
    - name: nexus-data-vol
      mountPath: /nexus-data
Run Code Online (Sandbox Code Playgroud)

服务定义:

apiVersion: v1
kind: Service
metadata:
  name: nexus3-service
spec:
  type: NodePort
  ports:
  - port: 8081
    nodePort: 30390
    protocol: TCP
    targetPort: 8081
  selector:
    app: nexus3
Run Code Online (Sandbox Code Playgroud)

然后在没有任何权限被拒绝或其他错误的情况下创建 pod 和服务:

# kubectl create -f nexus3.yaml
# kubectl create -f nexus3-svc.yaml
Run Code Online (Sandbox Code Playgroud)

尝试登录 Nexus3 容器并检查 /nexus-data 的所有者/权限:

# kubectl exec -it nexus3 -- sh
sh-4.2$ ls -ld /nexus-data/
drwxrwsrwx 16 root nexus 4096 Mar 13 09:00 /nexus-data/
sh-4.2$
Run Code Online (Sandbox Code Playgroud)

可以看到,该目录属于root:nexus,也可以查看该目录下的文件:

sh-4.2$ cd /nexus-data/
sh-4.2$ ls -l
total 72
drwxr-sr-x   3 nexus nexus  4096 Mar 13 09:00 blobs
drwxr-sr-x 269 nexus nexus 12288 Mar 13 08:59 cache
drwxr-sr-x   8 nexus nexus  4096 Mar 13 09:00 db
drwxr-sr-x   3 nexus nexus  4096 Mar 13 09:00 elasticsearch
drwxr-sr-x   3 nexus nexus  4096 Mar 13 08:59 etc
drwxr-sr-x   2 nexus nexus  4096 Mar 13 08:59 generated-bundles
drwxr-sr-x   2 nexus nexus  4096 Mar 13 08:59 instances
drwxr-sr-x   3 nexus nexus  4096 Mar 13 08:59 javaprefs
drwxr-sr-x   2 nexus nexus  4096 Mar 13 08:59 kar
drwxr-sr-x   3 nexus nexus  4096 Mar 13 08:59 keystores
-rw-r--r--   1 nexus nexus     8 Mar 13 08:59 lock
drwxr-sr-x   2 nexus nexus  4096 Mar 13 09:00 log
drwxr-sr-x   2 nexus nexus  4096 Mar 13 08:59 orient
-rw-r--r--   1 nexus nexus     5 Mar 13 08:59 port
drwxr-sr-x   2 nexus nexus  4096 Mar 13 08:59 restore-from-backup
drwxr-sr-x   7 nexus nexus  4096 Mar 13 09:00 tmp
sh-4.2$ touch test-file
sh-4.2$ ls -l test-file
-rw-r--r-- 1 nexus nexus 0 Mar 13 09:13 test-file
sh-4.2$ mkdir test-dir
sh-4.2$ ls -l test-dir
total 0
sh-4.2$ ls -ld test-dir
drwxr-sr-x 2 nexus nexus 4096 Mar 13 09:13 test-dir
Run Code Online (Sandbox Code Playgroud)

这就是 SetGID 的力量:)

现在让我们检查服务是否正常工作。我使用 minikube 来运行 kubernetes 集群:

chris@XPS-13-9350 ~ $ minikube service nexus3-service --url
http://192.168.39.95:30390
chris@XPS-13-9350 ~ $ curl -u admin:admin123 http://192.168.39.95:30390/service/metrics/ping
pong
Run Code Online (Sandbox Code Playgroud)

该服务按预期工作。