暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

容器云网络 | 我们是如何把问题复杂化的

北银金科逐浪青春 2021-11-05
680



容器云是构建云原生应用的最佳搭档,已是普遍共识,云原生架构是一套设计思想,其主旨是使得应用系统能够“生长”在“云”上。云的特性在我们看来,最显著的是弹性的服务能力和面向不确定性的设计。因此,如何在可变基础设施上稳定运行,在屏蔽计算、存储、网络的差异性后,还能够借助其弹性能力赋能应用本身,就成了衡量标准。容器封装及编排技术正好符合这样的时代背景,而且还更进一步解决了很多自动化运维的问题。



Heroku 创始人 Adam Wiggins 在2012年提出了非常重要的《The Twelve-Factor App》概念,也就是常说的“云原生应用十二原则”,来衡量一个应用系统是否适合在云上运行,他是云端应用系统一系列最佳实践的总结。尤其是经过试点应用上云阶段以后,回过头再来看这套原则,真的是指明方向、完美避坑的宝典。


经典的十二原则是目标,现实真正考验的是如何基于当下多种异构应用并存的背景去逐步实践它,作为云平台的建设者,可以选择仅面向敏态业务去设计云平台,充分发挥云平台的优势,但作为金融行业的云平台,涉及普惠民生的应用系统太多,业务、系统、应用的领域模型也导致其服务架构很复杂,不是一个微服务框架或者状态分离就能说得清楚。在保证安全稳定的前提下,进行架构平滑演进是不得不面对的责任和挑战,对于双模 IT 的特殊阶段,云平台要考虑的不仅仅是云原生应用,也需要面对存量应用和分阶段上云带来的,开发、交付、观测和运营保障能力的挑战。


回到本文的主题,对于容器云网络来说,他和计算、存储等其他基础设施一样,需要实现与应用的解耦,实现真正意义上服务于应用的云网络,我们不能再通过IP来识别应用流量,但又要基于IP网络来满足服务实例间的互联互通、彼此发现,同时还要在相当长的一段时间里,保证云原生应用架构与传统应用架构应用、云上应用与云下应用的南北向服务发布,甚至是东西向的动态服务发现。这不仅仅是个技术问题,还会影响到ITIL、CMDB这些管理系统的发展方向。


在容器网络方案的选择和设计中,我们会看到非常丰富的可选方案,从早期的MacvlanFlannel,再到Calico或者新兴的KubeOVN,甚至还有多网卡多平面单网卡多VLAN多种网络方案混合运行等等,各有各的优势和适用场景,很难得出那个方案最优的结论,这其实与容器云的发展规模和生产实践有关,不同的发展阶段对容器云网络的需求会不同。


在建设初期,通常会先挑选云原生架构开发的系统来上云。作为一个完整的系统,与网络相关的部分仅需要考虑的是应用组件之间进行顺畅的通讯,将一个Pod作为服务实例,通过容器技术将其封装,使其与操作系统环境解耦,再通过Kubernetes集群作为应用的服务框架,利用它来屏蔽基础设施环境,形成一致化的运行时平台。应用内部的组件间通讯也不受基础网络的影响,在集群内互联互通,达到统一数据平面,组件集中编排和统一的服务发现,对外则通过发布ingress、nodeport等外部可路由地址来对应用进行访问。


在这个阶段,用过最多的方案当属Flannel,准确来说应该是Flannel的VxLAN模式,非常简单好用。因为容器集群内部的网络与外界是隔离的,所有pod全部使用私网IP,不需要与外部直接连通,即使一个集群的节点跨了vlan,只要允许vxlan封装协议通过,也可以组成一个跨三层互通的集群网络传输平面。容器云管理员和网络管理员各得其所,只需要注意规划容器云私网IP不要与外部网络地址段冲突就行,工作起来大家互相不冲突。 



相比较Flannel-VxLAN,整个集群是一个网络平面。此外,Openshift-SDN 和 KubeOVN 还可以为Kubernetes中的每个Namespace(OCP里也叫Project)提供一个独立的网络平面,形成所谓租户间(Namespace)的网络隔离,也一样采用的是VxLAN,实际就是多个UDP多播组,相比GRE、IPIP这种点对点的隧道协议,采用UDP多播已是很大的进步,由于不是点对点组网,所以对于集群节点数量的变化要友好的多。后续还出现了Geneve封装协议,虽然比VxLAN要传输效率高很多,但 VxLAN 胜在成熟通用,支持的设备也多。


当我们还沉浸在试点应用顺利投产并稳定接入业务流量的喜悦之时,下一阶段的挑战已悄然到来 ——混合架构场景的云平台服务


  • 系统非全量上云,而是部分无状态组件先上云,但仍需要集中服务发现;

  • 利用云平台快速部署中间件,应用业务组件运行在云下,例如连接云上redis的哨兵集群;

  • 有些业务系统的部分组件与个别环境相关,没有上云需求,但又要与云上的组件共同使用一套服务注册和发现机制;

  • 应用开发时,想要从IDE连调云上运行环境;

  • 云平台运营人员如何管理容器云网络,出现问题如何排障。


以Kubernetes本身的能力来讲,发布一个服务给云下的应用使用时,如果是七层的服务(HTTP和HTTPS)可以通过ingress,也就是通过Nginx/Traefik这类反向代理服务来对外发布,这要求应用必须能够接受反向代理,而不是一定要与云下应用直接IP互联,如果是四层的服务(TCP和UDP)则会通过nodeport,也就是通过集群主机的IPTables来进行DNAT转换,而且在IPTables中还不止一个链,先要进入SVC链,才会按照比例将流量再转发给Pod链。



你会看到,如果是能够支持反向代理的服务那还好,但如果必须要支持DR直接路由模式呢,可能就会出现问题,比如云上提供redis的哨兵集群、FTP服务。我们来看看redis-sentinel,也就是哨兵的工作模型



首先,我们会通过sentinel发布的nodeportip来访问;

然后,哨兵节点会返回master的PodIP给client去连接。

最后,云下的主机连不通Pod的IP地址。。。。。卒~


当然我们可以使用类似predixy这类redis的proxy方案,但是简单做做get、set操作是没问题的,如果应用想要操作redis集群级别的指令就不支持了,所以云上云下打通ip路由就成了刚需,相类似的,还有Kafka的场景,消息的订阅和心跳检测,我们甚至在这个阶段还对应用进行了改造,在云上云下各自的Kafka集群中分发消息,但这的确并非长久直击,带来了本不该有的资源浪费和运维成本。


在应用上云的这个阶段,大多数是无状态组件先上云,有状态组件大部分还在云下,这种情况主要是考虑能够更好的发挥现有专业技术团队的能力。因此这引发了一个新的需求,容器云的私网IP地址如何与外部网络打通,实现双向可直接路由。同时,由于网络的打通,又产生了新的管理问题,比如网段需要统一规划,ip地址需要统一管理和分配。有时,并不是我们愿意引入复杂的技术和方案,因为都有学习成本,都需要评估学习曲线、技术团队、形成生产力的周期、应急响应的能力,但实现业务价值是一切的核心,既然叫云平台,那只能往前。


到这里,我们再次讨论容器云网络,通常就会一起讨论云上网络和云下网络的整体设计,深入讨论到Kubernetes中Pod的网络工作模型,且还要兼顾现有管理和监控手段是否能够覆盖这样动态的网络,将会背上多少多少新的技术债,会挑战哪些安全控制规范,能达到的效果和获得的收益是否值得这样去做。当某项先进的技术放到特定的场景里,总有个适应期,还是要落地实践,庆幸的是,团队的小伙伴都以此为乐,即使不一定哪天遇到个30min内解决不了的生产事故,就能把过往的荣耀打回原形。


不管容器云网络有哪些名字和开源实现的套件方案,从Pod间的网络通讯模型来讲,可以简单分为underlayoverlay两类。underlay类型的网络不会对Pod的流量进行封装,也就是说你可以从Pod所在主机的网络中直接抓到源地址或目的地址为PodIP的网络包,而overlay则不同,通常会将原始的Pod网络包封装到vxlan或其他隧道协议的包里,于是从网络上抓包,就只能抓到以主机IP为源地址或目的地址的包,除非再往里深入一层,把隧道协议的包头剥离掉。所以很明显相对underlay协议,overlay的网络模型有一个好处,就是可以穿越现有的网段划分,只要允许隧道协议穿越,那么不同区域的网络就可以通讯,甚至形成大二层网络,这在第一阶段相当好用,能完全屏蔽容器网络对现有网络的干扰,也能在试点应用阶段避免引入太多的运维力量,但问题也很突出:


  • 首当其冲是性能的损耗,每次都要封包拆包,这对密集型小包传输的场景影响非常大,而且MTU也要占用一部分给vxlan包头,如果应用不能感知,则原始数据包还可能被拆分重新形成两个数据包

  • 如果容器云的节点部署于虚拟机上,而IaaS也使用了隧道协议来做分布式VPC网络,那么当两个运行于不同虚拟机节点,且两个虚拟机运行于不同物理机节点的情况下,就会有两层隧道包头的消耗,性能影响就比较大了

  • 即使是对网络传输性能不敏感的应用也会遇到管理的问题,之前基于网络抓包模式工作的APM必须要按隧道协议来分析,之前按照IP或者IP范围作为访问控制对象的策略不生效了,这其实也给等保工作带来了不小的影响


所以我们会看到underlay的网络越来越流行,性能接近主机,管理手段也能沿用。在这个方案的探索和实践过程中,我感觉也经历了大致两个阶段,首先是把容器当虚拟机看,同一个二层平面,一个网段里,既有容器IP也有主机IP,比如MacVLAN、IPVLAN方案。每一个容器和它所在的主机利用linux的network namespace隔离,形成类似桥接的方式,共同使用主机网络平面,每个容器都有自己的ip地址和mac地址,从网络侧来看,他们是平级的。



从上图可以得知从主机网络侧来看,MacVLAN的主机网口会出现多个IP地址与MAC地址对,而IPVLAN会出现多个IP同一个MAC地址的情况,这也是为什么在IaaS层实施这类容器方案时,需要打开PortSecurity或混杂模式的原因。



但很快会遇到新的问题,比如网络地址分配,也就是 IPAM 不好统一,容易发生 IP 争抢,因为在MacVLAN的方案中,同一网段的IP,一部分给了容器使用,另一部分给了其他主机使用,没有统一的 IPAM,容器的IP地址通过外部DHCP服务来分配(若整个网段都是用DHCP,也勉强算是个统一的 IPAM 吧),如果是实现真正的集中统一的 IPAM 服务,那么他的管理权归网络运营部门呢,还是应用与基础架构一体的云平台运营部门呢,所以后来又进入了underlay的第二阶段,路由(routing)模型


路由模型最大的不同,一言以蔽之,所有容器所在的主机不再是个bridge,而是个router,每个主机就变成一个虚拟路由器,这个主机上所有的pod都不是直接与外界二层打通,而是作为其所在主机的内网成员,出现在主机的路由表中,主机与主机之间通过维护自身的路由表和学习其他主机的路由表,来达到根据pod数据包的目标地址来决定是转发到本地另一个pod中,还是去其他的主机,双方都能看见对方的原始IP地址,从现有基础网络也可以抓到以原始 Pod IP 作为原始地址的报文。作为路由模型最常见的实现是例如Flannel的HostGateway或者calico。



Flannel-HostGateway来讲,整个集群会先定一个B类的CIDR,此后每加入一个集群节点,就自动分配一个C类的IP地址段,Pod被调度到哪个节点,就会使用哪个C段的空闲IP,所以模型比较简单,IPAM逻辑也比较简单,很轻量也很好用,网络还能抓包,Flannel这个HostGateway模式解决了隧道到来的一系列问题,同时也限制集群了不能跨VLAN,因为两个网段间的三层设备没有两端容器网络地址段的路由信息,也就不会转发,另外,也无法固定Pod的IP地址,哪怕是固定到一个IP地址范围,除非定点部署,让Pod与Node节点亲和,因为IP是按段分给节点的,并不是面向Pod的,每个Pod的地址分配只是每个节点查了查本地的C段有哪个IP地址还没用,所以Flannel不管哪种模型,也仅仅是解决了集群内Pod连通的问题,这其实也符合Kubernetes对集群内部网络的原始诉求。


Calico就比较有意思了,相比Flannel的“不足”,它可以通过标准的BGP协议,把这些路由信息通告给外部支持BGP协议的网络设备,这样就实现了与现有网络的打通,与外部网络一起形成一个完整的路由拓扑,在实现容器网络区域自治的同时,也保证了现网网络规划和管理的独立性,在IP地址的分配上,Calico已经开始有独立的IPAM服务,能够将地址段分配粒度细化到与Kubernetes的namespace绑定,甚至是Pod级别,这不仅仅解决了Pod IP 路由可达的问题,更是为云上云下的访问控制策略提供了必要的条件。



下一次,我们将为大家分享在生产云中,基于SDN环境如何交付和管理容器网络,当然也有我们踩过的那些坑。


撰稿人 | 邢   佳

责任编辑 | 张子鑫


邢佳

作者

邢佳,北银金科云计算应用部,京小科容器云产品架构师,和一帮志同道合的小伙伴一起,在云原生的路上持续踩坑。






招聘启事


北银金融科技有限责任公司根植于北京银行,是一家致力于大数据、人工智能、云计算、区块链、物联网等新技术创新与金融科技应用的科技企业,公司充分发挥北京银行企业文化和技术积淀先天优势,通过对技术、场景、生态的完美融合,输出科技创新产品和技术服务。


现诚邀优秀人才加盟

共享金融科技时代硕果


扫描此二维码

期待您的加入





文章转载自北银金科逐浪青春,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论