我正在使用Spring Cloud Gateway和Spring Cloud Kubernetes Discovery在openshift上实现API Gateway。
我从项目 https://github.com/salaboy/s1p_gateway 开始。
我的网关配置是:
cloud:
gateway:
discovery:
locator:
enabled: true
url-expression: "'http://'+serviceId+':'+port"
kubernetes:
reload:
enabled: true
mode: polling
period: 5000
discovery:
service-labels:
type: "java-api"
当我查看我的/actuator/gateway/routes 时,我可以看到发现的服务:
{
"predicate":"Paths: [/common/**], match trailing slash: true",
"route_id":"ReactiveCompositeDiscoveryClient_common",
"filters":[
"[[RewritePath /common/(?<remaining>.*) = '/${remaining}'], order = 1]"
],
"uri":"http://common:8085",
"order":0
}
问题是8085是目标端口(即 pod 端口(而不是服务端口:
kind: Service
apiVersion: v1
metadata:
name: common
namespace: p4p
selfLink: /api/v1/namespaces/myspace/services/common
uid: 1851a76f-4764-11ea-a02c-000d3aa9b693
resourceVersion: '28657990'
creationTimestamp: '2020-02-04T15:36:21Z'
labels:
app: common
type: java-api
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8085
selector:
app: common
deploymentconfig: common
clusterIP: 172.30.7.24
type: ClusterIP
sessionAffinity: None
status:
loadBalancer: {}
为了让 API 网关正常工作,我必须对齐 pod 端口和服务端口,但这听起来很奇怪。
是否正在使用功能区?功能区的默认spring.cloud.kubernetes.ribbon.mode
是 POD。来自文档(引用(:
spring.cloud.kubernetes.ribbon.mode
支持POD
和SERVICE
模式。
POD
模式是通过获取 Pod IP 来实现负载均衡 Kubernetes 的地址和使用 Ribbon。POD 模式使用负载 功能区的平衡不支持 Kubernetes 负载均衡, 不支持 Istio 的流量策略。
SERVICE
模式直接基于功能区的服务名称。 获取 Kubernetes 服务被连接成service-name.{namespace}.svc.{cluster.domain}:{port}
例如:demo1.default.svc.cluster.local:8080
.SERVICE
模式使用负载 平衡 Kubernetes 服务以支持 Istio 的流量策略。
为什么不能简单地将Service port (port)
设置为8085
,以便它公开与Pod
相同的端口?实际上没有什么能阻止你这样做。
当我尝试通过网关调用 rest api 时,我得到
There was an unexpected error (type=Internal Server Error, status=500). finishConnect(..) failed: Host is unreachable: common/172.30.7.24:8085
服务是
Name: common Type: ClusterIP IP: 172.30.7.24 Port: <unset> 8080/TCP TargetPort: 8085/TCP Endpoints: 10.129.3.101:8085
它似乎使用了服务 IP 和 pod 端口。我还添加了
spring.cloud.kubernetes.ribbon.mode=SERVICE
但什么都没有改变。
从您发布的内容来看,当您尝试通过网关调用 rest api 时,它希望它使用您的Service
IP(172.30.7.24
(和端口8085
公开,因此只需在该端口上公开它,它应该可以正常工作:
...
spec:
ports:
- protocol: TCP
port: 8085
targetPort: 8085
...
如果有帮助,请告诉我。