当前位置: 首页 > 知识库问答 >
问题:

Kubernetes发现定位器上的Spring Cloud Gateway使用pod端口而不是服务端口

虞博涛
2023-03-14

我正在用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是target etPort(即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 gateway工作,我必须对齐pod端口和服务端口,但这听起来很奇怪。

共有2个答案

太叔乐家
2023-03-14

为什么不能简单地将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.kubenetes.ribbon.mode=service,但没有任何变化。

从您发布的内容来看,当您尝试通过网关调用 rest api 时,它希望它使用您的服务 IP (172.30.7.24) 和端口 8085 公开它,因此只需在该端口上公开它,它应该可以正常工作:

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

如果有帮助,请告诉我。

东门玺
2023-03-14

是否正在使用功能区?Ribbon 的默认 spring.cloud.kubernetes.ribbon.mode 是 POD。来自文档(引用):

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

>

  • POD模式是通过获取库伯内特斯的Pod IP地址并使用Ribbon来实现负载平衡,POD模式使用Ribbon的负载平衡不支持库伯内特斯负载平衡,不支持Istio的流量策略。

    < code >服务模式直接基于功能区的服务名称。将Kubernetes服务连接到< code>service-name。{ namespace } . SVC . { cluster . domain }:{ port } 如:< code > demo 1 . default . SVC . cluster . local:8080 。< code >服务模式使用Kubernetes服务的负载平衡来支持Istio的流量策略。

  •  类似资料:
    • 在我的spring Boot2.0应用程序中,我的主应用程序监听端口1234,我想让管理服务器运行在1235上。 我的服务器无法启动,出现以下错误: 如果我移除这个: 谢谢!

    • 只有。这些服务到底有什么不同?端口到底做什么?

    • 我编写UDP服务器,为NAT后面的客户端提供服务。 客户端将请求发送到公共IP和一些预定义的端口。服务器接收消息,创建(从池获取)线程并将消息传递给线程(处理程序)。 问题:我可以使用新的套接字(不同的端口)来发送响应,还是应该使用接收请求的相同端口(套接字)?

    • 我在pod上部署了SAS Viya编程。这使SASStudio在端口80上运行。我正在尝试通过下面的yaml文件使用nodeport和Inete公开SAS Studio。但在GCP控制台中,后端服务显示不健康,如果我尝试访问Ip,它会遇到默认后端或找不到页面。我可以使用集群IP和节点IP以及端口号访问服务。 如果我使用LoadBalancer服务而不是入口,那么我可以使用LoadBalancer

    • 在学习入门教程第3部分:部署到库伯内特斯时,我偶然发现了清单文件部署定义中的Pod模板。在pod和容器部分都没有指定端口。 这就引出了我最初的问题:端口发布如何从docker容器进入pod? 下面的引语听起来像是kubernetes在启动后了解了正在运行的容器,并从侦听0.0.0.0的服务中获取端口:port并将其映射到pod环境中的同一端口(网络名称空间)。 不在此处指定端口不会阻止该端口被公开

    • 我有一个基本的Java客户机服务器TCP程序,它能够通过局域网连接,也当我使用我的公共ip与端口转发。 让我困扰的是,当我尝试在hamachi VPN网络中使用相同的程序时,它不起作用。我想让它也在那里工作,因为许多人试图避免端口转发,但使用hamachi,因为这似乎对他们更容易。 服务器代码ss=new ServerSocket(4444);客户端c=SS.Accept(); 客户端代码套接字客

    • 我使用python中的套接字设置了一个客户机和一个服务器,客户机向服务器发送数据,服务器执行操作,然后向客户机返回一些数据。最初,客户端和服务器将具有相同的端口号(9999)。我目前的问题是,我必须将服务器端口更改为19999,当我试图运行时,它无法工作。客户端能够发送数据,如果它的端口也更改为19999,但它不工作,如果客户端是9999和服务器是19999,这是我需要的。新的网络系统,所以将感谢

    • https://kubernetes.io/docs/concepts/services-networking/Ingress/中的入口示例显示,为了指定bancked入口,我们必须指定servicePort和serviceName,例如: 我希望创建具有随机端口的服务,并避免在入口定义中指定它们。有没有ServicePort的替代方案?也许使用服务中分配的端口名称或targetPort?