Kubernetes环境下Spring Cloud Gateway无法注册到Eureka Server问题
部署2个Spring Boot微服务(Eureka Server、Spring Cloud Gateway)到K8s集群时,Gateway无法成功注册到Eureka Server,注册过程抛出域名无法解析的错误。
现有配置
1. K8s Eureka 部署配置(eureka.yml)
apiVersion: v1 kind: ConfigMap metadata: name: eureka-cm data: eureka_service_address: http://eureka-0.eureka:8761/eureka --- apiVersion: v1 kind: Service metadata: name: eureka labels: app: eureka spec: clusterIP: None ports: - port: 8761 name: eureka selector: app: eureka --- apiVersion: apps/v1 kind: StatefulSet metadata: name: eureka spec: serviceName: "eureka" replicas: 1 selector: matchLabels: app: eureka template: metadata: labels: app: eureka spec: containers: - name: eureka image: myrepo/eureka1.0:eureka imagePullPolicy: Always ports: - containerPort: 8761 env: - name: EUREKA_SERVER_ADDRESS valueFrom: configMapKeyRef: name: eureka-cm key: eureka_service_address --- apiVersion: v1 kind: Service metadata: name: eureka-lb labels: app: eureka spec: selector: app: eureka type: NodePort ports: - port: 80 targetPort: 8761
2. Eureka 应用配置(application.yml)
spring: application: name: eureka server: port: 8761 eureka: instance: hostname: "${HOSTNAME}.eureka" client: register-with-eureka: false fetch-registry: false serviceUrl: defaultZone: ${EUREKA_SERVER_ADDRESS}
3. K8s Gateway 部署配置(gateway.yml)
apiVersion: apps/v1 kind: Deployment metadata: name: cloud-gateway-app labels: app: cloud-gateway-app spec: replicas: 1 selector: matchLabels: app: cloud-gateway-app template: metadata: labels: app: cloud-gateway-app spec: containers: - name: cloud-gateway-app image: myrepo/gateway1.0:gateway imagePullPolicy: Always ports: - containerPort: 9191 --- apiVersion: v1 kind: Service metadata: name: cloud-gateway-svc spec: type: LoadBalancer ports: - port: 80 targetPort: 9191 protocol: TCP selector: app: cloud-gateway-app
4. Gateway 应用配置(application.yml)
eureka: instance: preferIpAddress: true hostname: eureka-0 client: registerWithEureka: true fetchRegistry: true serviceUrl: defaultZone: http://eureka-0.eureka.default.svc.cluster.local:8761/eureka
报错信息
Gateway Pod 启动时抛出如下域名解析错误:
error on POST request for "http://eureka-0.eureka.default.svc.cluster.local:8761/eureka/apps/API-GATEWAY": eureka-0.eureka.default.svc.cluster.local; nested exception is java.net.UnknownHostException: eureka-0.eureka.default.svc.cluster.local
尝试将defaultZone改为固定Pod域名格式172-17-0-3.default.pod.cluster.local:8761/eureka后依然注册失败。
问题核心是K8s集群的DNS解析配置与Eureka客户端注册地址不匹配,按以下步骤修改即可解决:
修正Gateway的Eureka注册地址
你当前Eureka部署在default命名空间下,不需要硬编码Pod域名(Pod重启后IP和域名都会变化,硬编码必然不稳定),直接使用K8s Service域名即可。首先删掉Gateway配置里错误的hostname: eureka-0配置(该配置是Eureka Pod的主机名,不属于Gateway实例),再将defaultZone改为:eureka: instance: preferIpAddress: true client: registerWithEureka: true fetchRegistry: true serviceUrl: defaultZone: http://eureka.default.svc.cluster.local:8761/eureka如果Gateway和Eureka部署在同一个命名空间,还可以简化为
http://eureka:8761/eureka,K8s DNS会自动解析到对应的Headless Service,转发到后端Eureka Pod。检查K8s集群CoreDNS运行状态
如果改完地址还是报UnknownHostException,进入任意一个业务Pod执行nslookup测试域名解析:nslookup eureka.default.svc.cluster.local如果解析失败,说明CoreDNS组件异常,或者集群Pod的DNS配置有误,需要先修复CoreDNS,保证同集群内Pod可以正常解析Service域名。
修正Eureka实例IP注册配置
如果域名能连通但依然注册失败,给Eureka和Gateway都加上Pod IP注入配置,保证注册到Eureka的是集群内可达的Pod IP:
首先在应用的application.yml中添加配置:eureka: instance: prefer-ip-address: true ip-address: ${HOST_IP:}再在对应的Deployment/StatefulSet容器配置中,注入Pod IP到环境变量:
env: - name: HOST_IP valueFrom: fieldRef: fieldPath: status.podIP避免服务拿到Docker内部网桥的不可达IP,导致后续服务调用失败。
验证网络连通性
配置修改完成后,进入Gateway Pod执行curl命令测试Eureka接口可达性:curl http://eureka:8761/eureka/info如果能正常返回Eureka的响应信息,说明网络链路通畅,重启Gateway即可自动完成服务注册。
内容的提问来源于stack exchange,提问作者Pickeroll

