2

我正在使用 spring cloud gateway 和 spring cloud kubernetes discovery 在 openshift 上实现 API 网关。

我从项目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是 targetPort(即 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 端口和服务端口,但这听起来很奇怪。

4

2 回答 2

0

为什么你不能简单地设置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 时,它希望它使用您的ServiceIP ( 172.30.7.24) 和 port8085公开,因此只需在该端口上公开它,它应该可以正常工作:

...
spec:
  ports:
    - protocol: TCP
      port: 8085
      targetPort: 8085
...

如果有帮助,请告诉我。

于 2020-02-06T18:13:09.930 回答
0

是否使用功能区?功能区的默认spring.cloud.kubernetes.ribbon.mode值为 POD。从文档(引用):

spring.cloud.kubernetes.ribbon.mode支持PODSERVICE模式。

  • POD模式是通过获取Kubernetes的Pod IP地址,使用Ribbon来实现负载均衡。POD 模式使用 Ribbon 的负载均衡 不支持 Kubernetes 负载均衡,不支持 Istio 的流量策略。

  • SERVICE模式直接基于 Ribbon 的服务名称。获取 Kubernetes 服务被串联成 service-name.{namespace}.svc.{cluster.domain}:{port}例如: demo1.default.svc.cluster.local:8080. 该SERVICE模式使用 Kubernetes 服务的负载均衡来支持 Istio 的流量策略。

于 2020-02-06T16:09:22.650 回答