在上一篇(一)服务注册与发现Eureka的集群搭建与配置 中,我们将基本的Eureka搭建完毕,接下来就需要搭建好对外暴露服务的Api服务,在我的项目中,使用的zuul作为api-gateway,接下来我将详细讲解,在工程中是如何配置并对外暴露端口提供服务的。
首先我们需要搭建好自己的微服务Zuul工程,具体的搭建我这就不具体细说,这里并不需要对我们本身的微服务进行特殊的修改及配置,唯一一个注意的点就是需要将端口设置为k8s集群中配置好的端口范围。
K8S中NodePort方式暴露服务的端口的默认范围(30000-32767)
Zuul网关与eureka服务不同的是,它可以作为无状态服务进行部署,因此本文将采用deployment的方式进行部署,同时这也是最常见的方式之一。
Deployment 是最常用的用于部署无状态服务的方式。Deployment 控制器使得您能够以声明的方式更新 Pod(容器组)和 ReplicaSet(副本集)。例如,以滚动更新为例,假设有 3 个容器组,现需要将他们的容器镜像更新为新的版本。
声明的方式,您只需要执行:
- 使用 kubectl 更新 Deployment 定义中 spec.template.spec.containers[ ].image 字段
这边暂不详述滚动更新操作,后续会进行扩展,感兴趣的也可以自己去了解查询。
(一)api-gateway.yaml文件配置
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway-deployment
namespace: box
spec:
selector:
matchLabels:
app: api-gateway
replicas: 3
template:
metadata:
labels:
app: api-gateway
spec:
containers:
- name: api-gateway
image: harbor.box.com/box/api-gateway
imagePullPolicy: Always
ports:
- containerPort: 19899
env:
- name: eureka.client.service-url.defaultZone
value:
"http://eureka-0.eureka.box.svc.cluster.local:8761/eureka,http://eureka-1.eureka.box.svc.cluster.local:8761/eureka,http://eureka-2.eureka.box.svc.cluster.local:8761/eureka"
- name: global.versionEnable
value:
"false"
volumeMounts:
- mountPath: /apps/logs/box
name: box-logs
volumes:
- name: box-logs #日志挂载
hostPath:
path: /apps/logs/box
采用了deployment的部署方式,同时通过env对容器的环境变量进行配置,这里可以根据自己工程中需要的配置进行添加修改。
(二)api-gateway-nodePort.yaml文件配置
# ------------------- Api-Gateway ------------------- #
apiVersion: v1
kind: Service
metadata:
labels:
app: api-gateway
name: api-gateway
namespace: box
spec:
type: NodePort
sessionAffinity: ClientIP
sessionAffinityConfig: #配置session保持
clientIP:
timeoutSeconds: 50800
ports:
- port: 19899 #服务端口
protocol: TCP
targetPort: 19899 #容器端口
nodePort: 31000 #对外node节点端口
selector:
app: api-gateway
### 当不设置session保持时,service向后台pod转发规则是轮询。当设置了session保持之后,k8s会根据访问的ip来把请求转发给他以前访问过的pod,这样session就保持住了。
将集群外部流量导入到集群内的有三种方式,只是实现方式不同。分别是NodePort,LoadBalancer 和 Ingress 。这三种方式各有利弊。
LoadBalancer 服务是暴露服务到 internet 的标准方式。在 GKE 上,这种方式会启动一个Network Load Balancer,它将给你一个单独的 IP 地址,转发所有流量到你的服务。
如果你想要直接暴露服务,这就是默认方式。所有通往你指定的端口的流量都会被转发到对应的服务。它没有过滤条件,没有路由等。这意味着你几乎可以发送任何种类的流量到该服务,像 HTTP,TCP,UDP,Websocket,gRPC 或其它任意种类。
这个方式的最大缺点是每一个用 LoadBalancer 暴露的服务都会有它自己的 IP 地址,每个用到的 LoadBalancer 都需要付费,这将是非常昂贵的。
Ingress 事实上不是一种服务类型。相反,它处于多个服务的前端,扮演着“智能路由”或者集群入口的角色。
默认 ingress 控制器是启动一个HTTP(s)Load Balancer。它允许你基于路径或者子域名来路由流量到后端服务。例如,你可以将任何发往域名 foo.yourdomain.com 的流量转到 foo 服务,将路径 yourdomain.com/bar/path 的流量转到 bar 服务。
如果你想要使用同一个 IP 暴露多个服务,这些服务都是使用相同的七层协议(典型如 HTTP),那么Ingress 就是最有用的。如果你使用本地的 GCP 集成,你只需要为一个负载均衡器付费,且由于 Ingress是“智能”的,你还可以获取各种开箱即用的特性(比如 SSL,认证,路由,等等)。 NodePort方式的选择及缺点
NodePort 服务是引导外部流量到你的服务的最原始方式。NodePort,正如这个名字所示,在所有节点(虚拟机)上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。
NodePort 服务主要有两点区别于普通的“ClusterIP”服务。第一,它的类型是“NodePort”。有一个额外的端口,称为 nodePort,它指定节点上开放的端口值 。如果你不指定这个端口,系统将选择一个随机端口。大多数时候我们应该让 Kubernetes 来选择端口。
缺点:
由于本文中部署的环境中,仅需要api-gateway对外暴露服务,其余都是在集群内部访问,且机器并不会变化,同时采用了其他高可用手段保证服务的高可用,因此采用了NodePort方式进行部署,推荐还是使用ingress进行配置。
在部署了K8s集群的机器上,进行部署操作。环境需具备docker和harbor仓库,其次每个节点对harbor的都可以访问到,否则会导致镜像拉取失败。
1.将jar包上传并打包成镜像并上传至仓库。
docker build -t="harbor.box.com/box/api-gateway" .
docker push harbor.box.com/box/api-gateway
2.启动k8s配置文件
kubectl apply -f api-gateway-nodePort.yaml
kubectl apply -f api-gateway.yaml
3. 查看pod是否启动:
kubectl get po -n box -o wide
如下图所示,可以看到api-gateway都已经正常启动 -n 后面的参数可以改成box也就是上文中配置的namespace,这边的截图为我本地项目中跑的namespace名字
4. 查看service 可以看到分配的ip及映射的端口
kubectl get svc -n box -o wide
打开eureka界面可以看到api已经注册上去 同时使用curl接口访问本地ip+映射的端口+服务接口,可以看到成功返回。
到这里 我们就搭建好一个基于k8s集群+docker的SpringCloud组件Zuul集群,下一节我将讲述我是如何搭建其他普通微服务的,比较简单 因为都是集群内部的访问。如果有疑问,欢迎留言区留言。
本文参考:
http://dockone.io/article/4884