【问题标题】:How to merge two configmaps using volume mount in kubernetes如何在 Kubernetes 中使用卷挂载合并两个配置映射
【发布时间】:2020-10-29 12:15:27
【问题描述】:

我有两个不同的配置映射 test-configmapcommon-config。我试图将它们安装在同一位置,但一个配置映射覆盖了另一个。然后我读到subPath 并没有工作。

部署.yaml

apiVersion: apps/v1beta1 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
  name: testing
spec:
  replicas: 1
  template:
    metadata:
      name: testing
      labels:
        app: testing
    spec:
      containers:
      - name: testing-container
        image: testing
        imagePullPolicy: IfNotPresent
      ports:
      - containerPort: __PORT__
      volumeMounts:
      - name: commonconfig-volume
        mountPath: /usr/src/app/config/test.config
        subPath: test.config
    volumes:
      - name: commonconfig-volume
        configMap:
          name: test-configmap
      - name: commonconfig-volume
        configMap:
          name: common-config

错误:

The Deployment "testing" is invalid: spec.template.spec.volumes[1].name: Duplicate value: "commonconfig-volume"

我不确定是否可以合并两个配置映射。如果是,那我该怎么做。

【问题讨论】:

  • 下次添加您提到的配置图的内容,以便对人们更有意义

标签: deployment kubernetes


【解决方案1】:

您必须使用特殊的projected 卷来实现这一点。部署示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: testing
spec:
  replicas: 1
  selector:
    matchLabels:
      app: testing
  template:
    metadata:
      name: testing
      labels:
        app: testing
    spec:
      containers:
      - name: testing-container
        image: testing
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: __PORT__
        volumeMounts:
        - name: commonconfig-volume
          mountPath: /usr/src/app/config
      volumes:
        - name: commonconfig-volume
          projected:
            sources:
            - configMap:
                name: test-configmap
            - configMap:
                name: common-config

你可以使用secretconfigMap一样

【讨论】:

  • 它是自 kubernetes 1.12 以来的测试版功能,供其他阅读本文的人使用。
【解决方案2】:

您不能将两个 ConfigMap 挂载到同一个位置。

但是为每个配置映射中的每个项目提及subPathkey 将使您可以从同一位置的两个配置映射中获取项目。您必须手动为每个文件编写挂载点:

apiVersion: v1
kind: Pod
metadata:
  name: config-single-file-volume-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "cat /etc/special-key" ]
      volumeMounts:
      - name: config-volume-1
        mountPath: /etc/special-key1
        subPath: path/to/special-key1
      - name: config-volume-2
        mountPath: /etc/special-key2
        subPath: path/to/special-key2
  volumes:
    - name: config-volume-1
      configMap:
        name: test-configmap1
        items:
        - key: data-1
          path: path/to/special-key1
    - name: config-volume-2
      configMap:
        name: test-configmap2
        items:
        - key: data-2
          path: path/to/special-key2
restartPolicy: Never

另一种方法是将它们挂载在同一目录下,但子路径不同,这样您就不必手动指定项目。但是,这里每个 configmap 的键将被放入两个不同的目录中:

apiVersion: v1
kind: Pod
metadata:
  name: config-single-file-volume-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "cat /etc/special-key" ]
      volumeMounts:
      - name: config-volume-1
        mountPath: /etc/special-keys
        subPath: cm1
      - name: config-volume-2
        mountPath: /etc/special-keys
        subPath: cm2
  volumes:
    - name: config-volume-1
      configMap:
        name: test-configmap1
    - name: config-volume-2
      configMap:
        name: test-configmap2
restartPolicy: Never

cm1cm2 将是两个目录,分别包含从 test-configmap1test-configmap2 中的键派生的文件。

【讨论】:

  • 我猜在第一个例子中,为了回答这个问题,volumeMounts.[].mountPath 的值应该相同但子路径不同?
  • 确保您的文件中没有注释掉的行(# something),因为由于某种原因,这会使双卷安装失败。请将其添加到您的答案中。
【解决方案3】:

注意:如果您在 configmap 中的数据量较少,这种方法很好

假设您有两个配置映射

测试配置图

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-configmap
data:
  test-1.conf: |
    test-property-1=test-value-1

common-confimap

apiVersion: v1
kind: ConfigMap
metadata:
  name: common-configmap
data:
  common-1.conf: |
    common-property-1=common-value-1

您可以在单个 configmap 中拥有相同的数据,而不是使用不同的 configmap,如下所示。

apiVersion: v1
kind: ConfigMap
metadata:
  name: single-configmap
data:
  common-1.conf: |
    property-1=value-1
  test-1.conf: |
    property-1=value-1

现在从上面的 configmap 创建一个卷并使用 mounhPath 挂载到容器,如下所示

来自 configmap 的音量

volumes:
- configMap:
    defaultMode: 420
    name: single-cofigmap
  name: my-single-config

volumeMount

volumeMounts:
- mountPath: /path/to/config/folder/
  name: my-single-config

现在您可以在容器内的/path/to/config/folder/ 位置看到两个文件。告诉您的应用程序使用它需要的那个。

【讨论】:

  • 谢谢。我试图弄清楚如何将卷和volumeMounts 堆叠太久。只是输出多个数据元素是有意义的......现在。
【解决方案4】:

另一个例子说明如何安装多个配置映射。对于 nginx 坞站,这是否要同时替换主 /etc/nginx/nginx.conf 和 /etc/nginx/conn.f 中的文件。这也会删除 conf.d 中的 default.conf 文件

 containers:
    - name: nginx-proxy
      image: nginx:1.16-alpine
      imagePullPolicy: Always
      ports:
        - containerPort: 443
        - containerPort: 80
      volumeMounts:
        - name: nginx-main-conf-file
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        - name: nginx-site-conf-file
          mountPath: /etc/nginx/conf.d
  volumes:
    - name: nginx-main-conf-file
      configMap:
        name: nginx-main-conf
    - name: nginx-site-conf-file
      configMap:
        name: nginx-site-conf

还有一点非常重要。如果您的 yaml 文件中有任何注释掉的行(# something),那么这将不起作用。这是一个错误。在 kubectl v1.14 中测试

【讨论】:

    【解决方案5】:

    一种方法是将它们安装在不同的点但在同一个 emptyDir 卷中,将相同的卷安装到 init container 并在 init 容器中包含一个简短的脚本,以使用您安装的任何工具合并这两个文件在脚本的开头。使用this 答案中的技术可以轻松地将脚本包含在 pod 清单中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-19
      • 2021-06-25
      • 2018-12-02
      • 2020-03-17
      • 2023-03-18
      • 2018-08-23
      • 2020-08-07
      • 2018-12-12
      相关资源
      最近更新 更多