Kubernetes Job与Pod中脚本/命令无法读取环境变量的问题
为什么K8s容器里的环境变量在echo命令中为空?
我最近碰到个挺头疼的问题:在Kubernetes里创建Job或者Pod时,明明已经配置了环境变量,env命令能正常输出变量值,但用echo "MY_VAR : ${MY_VAR}"却输出空值。
先看我测试的Job配置:
kubectl apply -f - <<EOF apiVersion: batch/v1 kind: Job metadata: name: sample spec: template: spec: containers: - command: - /bin/bash - -c - | env echo "MY_VAR : ${MY_VAR}" sleep 800000 env: - name: MY_VAR value: MY_VALUE image: mcr.microsoft.com/azure-cli:2.0.80 imagePullPolicy: IfNotPresent name: sample restartPolicy: Never backoffLimit: 4 EOF
查看日志时发现:
$ kubectl logs -f sample-7p6bp ... MY_VAR=MY_VALUE ... MY_VAR :
后来我用简单Pod做了同样测试:
kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: sample spec: containers: - name: sample imagePullPolicy: Always command: ["/bin/sh", "-c", "echo BEGIN ${MY_VAR} END"] image: radial/busyboxplus:curl env: - name: MY_VAR value: MY_VALUE EOF
日志结果还是空的:
$ kubectl logs -f sample BEGIN END
问题根源
这其实是变量替换时机搞的鬼:
当你在本地终端用<<EOF的 heredoc 语法写YAML时,本地的shell会先解析里面的${MY_VAR}变量。如果你的本地环境里没有设置MY_VAR,这个变量就会被替换成空字符串,然后才把替换后的内容传给Kubernetes。容器最终拿到的命令已经是echo "MY_VAR : "或者echo BEGIN END,自然输出空值。
解决方法
有两种简单的办法可以避免本地shell解析容器里的变量:
1. 使用单引号包裹heredoc结束符
把<<EOF改成<<'EOF',这样本地shell会把整个heredoc内容原封不动地传递,不会解析里面的变量,让容器内部的shell来处理${MY_VAR}:
kubectl apply -f - <<'EOF' apiVersion: batch/v1 kind: Job metadata: name: sample spec: template: spec: containers: - command: - /bin/bash - -c - | env echo "MY_VAR : ${MY_VAR}" sleep 800000 env: - name: MY_VAR value: MY_VALUE image: mcr.microsoft.com/azure-cli:2.0.80 imagePullPolicy: IfNotPresent name: sample restartPolicy: Never backoffLimit: 4 EOF
2. 转义变量中的$符号
在${MY_VAR}前加反斜杠,写成\${MY_VAR},这样本地shell会把\$当成普通字符,传递给容器后恢复成${MY_VAR},由容器内部shell解析:
kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: sample spec: containers: - name: sample imagePullPolicy: Always command: ["/bin/sh", "-c", "echo BEGIN \${MY_VAR} END"] image: radial/busyboxplus:curl env: - name: MY_VAR value: MY_VALUE EOF
或者也可以用单引号包裹整个命令字符串,这样本地shell也不会解析里面的变量:
command: ["/bin/sh", "-c", 'echo BEGIN ${MY_VAR} END']
这样修改后,容器里的echo命令就能正确输出环境变量的值了。
内容的提问来源于stack exchange,提问作者u123
相关产品推荐
相关产品推荐

