环境变量是怎么被注入的
Pod 创建时,kubelet 会为「在该 Pod 之前已经存在」的 Service 注入一组环境变量:形如大写服务名加下划线再加 SERVICE_HOST 与 SERVICE_PORT,分别指向该 Service 的虚拟 IP 与端口。这套机制比 DNS 方案更早,如今主要作为兼容手段存在。应用如果已经知道服务名,用 DNS 名称访问更可靠:DNS 记录随 Service 重建更新,而注入的变量只是创建那一刻的快照。
基本信息
| 适用平台 | 各版本 Pod 的创建过程 |
|---|---|
| 注入内容 | 大写服务名加后缀的 HOST 与 PORT 变量 |
| 生效时机 | Pod 创建时读取,Service 必须已存在 |
| 跨命名空间 | 不注入,需使用完整 DNS 名称 |
| 命名转换 | 服务名含连字符时转为下划线并整体大写 |
典型使用场景
- 遗留应用兼容:老代码习惯读取这类变量,不改代码即可迁移
- 快速排查:在容器里查看变量确认服务地址是否符合预期
- 理解部署顺序:解释为什么后创建的服务在已运行 Pod 里看不到
- 命名核对:确认带连字符的服务名对应的变量名怎么写
- 迁移评估:把变量访问逐步替换为 DNS 访问
查看注入结果
查看注入结果
kubectl exec -it web-x -n prod -- env | grep -i SERVICE
kubectl exec -it web-x -n prod -- env | grep -i KUBERNETES_SERVICE_HOST # 集群内部服务变量
kubectl get svc web -n prod -o jsonpath='{.spec.clusterIP}{"\n"}'
kubectl get svc -n prod # 对照实际存在的服务常见变量形态
| 变量形态 | 含义 | 示例 |
|---|---|---|
| 服务名_HOST | 服务虚拟 IP | WEB_SERVICE_HOST |
| 服务名_PORT | 服务端口 | WEB_SERVICE_PORT |
| 服务名_PORT_端口_TCP | 按端口细分的地址变量 | WEB_SERVICE_PORT_80_TCP |
| 连字符转换 | 连字符转下划线并大写 | web-api 变成 WEB_API |
注入是创建时的快照:如果 Service 在 Pod 启动之后才创建,变量不会补进已经运行的 Pod,这是「部署顺序不同结果不同」这类偶发问题的典型来源。
跨命名空间的 Service 不会被注入:跨命名空间访问应始终使用完整 DNS 名称,不要指望变量存在。
命名空间里的 Service 一多,这类变量会成倍增加并占满进程环境:服务数量大的集群里,改用 DNS 访问也能顺带减少环境变量的体积。