部署和ConfigMap之间是什么关系?

时间:2019-03-06 06:36:17

标签: bash shell docker kubernetes google-kubernetes-engine

我很好奇ConfigMap和Deployment在Kubernetes中的工作方式。

我想使用ConfigMap中的值作为部署容器的参数。我用不同的图像进行了尝试,并在使用sh作为入口点和其他命令作为入口点的容器之间传递ConfigMap值作为命令参数时发现了不同的行为。

下面是一个示例配置,可以更好地说明我的情况:

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-envs
data:
  key: "value"
  BUCKET_NAME: "gs://bucket-name/"
  OUTPUT_PATH: "/data"

deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
spec:
  template:
    containers:
    - name: firstContainer
      image: busybox
      command: ["sh"]
      args: 
      - c
      - |
        echo $key
        echo ${BUCKET_NAME}
        echo $(OUTPUT_PATH)
      envFrom:
      - configMapRef:
          name: app-envs
    - name: secondContainer
      image: someImage
      args: [ "cmd", "${BUCKET_NAME}", "${OUTPUT_DATA}", "${key}" ] 
      envFrom:
      - configMapRef:
          name: app-envs
    - name: thirdContainer
      image: someImage
      args: [ "cmd", "$(BUCKET_NAME)", "$(OUTPUT_DATA)", "$(key)" ] 
      envFrom:
      - configMapRef:
          name: app-envs

someImage是一个docker映像,具有某些bash脚本作为其打印环境值的入口点。


firstContainerthirdContainer能够正确打印所有ConfigMap值,这意味着所有valuegs://bucket-name//data都将作为输入参数接收

但是,secondContainer无法正确打印这些值。我试图回显接收到的参数,结果却收到了:

  

${BUCKET_NAME}${OUTPUT_DATA}${key}作为输入   参数,而不是ConfigMaps中的实际值。

因此,在观察了上述行为之后,这是我的问题:

  1. 部署和ConfigMap之间是什么关系?在那儿

  2. 某种指定在k8s吊舱/部署中如何创建资源的命令(例如,是否先加载ConfigMap,然后加载volumeMounts,然后再加载容器)?

  3. ${}$()有什么区别?将${}用于入口点不同于bashsh的容器时,为什么将ConfigMap值作为文字字符串接收?

谢谢。您的帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

Kubernetes仅直接理解括号$(VAR)中的环境变量引用;参见Define a Command and Arguments for a Container中的注释。

args: [ "cmd", "$(BUCKET_NAME)", "$(OUTPUT_DATA)", "$(key)" ] 

Kubernetes本身知道什么是环境变量并进行替换,因此该容器以cmd gs://bucket-name/ /data key的形式启动。

command: ["sh"]
args: 
- c
- |
  echo $key
  echo ${BUCKET_NAME}
  echo $(OUTPUT_PATH)

Kubernetes扩展了$(OUTPUT_PATH),但不理解任何其他形式的花括号,因此其他字符串按原样发送。不过,由于您是通过外壳程序显式运行的,因此$key${BUCKET_NAME}都是标准的外壳变量扩展,因此外壳程序会扩展这些值。

args: [ "cmd", "${BUCKET_NAME}", "${OUTPUT_DATA}", "${key}" ] 

Kubernetes不会在花括号中扩展内容,也没有外壳或其他任何东西可以扩展这些变量,因此变量字符串(而不是其内容)会照原样传递。