从Docker Compose迁移到Kubernetes后容器访问内部服务与WAN外部RabbitMQ问题
核心原因说明
你之前在Docker Compose中使用network_mode: host是让容器共享宿主机网络栈,因此可通过localhost访问同宿主机的其他服务,同时直接复用宿主机网络访问公网RabbitMQ。Kubernetes默认每个Pod拥有独立网络命名空间,localhost仅可访问当前Pod内的进程,而K8s Pod默认具备公网访问能力,你遇到的异常可通过以下两种极简方案解决:
方案1:零代码改动(K8s新手推荐)
将所有需要通过localhost互相访问的微服务放到同一个Pod内运行即可,K8s中同一个Pod的所有容器共享网络栈,和你之前使用Docker host网络的体验完全一致:
- 同Pod内的容器可直接用localhost加对应端口互相访问,不需要修改任何应用配置
- Pod默认使用集群网络出公网,不需要额外配置就可以直接用现有凭证连接外部RabbitMQ
操作仅需修改Deployment配置,把多个微服务的镜像定义放到同一个containers数组下即可,示例参考:
apiVersion: apps/v1 kind: Deployment metadata: name: my-service-group spec: replicas: 1 selector: matchLabels: app: my-service-group template: metadata: labels: app: my-service-group spec: containers: # 需要连接RabbitMQ的主业务容器 - name: app-container image: 你的业务应用镜像地址 env: - name: RABBITMQ_ADDR value: 外部RabbitMQ公网地址:端口 # 原有日志服务 - name: log-service image: 你的日志服务镜像地址 # 原有配置服务 - name: config-service image: 你的配置服务镜像地址 # 原有数据库服务 - name: db-service image: 你的数据库镜像地址
方案2:微服务单独部署场景(仅需修改少量应用配置)
如果你的其他微服务已经单独部署为独立的Deployment,仅需要做一处配置改动:
- 给每个内部微服务创建对应的K8s Service后,把业务应用中原本写
localhost:端口调用内部服务的地址,替换为[对应服务的Service名称]:[Service端口],K8s自带的DNS会自动完成内部服务的地址解析 - 访问外部RabbitMQ的配置不需要做任何修改,Pod默认可直接访问公网资源
补充说明
仅当你的集群管理员配置了严格的网络策略禁止Pod公网访问时,才需要联系管理员放开对应Pod访问外部RabbitMQ端口的出网规则,绝大多数默认搭建的K8s集群不需要该操作。
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

