K8s配置ConfigMap环境变量时如何正确引用Service/Pod
Docker到K8s迁移的服务访问配置问题
原有部署逻辑
在传统虚拟机Docker部署场景下,通常运行2个Docker容器:
- 1个代理节点服务
- 1个业务服务,通过.env文件配置调用代理容器
原环境获取代理容器IP的执行命令:
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' proxy-container
命令执行返回的IP地址示例:
172.17.0.2
获取IP后,在.env文件中完成如下配置:
URL=ws://172.17.0.2:4000/
迁移遇到的问题
迁移到K8s集群后,尝试沿用原有配置逻辑引用proxy-service始终失败,先后尝试使用proxy-service对应的Pod名称、Service名称配置均未生效。当前编写的env-configmap.yaml配置文件内容如下:
apiVersion: v1 kind: ConfigMap metadata: name: env-config data: URL: "ws://$(proxy-service):4000/"
正确配置方案
K8s集群内置CoreDNS组件实现服务发现,完全不需要手动查询Pod IP做硬编码配置,Pod IP会随Pod重建动态变化,原Docker场景下查IP写配置的逻辑不适用于K8s,按以下步骤调整即可:
- 前置检查
- 确认代理服务已经创建了对应ClusterIP类型的Service(同集群内访问用ClusterIP即可,不需要NodePort/LoadBalancer)
- 确认Service配置的端口、targetPort和代理容器实际监听的4000端口匹配,Service的selector标签能正确匹配到代理Pod
- 修正ConfigMap配置
ConfigMap不会自动解析$(xxx)格式的变量,同命名空间下的服务可以直接通过Service名称做DNS解析,直接去掉无效的$()包裹即可:
apiVersion: v1 kind: ConfigMap metadata: name: env-config data: URL: "ws://proxy-service:4000/"
如果代理服务和业务服务不在同一个命名空间,地址需要写全集群域名格式:ws://proxy-service.<代理服务所在命名空间名>.svc.cluster.local:4000/
3. 配置引用方式
业务负载可以通过两种方式使用该配置:
- 方式一:通过
envFrom直接把ConfigMap内容注入为容器环境变量,Deployment配置片段示例:
containers: - name: business-service image: 你的业务镜像地址 envFrom: - configMapRef: name: env-config
- 方式二:如果业务服务强依赖本地
.env配置文件,可以把ConfigMap挂载为容器内的.env文件,Deployment配置片段示例:
containers: - name: business-service image: 你的业务镜像地址 volumeMounts: - name: env-file mountPath: /app/.env # 替换为你业务服务读取.env的实际路径 subPath: .env volumes: - name: env-file configMap: name: env-config items: - key: URL path: .env
- 连通性排查
配置完成后如果访问异常,可进入业务容器执行网络测试,确认DNS解析和连通性正常,优先检查Service标签匹配、端口映射是否配置错误。
内容的提问来源于stack exchange,提问作者Matt - Block-Farms.io
相关产品推荐
相关产品推荐

