【问题标题】:How can I mount a dynamically generated file into a pod without creating a ConfigMap?如何在不创建 ConfigMap 的情况下将动态生成的文件挂载到 pod 中?
【发布时间】:2020-04-24 11:17:05
【问题描述】:

在我的应用程序中,我有一个控制平面组件,它在我的 k8s 集群上生成作业。我希望能够将动态生成的(但只读的)配置文件传递给每个作业。每个 Job 的配置文件都不同。

一种方法是为每个新作业创建一个包含所需配置文件内容的 ConfigMap,然后在启动作业时将 ConfigMap 设置为作业规范中的 VolumeMount。但是现在我在集群中有两个实体在语义上绑定在一起但不共享生命周期,即如果 Job 结束,ConfigMap 不会自动消失。

有没有办法直接将字符串“挂载”到 Job 的 Pod 中,而无需单独创建一些支持实体(如 ConfigMap)来存储它?我想我可以将它作为环境变量传入,但由于长度限制,这似乎很脆弱。

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

    传统的做法是通过initContaineremptyDir volumeMount 允许两个容器通过私有共享磁盘“通信”:

    spec:
      initContainers:
      - name: config-gen
        image: docker.io/library/busybox:latest
        command:
        - /bin/sh
        - -ec
        # now you can use whatever magick you wish to generate the config
        - |
          echo "my-config: is-generated"   > /generated/sample.yaml
          echo "some-env: ${SOME_CONFIG}" >> /generated/sample.yaml
        env:
        - name: SOME_CONFIG
          value: subject to injection like any other kubernetes env var
        volumeMounts:
        - name: shared-space
          mountPath: /generated
      containers:
      - name: main
        image: docker.example.com:1234
        # now you can do whatever you want with the config file
        command:
        - /bin/cat
        - /config/sample.yaml
        volumeMounts:
        - name: shared-space
          mountPath: /config
      volumes:
      - name: shared-space
        emptyDir: {}
    

    【讨论】:

    • 我明白了。不幸的是,大多数配置文件是用户在控制平面级别提供的,其余部分需要访问控制平面资源(db 等)才能生成,因此在数据平面 pod 内生成它没有意义。当然,我可以使用您的示例并通过回显包含预构建配置的大型静态字符串来“生成”配置,但我想这不是您想要的,对吧?
    • 我没有遵循您提到的所有词汇或限制,但据我了解,您有一些 Job 可以访问的配置材料,但没有结构化或不可用创建的Pod 的主容器可以使用的一种方式。如果环境的大小是您唯一关心的问题,xz compressing 然后对有效负载进行 base64 编码允许initContainer 解压缩它,同时仍然使Job 自包含。这更接近你的想法吗?
    【解决方案2】:

    如果您想使用 configmaps环境变量 来传递配置,则剩下的选项是 命令行参数配置文件

    您可以将配置作为命令行参数传递给您的每个作业。

    您还可以将配置作为文件挂载到您的 Job pod 中。但是由于生成配置的控制器和使用它的 Job 可能在不同的节点上运行,因此您需要一种将配置传递给 Job pod 的方法。如果您有一个可供所有节点访问的网络附加存储,则您的控制器可以写入共享存储上的位置,而 Job 可以从中读取。否则,如果您有一个服务(数据库、缓存等) 可以像数据存储一样工作,那么您的控制器可以写入数据存储,而作业可以从那里读取。

    如果您不想修改作业以从各种来源读取配置,则可以使用 initContainer 来完成从特定来源读取配置并将其写入本地的工作pod volume(emptyDir) 和 Job 可以从本地文件中读取。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      相关资源
      最近更新 更多