Deployment 如何在kubernetes中使用卷装载合并两个ConfigMap

Deployment 如何在kubernetes中使用卷装载合并两个ConfigMap,deployment,kubernetes,Deployment,Kubernetes,我有两个不同的配置映射测试配置映射和公共配置。我试图在同一个位置挂载它们,但一个配置映射重写了另一个。然后我读到了子路径,但不起作用 deploy.yaml apiVersion: apps/v1beta1 # for versions before 1.8.0 use apps/v1beta1 kind: Deployment metadata: name: testing spec: replicas: 1 template: metadata: name:

我有两个不同的配置映射测试配置映射公共配置。我试图在同一个位置挂载它们,但一个配置映射重写了另一个。然后我读到了
子路径
,但不起作用

deploy.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
错误:

部署“测试”无效:spec.template.spec.volumes[1]。名称:重复值:“commonconfig volume”


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

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

但是为每个configmaps中的每个项目提及
子路径
,将允许您从同一位置的两个configmaps中获取项目。您必须手动为每个文件写入装入点:

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

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

一种方法是将它们安装在不同的点,但安装在相同的
emptyDir
卷中,将同一个卷装载到中,并在init容器中包含一个短脚本,以使用在脚本开始时安装的任何工具合并两个文件。使用回答中的技巧,脚本可以很容易地包含在pod清单中。

您必须使用特殊卷才能实现这一点。部署示例:

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

您可以使用
secret
configMap

相同的另一个示例来说明如何装载多个configMap。对于nginx dock,您希望替换/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文件中有任何未注释的行(#某物),那么这将不起作用。这是一只虫子。在kubectl v1.14中进行了测试。

注意:如果configmaps中的数据量较少,则此方法很好

假设您有两个配置映射

测试确认图

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-configmap
data:
  test-1.conf: |
    test-property-1=test-value-1
apiVersion: v1
kind: ConfigMap
metadata:
  name: common-configmap
data:
  common-1.conf: |
    common-property-1=common-value-1
volumes:
- configMap:
    defaultMode: 420
    name: single-cofigmap
  name: my-single-config
通用confimap

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-configmap
data:
  test-1.conf: |
    test-property-1=test-value-1
apiVersion: v1
kind: ConfigMap
metadata:
  name: common-configmap
data:
  common-1.conf: |
    common-property-1=common-value-1
volumes:
- configMap:
    defaultMode: 420
    name: single-cofigmap
  name: my-single-config
您可以在单个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的卷

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-configmap
data:
  test-1.conf: |
    test-property-1=test-value-1
apiVersion: v1
kind: ConfigMap
metadata:
  name: common-configmap
data:
  common-1.conf: |
    common-property-1=common-value-1
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.[]。mountPath
值应该相同,但子路径不同?确保你的文件中没有注释外的行(#某物),因为出于某种原因会导致双volumeMounts失败。请将此添加到您的答案中。这是自kubernetes 1.12以来的测试版功能,供其他阅读本文的人使用。