You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

无服务注册中心时,Spring Cloud Gateway在K8s中路由至指定服务

在Kubernetes环境中用Spring Cloud Gateway实现无注册中心的服务路由

针对你升级Spring Cloud Gateway后遇到的服务路由问题,结合你的技术栈版本(Spring Boot 3.3.2、Spring Cloud 2023.0.3、Spring Cloud Kubernetes 1.1.10.RELEASE),可以通过以下步骤解决:

一、调整依赖配置

需确保引入Kubernetes服务发现与负载均衡的适配依赖,这是实现lb://serviceId路由的核心:

Maven依赖(pom.xml)

<dependencies>
    <!-- Spring Cloud Gateway核心 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!-- Spring Cloud LoadBalancer核心 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    <!-- Kubernetes服务发现 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-kubernetes-discovery</artifactId>
    </dependency>
    <!-- LoadBalancer与Kubernetes发现的适配 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-kubernetes-loadbalancer</artifactId>
    </dependency>
</dependencies>

Gradle依赖(build.gradle)

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'
    implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-discovery'
    implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-loadbalancer'
}

二、修正配置文件

调整application.yaml,启用Kubernetes服务发现与负载均衡适配,解决discovery-server-url报错及服务实例找不到的问题:

spring:
  cloud:
    # Gateway路由配置
    gateway:
      routes:
        - id: your-service-route
          # 使用lb://+K8s Service名称作为路由目标
          uri: lb://your-service-id
          predicates:
            - Path=/your-service/**
    # Kubernetes服务发现配置
    kubernetes:
      discovery:
        enabled: true
        # 仅发现带有指定标签的K8s Service(和原Zuul配置一致)
        service-labels:
          discovery: enabled
        # 集群内部运行时无需手动指定discovery-server-url,会自动调用K8s内部API
        # 若在外部环境测试,可添加:discovery-server-url: https://kubernetes.default.svc:443
      # 启用Kubernetes适配的LoadBalancer
      loadbalancer:
        enabled: true
        kubernetes:
          enabled: true
    # 禁用自动注册到外部服务注册中心(和原Zuul配置一致)
    service-registry:
      auto-registration:
        enabled: false

关键说明:

  • 之前启动报错需指定discovery-server-url,是因为缺少spring-cloud-starter-kubernetes-loadbalancer依赖,导致Kubernetes发现组件无法自动适配集群内部API地址;
  • 启用spring.cloud.kubernetes.loadbalancer.enabled后,LoadBalancer会通过Kubernetes API获取Service的Endpoints,实现客户端侧负载均衡。

三、验证ServiceAccount权限

确保网关Pod绑定的ServiceAccount具备访问Kubernetes服务、端点的权限,创建RBAC规则:

# 定义ClusterRole,授予服务发现所需权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: gateway-discovery-role
rules:
  - apiGroups: [""]
    resources: ["services", "endpoints", "pods"]
    verbs: ["get", "list", "watch"]
---
# 绑定ClusterRole到网关的ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gateway-discovery-binding
subjects:
  - kind: ServiceAccount
    name: gateway-sa
    namespace: your-namespace # 替换为网关所在命名空间
roleRef:
  kind: ClusterRole
  name: gateway-discovery-role
  apiGroup: rbac.authorization.k8s.io

在网关的Deployment中指定ServiceAccount:

spec:
  serviceAccountName: gateway-sa

四、测试路由

启动网关Pod后,可通过以下方式验证:

  1. 查看网关日志,确认是否成功获取到目标Service的Endpoints;
  2. 发送测试请求:curl http://<gateway-ip>/your-service/<api-path>,检查是否能正确转发到目标服务。

补充:服务自动注册配置

若需实现服务自动注册到Kubernetes(替代外部注册中心),可添加以下配置:

spring:
  cloud:
    kubernetes:
      registration:
        enabled: true
        # 自定义注册的Service名称(可选,默认用spring.application.name)
        service-name: your-gateway-service
        # 暴露的端口
        ports:
          - name: http
            port: 8080
            target-port: 8080

内容的提问来源于stack exchange,提问作者Istvan Kiss

火山引擎 最新活动