Spring Cloud Kubernetes + Spring Cloud Gateway: невозможно найти экземпляр для службы k8s
Я использую Spring Cloud Kubernetes + Spring Cloud Gateway(SCG), и у меня возникли проблемы с развертыванием моего приложения в GKE. SCG не находит сервис k8s, я все еще получаю эту ошибку:
There was an unexpected error (type=Service Unavailable, status=503).
Unable to find instance for uiservice
uiservice
это угловое приложение.
Когда я смотрю на .../actuator/gateway/routes
У меня есть этот результат:
[
{
"route_id": "CompositeDiscoveryClient_gateway",
"route_definition": {
"id": "CompositeDiscoveryClient_gateway",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/gateway/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"regexp": "/gateway/(?<remaining>.*)",
"replacement": "/${remaining}"
}
}
],
"uri": "lb://gateway",
"order": 0
},
"order": 0
},
{
"route_id": "CompositeDiscoveryClient_uiservice",
"route_definition": {
"id": "CompositeDiscoveryClient_uiservice",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/uiservice/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"regexp": "/uiservice/(?<remaining>.*)",
"replacement": "/${remaining}"
}
}
],
"uri": "lb://uiservice",
"order": 0
},
"order": 0
},
{
"route_id": "uiservice_route",
"route_definition": {
"id": "uiservice_route",
"predicates": [
{
"name": "Path",
"args": {
"_genkey_0": "/*"
}
}
],
"filters": [],
"uri": "lb://uiservice",
"order": 0
},
"order": 0
},
....
]
Обратите внимание, что услуги хорошо открыты из-за этого: "route_id": "CompositeDiscoveryClient_gateway"
а также "route_id": "CompositeDiscoveryClient_uiservice"
эти маршруты не мои (я их не определил).
Я взглянул на этот пост: как настроить приложение Spring Cloud Gateway, чтобы оно могло использовать Service Discovery в Spring Cloud Kubernetes? безуспешно.
Моя конфигурация:
spring:
profiles:
active: prod
cloud:
kubernetes:
reload:
enabled: true
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: uiservice
allowedMethods: "*"
allowCredentials: true
maxAge: 7200
allowedHeaders: "*"
exposedHeaders:
- "Access-Control-Allow-Origin"
- "Access-Control-Allow-Methods"
- "Access-Control-Max-Age"
- "Access-Control-Allow-Headers"
- "Cache-Control"
- "Authorization"
- "Content-Type"
routes:
#======UISERVICE========
- id: uiservice_route
uri: lb://uiservice
predicates:
- Path=/* #default route
- id: uiservice_route_assets
uri: lb://uiservice
predicates:
- Path=/assets/**
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
restart:
enabled: true
Кроме того, как я могу отключить автообнаружение шлюза? Я не хочу "route_id": "CompositeDiscoveryClient_gateway"
зависимости:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-all</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Спасибо за вашу помощь
4 ответа
Я наконец нашел решение после потери дня. Я думаю, что существует проблема с обнаружением службы при использовании ленты. Я использую обнаружение службы k8s dns вместо того, чтобы полагаться на ленту, поэтому моя новая конфигурация:
routes:
- id: uiservice_route
uri: http://uiservice:4200 # switch 'lb://' to 'http://'
predicates:
- Path=/*
Конфигурация пользовательского сервиса K8s:
apiVersion: v1
kind: Service
metadata:
name: uiservice
spec:
sessionAffinity: ClientIP
selector:
app: uiservice
ports:
- name: http
port: 4200
targetPort: ui-port
Возник новый вопрос: зачем использовать Ribbon для запросов балансировки нагрузки, поскольку сервисы k8s изначально делают это?
Установите следующее свойство
spring:
cloud:
gateway:
discovery:
locator:
enabled: false
Должно получиться так:
spring:
application.name: gateway
cloud:
gateway:
discovery:
locator:
enabled: true
url-expression: "'http://'+serviceId+':'+getPort()"
lower-case-service-id: true
Когда звоните http://gateway/my-service-name/api/etc
, а затем позвонит my-service-name/api/etc
если сервис присутствует в кубернетах
Итак, вам нужно убедиться, что у вас есть такая услуга, как:
apiVersion: v1
kind: Service
metadata:
name: my-service-name
namespace: default
labels:
app: my-service-name
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30080
selector:
app: my-service-name
Я не думаю, что вы добавили
starter-ribbon
зависимость, которая будет принимать ответ для поиска вашего экземпляра службы в среде k8s.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>