我很好奇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脚本作为其打印环境值的入口点。
firstContainer
和thirdContainer
能够正确打印所有ConfigMap值,这意味着所有value
,gs://bucket-name/
和/data
都将作为输入参数接收
但是,secondContainer
无法正确打印这些值。我试图回显接收到的参数,结果却收到了:
${BUCKET_NAME}
,${OUTPUT_DATA}
和${key}
作为输入 参数,而不是ConfigMaps中的实际值。
因此,在观察了上述行为之后,这是我的问题:
部署和ConfigMap之间是什么关系?在那儿
${}
和$()
有什么区别?将${}
用于入口点不同于bash
或sh
的容器时,为什么将ConfigMap值作为文字字符串接收?
谢谢。您的帮助将不胜感激。
答案 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不会在花括号中扩展内容,也没有外壳或其他任何东西可以扩展这些变量,因此变量字符串(而不是其内容)会照原样传递。