一次对K8S集群service的“非主流”访问方式引发的网络探究

本文介绍了如何在K8S集群中,通过非主流方式实现集群外部对clusterIP类型service的访问。文章详细分析了K8S服务类型,以及在特定需求下,通过IPsec隧道解决跨网络访问问题。在实践中,通过TCPdump抓包分析,发现并解决了数据包在跨节点转发时被丢弃的问题,最终通过开启kube-proxy的masqueradeALL参数实现了SNAT转换,成功访问service。
摘要由CSDN通过智能技术生成

一次对K8S集群service的“非主流”访问方式引发的网络探究

(一)“颇有个性”的需求

某日,我们接到了客户的求助。客户在云上环境使用了托管K8S集群产品部署测试集群。因业务需要,研发同事需要在办公网环境能直接访问K8S集群的clueterIP类型的service和后端的pod。通常K8S的pod只能在集群内通过其他pod或者集群node访问,不能直接在集群外进行访问。而pod对集群内外提供服务时需要通过service对外暴露访问地址和端口,service除了起到pod应用访问入口的作用,还会对pod的相应端口进行探活,实现健康检查。同时当后端有多个Pod时,service还将根据调度算法将客户端请求转发至不同的pod,实现负载均衡的作用。常用的service类型有如下几种:
1、 clusterIP类型,创建service时如果不指定类型的话的默认会创建该类型service,clusterIP类型的service只能在集群内通过cluster IP被pod和node访问,集群外无法访问。通常像K8S集群系统服务kubernetes等不需要对集群外提供服务,只需要在集群内部进行访问的service会使用这种类型;
2、 nodeport类型,为了解决集群外部对service的访问需求,设计了nodeport类型,将service的端口映射至集群每个节点的端口上。当集群外访问service时,通过对节点IP和指定端口的访问,将请求转发至后端pod;
3、 loadbalancer类型,该类型通常需要调用云厂商的API接口,在云平台上创建负载均衡产品,并根据设置创建监听器。在K8S内部,loadbalancer类型服务实际上还是和nodeport类型一样将服务端口映射至每个节点的固定端口上。然后将节点设置为负载均衡的后端,监听器将客户端请求转发至后端节点上的服务映射端口,请求到达节点端口后,再转发至后端pod。Loadbalancer类型的service弥补了nodeport类型有多个节点时客户端需要访问多个节点IP地址的不足,只要统一访问LB的IP即可。同时使用LB类型的service对外提供服务,K8S节点无需绑定公网IP,只需要给LB绑定公网IP即可,提升了节点安全性,也节约了公网IP资源。利用LB对后端节点的健康检查功能,可实现服务高可用。避免某个K8S节点故障导致服务无法访问。
通过对K8S集群service类型的了解,我们可以知道客户想在集群外对service进行访问,首先推荐使用的是LB类型的service。由于目前K8S集群产品的节点还不支持绑定公网IP,因此使用nodeport类型的service无法实现通过公网访问,除非客户使用专线连接或者IPSEC将自己的办公网与云上网络打通,才能访问nodeport类型的service。而对于pod,只能在集群内部使用其他pod或者集群节点进行访问。同时K8S集群的clusterIP和pod设计为不允许集群外部访问,也是出于提高安全性的考虑。如果将访问限制打破,可能会导致安全问题发生。所以我们的建议客户还是使用LB类型的service对外暴露服务,或者从办公网连接K8S集群的NAT主机,然后通过NAT主机可以连接至K8S节点,再访问clusterIP类型的service,或者访问后端pod。
客户表示目前测试集群的clusterIP类型服务有上百个,如果都改造成LB类型的service就要创建上百个LB实例,绑定上百个公网IP,这显然是不现实的,而都改造成Nodeport类型的service的工作量也十分巨大。同时如果通过NAT主机跳转登录至集群节点,就需要给研发同事提供NAT主机和集群节点的系统密码,不利于运维管理,从操作便利性上也不如研发可以直接通过网络访问service和pod简便。

(二)方法总比困难多?

虽然客户的访问方式违背了K8S集群的设计逻辑,显得有些“非主流”,但是对于客户的使用场景来说也是迫不得已的强需求。作为技术中台的攻城狮,我们要尽最大努力帮助客户解决技术问题!因此我们根据客户的需求和场景架构,来规划实现方案。
既然是网络打通,首先要从客户的办公网和云上K8S集群网络架构分析。客户办公网有统一的公网出口设备,而云上K8S集群的网络架构如下,K8S集群master节点对用户不可见,用户创建K8S集群后,会在用户选定的VPC网络下创建三个子网。分别是用于K8S节点通讯的node子网,用于部署NAT主机和LB类型serivce创建的负载均衡实例的NAT与LB子网,以及用于pod通讯的pod子网。K8S集群的节点搭建在云主机上,node子网访问公网地址的路由下一跳指向NAT主机,也就是说集群节点不能绑定公网IP,使用NAT主机作为统一的公网访问出口,做SNAT,实现公网访问。由于NAT主机只有SNAT功能,没有DNAT功能,因此也就无法从集群外通过NAT主机访问node节点。
关于pod子网的规划目的,首先要介绍下pod在节点上的网络架构。如下图所示,

在这里插入图片描述
在节点上,pod中的容器通过veth对与docker0设备连通,而docker0与节点的网卡之间通过自研CNI网络插件连通。为了实现集群控制流量与数据流量的分离,提高网络性能,集群在每个节点上单独绑定弹性网卡,专门供pod通讯使用。创建pod时,会在弹性网卡上为Pod分配IP地址。每个弹性网卡最多可以分配21个IP,当一张弹性网卡上的IP分配满后,会再绑定一张新的网卡供后续新建的pod使用。弹性网卡所属的子网就是pod子网,基于这样的架构,可以降低节点eth0主网卡的负载压力,实现控制流量与数据流量分离,同时pod的IP在VPC网络中有实际对应的网络接口和IP,可实现VPC网络内对pod地址的路由。
了解完两端的网络架构后我们来选择打通方式。通常将云下网络和云上网络打通,有专线产品连接方式,或者用户自建VPN连接方式。专线产品连接需要布设从客户办公网到云上机房的网络专线,然后在客户办公网侧的网络出口设备和云上网络侧的bgw边界网关配置到彼此对端的路由。如下图所示

在这里插入图片描述
基于现有专线产品BGW的功能限制,云上一侧的路由只能指向K8S集群所在的VPC,无法指向具体的某个K8S节点。而想要访问clusterIP类型service和pod,必须在集群内的节点和pod访问。因此访问service和pod的路由下一跳,必须是某个集群节点。所以使用专线产品显然是无法满足需求的。
我们来看自建VPN方式,自建VPN在客户办公网和云上网络各有一个有公网IP的端点设备,两个设备之间建立加密通讯隧道,实际底层还是基于公网通讯。如果使用该方案,云上的端点我们可以选择和集群节点在同一VPC的不同子网下的有公网IP的云主机。办公网侧对service和pod的访问数据包通过VPN隧道发送至云主机后,可以通过配置云主机所在子网路由,将数据包路由至某个集群节点,然后在集群节点所在子网配置到客户端的路由下一跳指向端点云主机,同时需要在pod子网也做相同的路由配置。至于VPN的实现方式,通过和客户沟通,我们选取ipsec隧道方式。
确定了方案,我们需要在测试环境实施方案验证可行性。由于我们没有云下环境,因此选取和K8S集群不同地域的云主机代替客户的办公网端点设备。在华东上海地域创建云主机office-ipsec-sh模拟客户办公网客户端,在华北北京地域的K8S集群K8S-BJTEST01所在VPC的NAT/LB子网创建一个有公网IP的云主机K8S-ipsec-bj,模拟客户场景下的ipsec云上端点,与华东上海云主机office-ipsec-sh建立ipsec隧道。设置NAT/LB子网的路由表,添加到service网段的路由下一跳指向K8S集群节点k8s-node-vmlppp-bs9jq8pua,以下简称node A。由于pod子网和NAT/LB子网同属于一个VPC,所以无需配置到pod网段的路由,访问pod时会直接匹配local路由,转发至对应的弹性网卡上。为了实现数据包的返回,在node子网和pod子网分别配置到上海云主机office-ipsec-sh的路由,下一跳指向K8S-ipsec-bj。完整架构如下图所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值