0
点赞
收藏
分享

微信扫一扫

云原生架构之Springboot Gateway+K8s 服务注册发现方案(南北流量)


一 方案概述

springboot gateway 服务利用spring cloud kubernetes进行调用K8s API获取service服务发现,进行路由转发。

二 SpringBoot + K8s service服务注册发现方案

2.1 方案简介

springboot gateway 使用spring cloud kubernetes 与api Servier的http交互,方便项目中对api Server的请求和读取k8s中的 服务注册发现 ​​Services​​​ / ​​Endpoints​​。

云原生架构之Springboot Gateway+K8s 服务注册发现方案(南北流量)_Kubernetes

南北流量访问 ​​http://网关服务IP:网关服务端口/后端服务service名称/请求api路径​​ , gateway 通过调用API server获取到后端服务endpoints,进行请求路由转发转发。

2.2 服务注册发现实现

2.2.1 服务注册过程

spring cloud 服务配置有serivce的服务,启动后k8s集群针对调用该service,后端会返回具体的pod列表。

2.2.2 服务发现过程

通过 spring cloud kubernetes的服务发现,调用k8s api获取pod实例的ip和端口,gateway 进行流量转发。

2.3 方案特点

  • 优点:
  • 服务直接通过k8s服务发现,获取service后的实例POD IP和端口,gateway 流量转发,直接对POD发起,不经过service转发,性能好。
  • 不足:
  • 负载均衡算法在服务调用端(客户端)实现,例如ribbon实现,如果后期使用服务治理框架例如istio/linkerd不适用。

三 实战

3.1 后端API服务

对外暴露的API服务,服务注册为编写服务对应的service yaml资源对象。 源码位置:​​github.com/redhatxl/cl…​​

3.2 gateway

3.2.1 服务逻辑

springboot-init 为服务提供者,对外提供 /services 用于获取 K8s 名称空间的名称,及返回相应 POD 的hostname。服务注册,仅需为服务编写 service yaml 资源清单即可。

3.2.2 服务发现

通过引入 spring-cloud-starter-kubernetes-client-all 进行服务发现

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-all</artifactId>
<version>2.1.3</version>

3.2.3 项目目录结构

.
├── Dockerfile
├── HELP.md
├── README.md
├── deploy
│ ├── deploy.yaml
│ └── deploy.yamle
├── mvnw
├── mvnw.cmd
├── pom.xml
├── springboot-gateway.iml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── xuel
│ │ │ └── springbootgateway
│ │ │ └── SpringbootGatewayApplication.java
│ │ └── resources
│ │ ├── application.properties
│ │ └── application.yaml

3.2.4 K8s部署文件

apiVersion: apps/v1
kind: Deployment
metadata:
namespace: springgateway
name: springboot-gateway
labels:
app: springboot-gateway
spec:
replicas: 1
selector:
matchLabels:
app: springboot-gateway
template:
metadata:
labels:
app: springboot-gateway
spec:
containers:
- name: springboot-gateway
image: ccr.ccs.tencentyun.com/xxxxxxxxxx-dev/springbootgateway:img_v5
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
port: 8080
path: /actuator/health
periodSeconds: 10
initialDelaySeconds: 3
terminationGracePeriodSeconds: 10
failureThreshold: 5
timeoutSeconds: 10
readinessProbe:
httpGet:
port: 8080
path: /actuator/health
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 5
timeoutSeconds: 10

---
apiVersion: v1
kind: Service
metadata:
name: springbootgateway
namespace: springgateway
labels:
app: springboot-gateway
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
type: ClusterIP
selector:
app: springboot-gateway

3.2.5 项目源码

项目位置:​​github.com/redhatxl/cl…​​

四 测试

4.1 单独测试服务API

k port-forward -n springgateway --address 0.0.0.0 svc/springbootgatewayserviceprovider 8888:8080

云原生架构之Springboot Gateway+K8s 服务注册发现方案(南北流量)_云原生_02

4.2 通过gateway 进行测试

k port-forward -n springgateway --address 0.0.0.0 svc/springbootgateway 9999:8080

云原生架构之Springboot Gateway+K8s 服务注册发现方案(南北流量)_Kubernetes_03

4.3 查看资源

云原生架构之Springboot Gateway+K8s 服务注册发现方案(南北流量)_云原生_04

五 其他

配置 ​​url-expression​​​ 目的是为了在转发的时候直接转发到 Kubernetes 中相应的 Service 上去,默认的表达式为 ​​"'lb://'+serviceId"​​​ ,这种适用于通过 Consul 或者 Eureka,最终是根据服务的IP和端口访问, ​​spring-cloud-kubernetes​​​ 没有实现 ​​com.netflix.loadbalancer.AbstractServerList​​ ,所以不会进行IP转换,最终是通过服务名称查找Service 实现调用,所以不需要负载均衡

  • 如果是客户端实现负载均衡,则不需要指定​​"'http://'+serviceId+':'+port"​
举报

相关推荐

0 条评论