已通过Vault Agent注入K8s Pod密钥,如何将其设为全局环境变量?
解决Vault注入密钥无法作为全局环境变量被应用读取的问题
问题根源
你当前的Deployment配置仅执行了source /vault/secrets/secrets,但该操作仅在当前bash进程中生效,且执行后bash直接退出,没有启动应用;即便启动应用,若不在同一个进程链中,环境变量也无法继承。
方案1:在同一Shell进程中加载变量并启动应用
将加载环境变量和启动应用的命令放在同一个bash会话中,确保变量能传递给应用进程。
- 先通过
docker inspect adouadi/python:latest查看镜像的原始启动命令(CMD或ENTRYPOINT字段),比如假设原始命令是python /app/main.py。 - 修改Deployment的容器command和args:
containers: - name: myapp image: adouadi/python:latest ports: - containerPort: 80 command: ['/bin/bash', '-c'] args: ['source /vault/secrets/secrets && exec python /app/main.py']
如果不确定原始启动命令,可以用exec "$0" "$@"来继承镜像的ENTRYPOINT/CMD:
containers: - name: myapp image: adouadi/python:latest ports: - containerPort: 80 entrypoint: ['/bin/bash', '-c'] command: ['source /vault/secrets/secrets && exec "$0" "$@"'] args: ['<镜像原始ENTRYPOINT>', '<原始CMD参数>']
方案2:直接用Vault Agent注入环境变量(推荐)
无需手动编写source脚本,利用Vault Agent Injector的环境变量映射功能,直接将Vault中的密钥转为容器环境变量,应用可直接读取。
修改Deployment的annotations部分:
metadata: annotations: vault.hashicorp.com/agent-inject: 'true' vault.hashicorp.com/role: 'internal-app' # 映射USERNAME环境变量 vault.hashicorp.com/agent-inject-secrets-username: 'internal/data/database/config' vault.hashicorp.com/agent-inject-template-username: '{{ with secret "internal/data/database/config" }}{{ .Data.data.username }}{{ end }}' vault.hashicorp.com/agent-inject-env-username: 'USERNAME' # 映射PASSWORD环境变量 vault.hashicorp.com/agent-inject-secrets-password: 'internal/data/database/config' vault.hashicorp.com/agent-inject-template-password: '{{ with secret "internal/data/database/config" }}{{ .Data.data.password }}{{ end }}' vault.hashicorp.com/agent-inject-env-password: 'PASSWORD' # 依次添加其他变量 vault.hashicorp.com/agent-inject-secrets-rootpassword: 'internal/data/database/config' vault.hashicorp.com/agent-inject-template-rootpassword: '{{ with secret "internal/data/database/config" }}{{ .Data.data.rootpassword }}{{ end }}' vault.hashicorp.com/agent-inject-env-rootpassword: 'ROOT_PASSWORD' vault.hashicorp.com/agent-inject-secrets-database: 'internal/data/database/config' vault.hashicorp.com/agent-inject-template-database: '{{ with secret "internal/data/database/config" }}{{ .Data.data.database }}{{ end }}' vault.hashicorp.com/agent-inject-env-database: 'DATABASE' vault.hashicorp.com/agent-inject-secrets-host: 'internal/data/database/config' vault.hashicorp.com/agent-inject-template-host: '{{ with secret "internal/data/database/config" }}{{ .Data.data.host }}{{ end }}' vault.hashicorp.com/agent-inject-env-host: 'HOST'
配置完成后,Vault Agent会自动将这些变量注入容器环境,应用启动后可直接通过语言内置的环境变量读取方法(如Python的os.environ.get("USERNAME"))获取值。
方案3:将环境变量脚本加入全局Shell配置
如果应用通过Shell启动,可将Vault生成的脚本链接到容器的/etc/profile.d/目录,实现Shell启动时自动加载变量。需要添加一个init容器完成链接操作:
spec: serviceAccountName: internal-app initContainers: - name: setup-vault-env image: busybox:latest command: ['sh', '-c'] args: ['ln -sf /vault/secrets/secrets /etc/profile.d/vault-env.sh'] volumeMounts: - name: vault-secrets mountPath: /vault/secrets - name: etc-profile mountPath: /etc/profile.d containers: - name: myapp image: adouadi/python:latest ports: - containerPort: 80 volumeMounts: - name: vault-secrets mountPath: /vault/secrets - name: etc-profile mountPath: /etc/profile.d volumes: - name: etc-profile emptyDir: {} - name: vault-secrets emptyDir: {}
注意:此方法仅适用于应用通过Shell启动的场景,若应用直接执行二进制文件(无Shell介入),则无法加载该配置。
内容的提问来源于stack exchange,提问作者Anis Douadi
相关产品推荐
相关产品推荐

