容器之间的 Kubernetes 卷 - 权限被拒绝

Posted

技术标签:

【中文标题】容器之间的 Kubernetes 卷 - 权限被拒绝【英文标题】:Kubernetes volume between containers - Permission denied 【发布时间】:2021-08-28 01:35:02 【问题描述】:

我有 2 个容器:一个带有 gcloud/gsutil 和 clickhouse(基于 debian/buster-slim,在 Dockerfile 中没有设置额外的用户或权限)和 git-sync 容器。 我在一个具有共享卷的 Pod 中并排运行它们。 我在共享卷的 git-sync 容器中使用 sh 脚本提取存储库。这是清单:

apiVersion: v1
kind: Pod
metadata:
  name: ...
  namespace: ...
  annotations:
    ...
  labels:
    ...
spec:
  serviceAccountName: airflow
  automountServiceAccountToken: true
  volumes:
    - name: sql
      emptyDir: 
  containers:
    - name: base
      securityContext:
        runAsUser: 65533
        runAsGroup: 65533
      imagePullPolicy: Always
      image: clickhouse-client-gcloud:20.6.4.44
      volumeMounts:
        - name: sql
          mountPath: /opt/sql
      resources:
        requests:
          memory: "4000Mi"
          cpu: "4"
        limits:
          memory: "8000Mi"
          cpu: "4"
      env:
        - name: GS_SERVICE_ACCOUNT
          valueFrom:
            secretKeyRef:
              name: ...
              key: service_account.json
    - name: git-sync
      securityContext:
        runAsUser: 65533
        runAsGroup: 65533
      image: k8s.gcr.io/git-sync/git-sync:v3.3.1
      imagePullPolicy: Always
      volumeMounts:
        - name: sql
          mountPath: /tmp/git/
      resources:
        requests:
          memory: 300Mi
          cpu: 500m
        limits:
          memory: 600Mi
          cpu: 1000m
      envFrom:
      - configMapRef:
          name: ...
      - secretRef:
          name: ...

所以,我在一个容器中有 gcloud 和 clickhouse 客户端,在另一个容器中有 sh/sql 脚本,它们彼此共享卷。 第二个容器中有.sh 脚本:

echo $GS_SERVICE_ACCOUNT >> service_account.json 
gcloud auth activate-service-account --key-file=service_account.json

文件结构:

opt/
- cloud_client
- sql
-- git-repo
--- sql
---- 00.raw
----- 01.current.sh

当我运行 pod 时,对于客户端容器,我有下一个命令和参数:

cmds=["sh"],
arguments=["/opt/sql/git-repo/sql/00.raw/01.current.sh", f"get_current_parsing_day()"]

但我得到了:

sh: 0: Can't open /opt/sql/git-repo/sql/00.raw/01.current.sh

如果我使用sleep 运行客户端容器,使用/bin/bash 连接内部,然后运行sh /opt/sql/git-repo/sql/00.raw/01.current.sh,则文件创建失败。

cannot create service_account.json: Permission denied

如果我继续,cd 到该存储库并运行 sh 01.current.sh,然后我得到 gsutil 错误:

WARNING: Could not setup log file in /.config/gcloud/logs, (Error: Could not create directory [/.config/gcloud/logs/2021.06.11]: Permission denied.

Please verify that you have permissions to write to the parent directory.)
ERROR: gcloud crashed (ValueError): No key could be detected.

If you would like to report this issue, please run the following command:
  gcloud feedback

To check gcloud for common problems, please run the following command:
  gcloud info --run-diagnostics

但是密钥文件在那里,它是为服务帐户创建并包含 JSON...

好像我有权限问题,但我不明白如何解决?我想从两个容器中执行文件/脚本并允许它们写入主容器。

【问题讨论】:

【参考方案1】:

问题出在securityContext,我运行了两个容器,但不是以root身份(虽然它是not a good practice),但是容器本身没有定义这个uid。

securityContext:
    runAsUser: 65533
    runAsGroup: 65533

我删除它并重新启动它后,一切都解决了。

【讨论】:

以上是关于容器之间的 Kubernetes 卷 - 权限被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes之存储卷

Kubernetes存储

Kubernetes 主要功能

在K8S中使用Local持久卷

在K8S中使用Local持久卷

如何在 kubernetes 中使用 windows 容器挂载卷?