secret或configmap对象key名称带点,env命令不显示分析
分享一个最近在排查的问题:
k8s的 secret 或 configmap 对象,如果 key 名称是带【.】的,比如【a.b.c 、db.host】这种名称,注入到POD后,使用env等命令查看不到变量名称
命令中 k=kubelet
1、srcret 对象内容
[root@test-4 1]# k describe secret mysecret
... Data ==== a.b.c: 9 bytes pass: 12 bytes user: 5 bytes
2、POD配置文件,ENV 引用 mysecret 对象。
apiVersion: v1 kind: Pod metadata: name: app spec: containers: - envFrom: - secretRef: name: mysecret - configMapRef: name: czg-configmap name: helloworld image: registry.ap-southeast-5.aliyuncs.com/czg_namespace/helloworld:v2
2、进入POD查看环境环境
[root@test-4 1]# k exec -it app sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. # env | grep 'a.b.c' #
3、开始排查
尝试使用 setenv 、export 等查看变量的命令,都不显示 'a.b.c' 这种环境变量名称。
后来以为是云厂商之间差的异,在阿里云和AWS测试,都有这个问题。
经过网上的搜索,k8s 对 'a.b.c' 这种带点的变量名称底层调用的是 【setenv】函数,
参考:https://robberphex.com/envvars-limitation/
通过此函数并不能添加或修改 shell 进程的环境变量,或者说通过setenv函数设置的环境变量只在本进程,而且是本次执行中有效。
也就是只针对 POD 中的进程有效,shell 登入POD后,看不到这种环境变量。
参考:https://blog.csdn.net/qq_41595735/article/details/90239159
4、验证
为了验证网上的结论,写了一小段 python 程序,打印当前环境变量;打成镜像部署到K8S环境中,python程序可以正常看到 'a.b.c' 环境变量。
python核心代码:
from flask import Flask import socket import os app = Flask(__name__) @app.route('/') def hello(): html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" return html.format(name=os.environ, hostname=os.getenv('a.b.c')) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)