我创建了两个Spring Boot应用程序,它们都将部署在Kubernetes集群中。这些应用程序之一将充当网关,因此将Spring Cloud Gateway用作依赖项。另外,我想将服务发现与Spring Cloud Kubernetes集成在一起,并且网关使用服务发现来自动生成相应的路由。但是,当我公开运行在本地Minikube集群中的网关应用程序并调用第二个应用程序/服务时,出现以下错误消息:Unable to find instance for ...-service
当前我已安装以下内容:
我创建了一个具有两个子项目(网关和另一个服务)的Gradle项目。所有项目都将在本地构建/部署。默认服务帐户有权读取Kubernetes API。部署这些服务后,我将从外部公开网关服务。在网关服务中,我实现了一些端点,
一切似乎都正常,但是当我用URI/serviceId
调用其他服务时,我收到503错误...
使用以下Spring Cloud版本: spring-cloud-starter-kubernetes 1.0.1。发布 spring-cloud-starter-gateway 2.1.1。发布
我的演示应用程序可以在https://github.com/nmaoez/spring-cloud-gateway-kubernetes上使用,README.md提供了将两个服务都部署在本地Minikube群集中的步骤。还显示了所有可用的端点。但是有趣的是网关的application.yaml和应用程序类。
application.yaml:
spring:
application:
name: gateway-service
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
management:
endpoints:
web:
exposure:
include: '*'
GatewayApplication.java
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class GatewayApplication {
@Autowired
RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/")
@ResponseBody
public String hello() {
return "GatewayApplication says hello!";
}
@GetMapping("/test")
@ResponseBody
public String invokeTestService() {
List<ServiceInstance> testServiceInstances = this.discoveryClient.getInstances("test-service");
return restTemplate.getForObject(testServiceInstances.get(0).getUri(), String.class);
}
@GetMapping("/services")
public List<String> services() {
return this.discoveryClient.getServices();
}
@GetMapping("/services/{serviceId}")
public List<ServiceInstance> servicesById(@PathVariable("serviceId") String serviceId) {
return this.discoveryClient.getInstances(serviceId);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
在将gateway-service / application.yaml中的url-expression字段改写为
后,我得到了一些运行方式的信息url-expression: "uri+'/'"
此后,我调用gateway-uri/another-service/
后得到了正确的响应。但我希望不明确替换默认的lb://serviceid
。我该怎么办?
我希望,如果我通过网关在集群中调用另一个服务,那么我将在应用程序的其余控制器中得到200响应和正确答案。
答案 0 :(得分:1)
我刚刚使用 Spring Cloud Gateway 和 Kubernetes 实现了一个示例应用程序,它在 Docker 桌面中的作用就像一个魅力。并且不需要额外或有趣的配置。
如果有帮助,这就是我的build.gradle
:
plugins {
id 'org.springframework.boot' version '2.4.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.1.0-SNAPSHOT'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
ext {
set('springCloudVersion', "2020.0.0")
set('springCloudKubernetesVersion', '1.1.7.RELEASE')
set('springCloudVersion', '2020.0.0')
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation "org.springframework.cloud:spring-cloud-starter-kubernetes:$springCloudKubernetesVersion"
implementation "org.springframework.cloud:spring-cloud-starter-kubernetes-config:$springCloudKubernetesVersion"
implementation "org.springframework.cloud:spring-cloud-starter-kubernetes-ribbon:$springCloudKubernetesVersion"
implementation "org.springframework.cloud:spring-cloud-starter-kubernetes-loadbalancer:$springCloudKubernetesVersion"
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion"
}
}
test {
useJUnitPlatform()
}
这是来自 application.yaml
的配置:
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
最后,DiscoveryClient
在应用中启用:
@SpringBootApplication
@EnableDiscoveryClient // So services can be discovered
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
请注意,正如 Jakub Kubrynski 所说,您必须包含 Ribbon 依赖项。
还要注意路由仅在网关部署到 K8s 集群时才有效。在它之外,它可以看到 K8s 服务,但无法路由到它们,因为它们使用的是 K8s 网络中的 IP 地址。
答案 1 :(得分:0)
您还必须将依赖项添加到spring-cloud-starter-kubernetes-ribbon
。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
然后它就可以工作,而无需进行任何重写,只需使用spring.cloud.gateway.discovery.locator.enabled: true