【问题标题】:What's the best way to share/mount one file into a pod?将一个文件共享/挂载到 pod 中的最佳方法是什么?
【发布时间】:2023-03-18 11:15:01
【问题描述】:

我正在考虑使用机密来挂载单个文件,但您似乎只能挂载会覆盖所有其他内容的目录。如何在不挂载目录的情况下共享单个配置文件?

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

    例如,您有一个包含 2 个配置文件的配置映射:

    kubectl create configmap config --from-file <file1> --from-file <file2>
    

    您可以像这样使用 subPath 将单个文件挂载到现有目录中:

    ---
            volumeMounts:
            - name: "config"
              mountPath: "/<existing folder>/<file1>"
              subPath: "<file1>"
            - name: "config"
              mountPath: "/<existing folder>/<file2>"
              subPath: "<file2>"
          restartPolicy: Always
          volumes:
            - name: "config"
              configMap:
                name: "config"
    ---
    

    完整示例here

    【讨论】:

    • 困惑为什么当 OP 只需要 1 个文件时这显示 2 个文件的示例,我认为这同样适用于单个文件的情况。
    • @the0ther 是的,只是为了说明它如何处理多个文件
    • 如果文件不是 ConfigMap 或者不在 ConfigMap 中怎么办?是否可以从本地磁盘挂载任意文件?
    • @LondonRob 在你的情况下你应该使用 hostPath,见kubernetes.io/docs/concepts/storage/volumes/#hostpath
    • 注意:使用 ConfigMap 作为 subPath 卷的容器将不会收到 ConfigMap 更新。 kubernetes.io/docs/tasks/configure-pod-container/…
    【解决方案2】:

    我将从here 的这个工作示例开始。确保您至少使用 Kubernetes 1.3。

    像这样简单地创建一个 ConfigMap:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: test-pd-plus-cfgmap
    data:
      file-from-cfgmap: file data
    

    然后像这样创建一个 pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pd-plus-cfgmap
    spec:
      containers:
      - image: ubuntu
        name: bash
        stdin: true
        stdinOnce: true
        tty: true
        volumeMounts:
        - mountPath: /mnt
          name: pd
        - mountPath: /mnt/file-from-cfgmap
          name: cfgmap
          subPath: file-from-cfgmap
      volumes:
      - name: pd
        gcePersistentDisk:
          pdName: testdisk
      - name: cfgmap
        configMap:
          name: test-pd-plus-cfgmap
    

    【讨论】:

    • 这会像前面提到的 OP 一样覆盖整个目录。
    • 我不同意。测试了包括“subPath”的方法,并且只安装了文件而不是整个目录。用 Kubernetes 1.5 测试。
    • @dmorlock 这个问题措辞含糊。这将如标题所示“将一个文件共享/挂载到 pod”,就像问题询问“共享配置文件而不挂载目录”一样
    • 我现在不得不三次回答这个问题,因为kubernetes.io/docs/tasks/configure-pod-container/… 的文档中没有提到“子路径”这个词。我想这是一个需要创建和提交的友好文档 PR。
    • @JoelB,如果我只想挂载我的主路径而不是像 ./abc.txt 这样的子路径,其中 abc.txt 位于容器内的主文件夹而不是子文件夹,有什么办法吗.
    【解决方案3】:

    目前(v1.0、v1.1)没有办法卷挂载单个配置文件。 Secret 结构自然能够表示多个秘密,这意味着它必须是一个目录。

    当我们获取配置对象时,应该支持单个文件。

    与此同时,您可以挂载一个目录并从您的映像中对其进行符号链接,也许吧?

    【讨论】:

    【解决方案4】:

    已接受答案的有用附加信息:

    假设您的源文件名为 environment.js,而您希望目标文件名为 destination_environment.js,那么您的 yaml 文件应如下所示:

    ---
            volumeMounts:
            - name: "config"
              mountPath: "/<existing folder>/destination_environment.js"
              subPath: "environment.js"
          volumes:
            - name: "config"
              configMap:
                name: "config"
    ---
    

    【讨论】:

      【解决方案5】:

      我没有投票或回复主题的声誉,所以我会在这里发帖。投票最多的答案并不像它所说的那样起作用(至少在 k8s 1.21.1 中):

                volumeMounts:
                  - mountPath: /opt/project/config.override.json
                    name: config-override
                    subPath: config.override.json
                command:
                  - ls
                  - -l
                  - /opt/project/config.override.json
      

      产生一个空目录/opt/project/config.override.json。 我已经在文档和谷歌中挖掘了几个小时,但仍然无法将这个单个 json 文件挂载为 json 文件。

      我也试过这个:

                volumeMounts:
                  - mountPath: /opt/project/
                    name: config-override
                    subPath: config.override.json
                command:
                  - ls
                  - -l
                  - /opt/project
      

      很明显,它将/opt/project 列为空目录,因为它试图将 json 文件挂载到它。在这种情况下不会创建名为 config.override.json 的文件。

      PS:挂载到文件的唯一方法是:

                volumeMounts:
                  - mountPath: /opt/project/override
                    name: config-override
                command:
                  - ls
                  - -l
                  - /opt/project/override
      

      它会创建一个目录/opt/project/override 并将在 configMap 创建中使用的原始文件名符号链接到所需的内容:

      lrwxrwxrwx 1 root root 27 Jun 27 14:37 config.override.json -> ..data/config.override.json
      

      【讨论】:

      • 今天也发生在我身上。这是1.18。如果卷是配置映射,它可以工作,但不知何故,如果它是一个秘密,它就不会。你找到解决办法了吗?
      【解决方案6】:

      假设您想将新的 log4j2.xml 挂载到正在运行的部署中以增强日志记录

      # Variables
      k8s_namespace=xcs
      deployment_name=orders-service
      container_name=orders-service
      container_working_dir=/opt/orders-service
      
      # Create config map and patch deployment
      kubectl -n ${k8s_namespace} create cm log4j \
       --from-file=log4j2.xml=./log4j2.xml
      
      kubectl -n ${k8s_namespace} patch deployment ${deployment_name} \
       -p '{"spec":{"template":{"spec":{"volumes":[{"configMap":{"defaultMode": 420,"name": "log4j"},"name": "log4j"}]}}}}'
      
      kubectl -n ${k8s_namespace} patch deployment ${deployment_name} \
       -p '{"spec":{"template":{"spec":{"containers":[{"name": "'${container_name}'","volumeMounts": [{  "mountPath": "'${container_working_dir}'/log4j2.xml","name": "log4j","subPath": "log4j2.xml"}]}]}}}}'
      
      

      【讨论】:

        猜你喜欢
        • 2020-08-26
        • 1970-01-01
        • 2020-01-26
        • 2016-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多