定义
企业级网关通过域名、路由将请求分发到对应的应用上,通常承载数千个服务的流量,对稳定性有较高要求。
CNCF全景图
选型
Kubernetes抽象出两个核心概念:Service,为多个Pod提供统一的访问入口;Ingress(之后由Gateway API替代),定义了如何将外部流量路由到集群内部的服务。
Ingress的具体实现需要依靠底层组件读取相关配置,并将其转换为Nginx可执行的配置。此外,云原生网关通常部署在Kubernetes集群内部,必须能够解析内部服务的IP,并能够通过Kubernetes网络转发请求。
由此可以概括出云原生网关应具备的关键能力:
1、能够解析Ingress资源对象,并将其转换为自己的配置;
2、能够获取内部服务IP,实现多样化的负载均衡策略;
云原生网关分为以下三类:
1、基于nginx,使用openresty作为控制平面;
2、基于envoy,需要学习xDS协议,是云原生生态中积极推动的项目代表着未来的发展方向;
3、自研解决方案,golang编写,由于转发内核都是自研的,稳定性和兼容性一般;
nginx类ingress功能有限,最大的问题是其配置生效不是动态的。架构设计是基于work和master进程,其中master进程负责管理,work进程处理请求。如果需要修改配置,必须重启所有的work进程。
架构
数据面DP:实际处理流量转发的服务,在这里就是Nginx;
控制面CP:对接ingress规范,将配置的路由转换为数据面可以理解的格式,并下发这些配置,使之生效,包括:上游服务、消费者、插件和证书等;
数据存储:建议为APISIX单独部署一套Etcd;
优点:控制面出现问题,业务流量处理也不会受到影响,只是无法更新新的配置;
安装
apisix官方
apisix部署
流量转发
一旦流量成功匹配路由规则后,APISIX会将其转发给上游服务。
APISIX能够绕过Service,直接对接Pod,使整个流量转发过程变成APISIX到Pod的直接通信。从Kubernetes的网络模型来看,这就是集群内Pod到Pod之间的通信。
通常,会将网关组件独立部署在几台服务器上,因此网关转发请求到Pod,即服务本身需要跨节点通信。在Kubernetes的网络模型中,这种跨节点通信是由CNI插件来实现的。
模式
hostnetwork
优点:使用简单,并且能够传递真实IP。
将APISIX的network namespace直接附加到k8s node上,这样APISIX就不会使用Pod网络的地址,而是使用node的IP。数据转发时,受到kube-proxy配置的规则约束,经由postrouting链处理,再通过CNI跨节点到达目标服务。
缺点:没有使用网络虚拟化,最大的影响是无法使用滚动发布来更新网关服务。
external load balancer
需要外部硬件负载均衡,使用LoadBalancer类service,流量由外部SLB处理并转发到集群内。转发过程繁琐。
externalIPs
spec:
ports:
- name: apisix-gateway
protocol: TCP
port: 80
targetPort: 80
nodePort: 30238
- name: tls
protocol: TCP
port: 443
targetPort: 443
nodePort: 32435
selector:
app.kubernetes.io/instance: apisix
app.kubernetes.io/name: apisix
type: NodePort
externalIPs:
- A.B.x.x
sessionAffinity: None
externalTrafficPolicy: Local
1、如果service为ClusterIP类型,则k8s层面的负载均衡有效,流量平均转发到后端Pod;
2、如果需要保留源IP地址,service须为NodePort类型,并将externalTrafficPolicy设置为Local。内核实现把发往external IP的80端口的请求转发给Pod,但会失去SVC服务负载均衡的能力;
3、由于apisix部署时有外置负载均衡提供vip,确保即使在某些节点出现故障时,服务仍然可以保持高可用,所以选择2;
4、此模式下,NodePort类型service不再发挥作用,因此可以在防火墙上只开放80、443,关闭30238、32435;
5、所有node依然通过iptables设置30238端口相关的规则,实际没用,因为externalTrafficPolicy设置为Local,只处理发给Pod所在node的流量;
6、登录对应node可以访问80、30238及443、32435;
7、为了更好地理解流量的路由路径,查看iptables发现,80端口的规则与ClusterIP对应,externalIPs使用A.B.x.x来匹配;
结论:
externalIPs实际上是NodePort类型service,借此指定端口映射到主机上,同时配合externalTrafficPolicy策略,将流量限制到指定的IP列表中。在三种模式中,使用了externalIPs,因为首先解决了hostnetwork不利于Pod变更的问题,其次利用了k8s原有功能实现,减少了转发路径,同时也保留了源IP。