K8S的网络接口CNI及灵雀云的实践

K8S的网络接口CNI及灵雀云的实践

K8S的网络模型

我们从底层网络来看,分为三个层面。首先是Pod之间的多个容器的网络互通。我们知道,K8S的Pod可以由多个容器组成,这个层面网络互通是比较简单的,因为所有的容器都是共享一个网卡,可以直接通信。

第二个,一台虚拟机上多个容器之间的网络是如何通信的。这块儿其实也比较好解决,例如Docker会搭一个网桥,让上面所有的东西、网卡接到网桥上,他们之间的网络就可以互通。Docker默认服务会创建一个Docker0的网桥,其它主流的像Calico、Flannel的模式也是类似的。这种方式的实现也是现在的主流。

第三种是比较难的,Docker一开始就没有做好,是跨主机的Pod之间的网络通信。对于K8S来说,这个网卡如何分配其实K8S是没有定义的。不同Pod跨主机网络之间如何通信、如何打通网络,K8S不管,是交给第三方实现的。在这块,是有很多工作可以做的。

容器网络设计给运维人员带来的困惑

现在我们再想一些问题,容器网络设计会给传统运维工作带来怎样的困惑?

传统运维工作强调对IP要有很强的管控。容器时代,Pod需不需要有固定的IP?Pod重启之后,IP是否不变?其实K8S没有规定,而且从大部分主流的实现来看,容器IP是可以变的。既然容器的IP是会变的,就会带来一个很直接的问题,我想访问这个服务怎么访问?之前两位同事讲过很多,我不做很细的介绍。

这个大致的原理是,尽管底层Pod IP不断变化,但是我会给你提供固定的域名或者DNS的方式,或者固定的Cluster IP的方式等等。不管Pod方式如何变,总会给你固定的方式,通过固定的方式可以访问到一直变化的IP,这些方式都是通过Kube-proxy、iptables、Kube-dns实现。

我们实际测的时候发现,K8S的服务发现功能比较少,随着访问量越来越大,会发现它的性能有很多问题,还有稳定性也有很严重的问题,而且它的稳定性缺陷是它从设计当初就很难避免。我们正在改进这些设计缺陷问题。

为此很多人就会问,说你的容器IP是一直变的,怎么管?但容器就是这样的,容器生命周期很短,不断创建、不断消失,IP肯定不断变。容器的好处是,你可以在这台机器上挂,在另外一台机器也可以。但运维人员首先觉得IP这样飘不好。对于运维来说,网络方面是很重要的资源,要对IP进行强管控,服务来回飘,会让他的安全感下降很多。

运维服务有很多基于IP的东西,有流量和突发的监控,如果你服务的IP一直变化,通过这个IP它很难用到这个服务,相当于IP的监控就没有意义,因为根本不知道IP流量上去了是哪个服务的,很难对应到这个事。

还有是对于IP安全策略没有办法做。如果以前IP是固定的,iptables或者网络底层防火墙,这样的东西都是很好做的,可以很好的进行服务之间的安全访问限制。如果IP都是变的,这个事情就变得没有办法做了。

第四是定位分析和数据处理问题。我们见到,有的客户把网络正常在跑的所有流量镜像一份,每天对复制的流量进行分析,看你有没有违规操作或者有什么恶意攻击,或者哪些行为不正常,这样他们通过IP再定位服务。如果IP是变的,相当于把他们很多能做的事情去掉了。

还有一些特殊的软件,他们的license是根据网卡来的,就是说他的license是根据网卡的IP加上Mac计算出来的。这种情况下相当于IP变了,license失效,软件跑不起来。

还有你的IP不断变化,实际中也有问题,有很多服务和软件就是基于IP部署的,基于IP相互发现的,最典型的是Etcd这样的。如果你是用K8S或者其他的容器,IP是变的,这个东西怎么填都是很难的事情。

K8S有它的解决方案,Headless Server和 Stateful Set可以做这个事情。但是这个事情在我看来有两个问题,它引入两个不好理解的概念,如果大家对K8S比较关心,第一次看,我觉得你看好半天才能明白它干什么,它为什么这么设计。它的核心理想是你的Pod IP是变的,然后给Pod一个顺序,给每个Pod一个标志符,etcd1、2、3,给他们三个人每个人用k8s Service+域名,你在里面不用填IP,填对应的三个域名就可以。但域名有cash缓存的问题,底层Pod IP失效,域名的缓存没有失效就会造成研判时间的不一致,我觉得靠Service做这件事情也是有问题的,并不能完美的解决这个问题。

为什么Docker、K8S都没有做固定IP的事情?

刚才说了IP不固定的影响,做容器之前大家可能没有想这个事,可能从一开始就认为IP是不固定的,我们想一下如果IP是固定的有什么影响,其实好像还可以用,并且可能变得更简单。比如Cluster IP或者DNS它们的映射由于IP是固定的可能变得更简单了。如果容器的IP固定,运维传统的基于IP的监控也可以做了,因为对他们来说没有影响,和原来是一样的,对他们的接受程度也会更高一点。

我们很多服务发现的方式,可能之前通过K8S的Sevrice来进行服务发现,既然IP固定,我们可以跳过,直接用IP服务发现就可以,没有必要让你的运维理解很复杂的概念。大家会问什么是Cluster IP,什么是Pod,这些还是有理解成本,如果提供原生的方式也是不错的。

可能想到一个问题,既然固定IP还是有好处的,为什么Docker还是K8S都没有做这个事情呢?我觉得一开始Docker没有想好这个事情怎么做。最开始Docker就是一个单机的工具,没有想做得很复杂,最早Docker的网络和存储都是很弱的,它根本没有往这方面想。

还有一点,在我理解就是理念之争。到底服务应该做成有状态的还是无状态的?有Docker之后大家认为容器应该是跑无状态的东西,而不是有状态的东西,但是网络这块是有状态的。我们之前说有状态想到的是存储,认为存储才是有状态的服务,其实网络也是状态的一部分。大家可以想一下,如果Pod里面的服务访问外面,给外部留下的信息是某个IP访问我,所以对外的状态对你来说,IP其实也是你的一个状态,所以说网络其实也是状态的一部分,如果要做有状态这个事情就变得很难。

但是能不能做呢?可以做,我们做了一些尝试,做的方式是我们自定义CNI插件。

如何自定义CNI插件?

CNI,这个概念大家平时听的少一点。它的全称是Container Network Interface,它注重给你的容器提供一套标准的网络的接口。现在包括K8S等都是通过CNI这种方式实现的。CNI 是 CNCF 的一个项目,如果你对比其它项目,CNI应该是里面最简单的。如果你对这个项目有兴趣,从这里开始是比较好的,可能几百行或者上千行的代码就到头了。一个是CNI的标准,包括CNI接口和库,怎么快速实现CNI,还有CNI提供的网络插件。

介绍一下Kubernetes和CNI之间是如何交互的,给大家讲完之后,大家可以比较容易上手,自己实现自己的网络。

这是Kubernetes的基本参数,大家可以看到。红色的标起来的是两个选项。CNI在我看来是有点奇怪的实现。一般的时候一个程序和另一个程序交互,大概是HTTP REST或者是RPC或者TCP的通信,但是CNI和Kubernetes的交互方式是通过二进制文件的方式,它会调用二进制文件传一个参数来做这样的事情。第二张是CNI实现的组件,他们都是以二进制的形式放在目录下面。左下角是CNI的配置,是最简单的,参数很少,还有一些其他比较复杂的。其实比较重要的是type和IPAM。

大概讲一下它交互的流程,是通过创建Pod和销毁Pod两个事件来触发的。创建Pod的时候,它会去调CNI,它会根据这个文件会先调用macvlan,创建一个网卡,然后再分配IP,都是调里面的DHCP和macvlan二进制文件。创建网卡,构建IP,把这个网卡放到Pod network namespace,相当于完成Pod网卡的创建。还有,Pod删除的时候,可能调用二进制文件释放掉,然后删除网卡,完成网卡的销毁。大概的交互比较简单,就这两个,实现的时候也是实现这两个方法就可以。

最下面是main函数,其实有一个库,可以方便实现,照着这个写就可以,需要实现的是下面的函数就可以。函数其它的都不太用着重关注,都是做错误处理。最主要关注上面的,它是在NetNSpath里面创建的一块link,删除的时候再把这块网卡删除,这是最简单的设备创建。如果大家对网络比较熟,或者对自己的网络有特殊的要求或者定制化的需求,其实在里面实现自己的逻辑就可以,整体来说它的逻辑还是比较简单的。而且还有一个功能是多个命令是可以串联的,比如我刚才举的例子,macvlan和DHCP是串联的,macvlan先创建网卡,然后再调DHCP,分配IP,他们之间有一个result的返回,通过result进行数据结构的传输。我们看一下result就可以知道网络还可以做什么别的事情。

这是官方定义的API标准,其实我们也是可以在里面扩充的。上面是interfaces,Kubernetes这个网络做得实在太简单,包括容器中的很多东西都是太简单了,可能一个pod里面有一个网卡设一个IP就完了。其实一个pod里面有多个网卡的需求,一个数据流,一个控制流,这种是可以做的。在它的interfaces里面可以看到有内置的网卡和mac地址,因为我们碰到有些客户,你的mac是可信域才可以做安全策略,这需要你要自定义的mac。再往下,网卡是不是有多个IP,而不是常用的网络,一个容器的一个IP。再往下可以定义这个容器的路由表,包括路由的顺序等等都是可以定义的。再往下是DNS server,容器里面的DNS都可以自定义,容器通信网络这块有很多可以做的事情,如果大家想做这方面,我觉得机会还是很大的。现在的网络说实在的,尽管实现很多,但是都还是蛮弱的。

容器网络方面已经有一些第三方实现,比较知名的有flannel、calico、weave……。下面两项其实是它官方已经实现的,看起来分两大类:一是网卡生成的方式,比如bridge、ipvlan、macvlan、loopback、ptp、vlan。第二大块是IPAM。我不知道大家是否理解IPAM,IPAM的意思是IP该怎么分配。官方实现的有两种,一种是DHCP,一种是host-local。

灵雀云如何通过IPAM做到精确管控IP?

回到之前说的我们要做固定IP,大家可以很容易联想IPAM这块做一些东西,因为这个IPAM是针对IP的,如果要做的话,先看一下现有的两种有没有问题,或者现有的两种怎么实现。DHCP大家比较熟悉,就是自动分配IP,它的问题是没有办法精细管控IP。因为当需要通过主机发再发DHCP的广播再获得IP,相当于容器IP和宿主机的IP混在一起,很难精确分配到某个Pod使某个IP,因为你不知道这些信息。这在实际生产环境用得很少。因为IP管控要求很严格,不可能自己计算IP,我们家里的wifi或者办公才会用到,企业级业务碰到的机会都很少。

host-local,每台机器上都有这个文件,这个文件上规定每台机器能生成一些IP。可以看一下配置文件的格式。其实这两个参数比较重要,一个是rangeStart和rangeEnd,就是每台机器分配的范围是多少。这种分配方式有一个很严重的问题, Calico 和 Flannel都有,就是每台机器都是固定的,这给每台机器划分了一个网关,相当于你Pod是在机器上的,因为IP是很不灵活,很难实现IP的漂移。而且分配IP比较困难,新增机器要重新定义,这台机器用多少IP,要考虑IP段的释放,很不灵活,显然没有办法实现固定IP的事情。

为什么这个事情感觉这么难?我觉得也是K8S设计理念的问题,我们可以看到K8S管了很多东西,管了Pod、configmap、Service等,你会发现它没有管你的IP。理论上来说,IP对你的服务或者对你的集群来说是很重要的资源,但是K8S里面IP不是它的一等应用,甚至你根本没有一个跟容器相关的资源在开发里面找到,所以使得你的IPAM变得很难。你要么通过K8S完全无关的东西来实现,要么通过锁死的方式实现,这其实都是因为你没有把IP资源看得特别重,你只是当做可以随机分配的,所以它设置的理念就是你的IP我不关心,该是什么就是什么,所以导致这样的结果。

最后讲一下我们做的,我们把IP当做很重要的资源,进行单独的管理。我们会专门实现IPAM的组件,实现网段的添加、删除,可以在K8S管理网段,给某个业务或者某几个用户分配一个网关,然后对IP进行网关设置,路由设置,和DNS设置。有了网段之后,有IP的添加删除,会有很重要的资源,该用哪些IP,哪些IP是可以用的,都是可以用管理员指定的,而不是像K8S随机划一个网段,还有权限、配额,之后就可以顺利创建服务了。

现在创建K8S的Deploy的时候需要申明用哪几个IP。如果IP信息传输到IPAM的组件,这个IPAM就是一个数据库,这个数据库就会显示哪些IP可以使用,哪些应该被哪个服务使用,把这个记录下来。在K8S启动Pod,CNI里面再实现一套逻辑,把IPAM的逻辑实现了,那套做的东西会进入IPAM的数据库里面找,如果用就占用这个,别人不能再用,就可以实现每个POD有自己的IP,这个IP是你之前想要的。如果在删除的时候,CNI会把IP释放掉,说明这个IP不会再被这个服务使用,别的服务可以使用这个IP。我们如果想创建etcd的服务,就不用再写一个东西,你只要做你想要的IP就可以,很大的简化你的工作量,而且实现我之前说的传统的运维,IP的监控、管理的东西。

时间: 2024-10-09 06:13:55

K8S的网络接口CNI及灵雀云的实践的相关文章

从微软到灵雀云:一个理工男的“云上云”之路

2015年10月20日 作者: 转载 目录: 媒体报道 评论: 没有评论 导读:这家刚刚完成1000万美元A轮融资的Docker云计算平台公司,陈设与作派处处透露着理工男的实用主义.‌‌ 灵雀云办公室的会客区里,那张银灰色宜家沙发,是从去年公司初创的公寓里搬来的.CEO左玥迎面走来,牛仔裤,运动鞋,胡子拉碴. “这些办公椅是上一家公司留下来的,五十块一把,我们给买了”,左玥对i黑马记者说.这家刚刚完成1000万美元A轮融资的Docker云计算平台公司,陈设与作派处处透露着理工男的实用主义. 灵雀

Jenkins官方社区携手灵雀云成功举办Jenkins Meetup

10月27日,由 Jenkins 官方社区和灵雀云主办的 Jenkins 插件开发 Meetup 在北京中科曙光大厦成功举办.这是Hacktoberfest(即 Hack October Festival,十月"黑客"庆典)黑客马拉松活动的一部分. 灵雀云DevOps高级研发工程师赵晓杰作为出品人全程主导了此次Meetup.他本人也是Jenkins中文社区的重要贡献和维护者.他和现场开发者分享了为何要参与开源社区.如何参与.并现场演示Jenkins插件开发,开发者动手操作. 为什么要参

杰蛙&灵雀云 最“库”管理 容器DevOps最佳实践沙龙

报名链接:https://www.bagevent.com/event/6462063 杰蛙&灵雀云 最"库"管理 容器DevOps最佳实践沙龙 原文地址:https://blog.51cto.com/jfrogchina/2485420

9 年云原生实践全景揭秘|《阿里巴巴云原生实践 15 讲》正式开放下载

以容器.服务网格.微服务.Serverless 为代表的云原生技术,带来一种全新的方式来构建应用.同时,云原生也在拓展云计算的边界,一方面是多云.混合云推动无边界云计算,一方面云边端的协同.在云的趋势下,越来越多的企业开始将业务与技术向“云原生”演进. 在这个演进过程中,企业都或多或少都面对一些困惑与挑战,其中如何将应用和软件向 Kubernetes 体系进行迁移.交付和持续发布是一个普遍的难题. 阿里巴巴从 2011 年开始通过容器实践云原生技术体系,在整个业界都还没有任何范例可供参考的大背境

重磅发布 | 《不一样的 双11 技术,阿里巴巴经济体云原生实践》电子书开放下载

2019 双11,订单创新峰值达到 54.4 万笔/秒,单日数据处理量达到 970PB,面对世界级流量洪峰,今年的阿里巴巴交出了一份亮眼的云原生技术成绩单,并实现了100% 核心应用以云原生的方式上云: 双11 基础设施 100% 上云 支撑 双11 在线业务容器规模达到 200 万 采用神龙弹性裸金属服务器计算性价比提升 20%? 这些数据背后是对一个个技术问题的反复尝试与实践.这一次,我们对云原生技术在 双11 的实践细节进行深挖,筛选了其中 22 篇有代表性的文章进行重新编排,整理成书<不

软交所“猎豹移动运营环境云平台实践”主题沙龙成功举办

2014年8月6日下午,由软交所举办的"猎豹移动运营环境云平台实践"主题沙龙活动在中关村知识产权大厦二层软交所第一会议室成功举办. 为向各会员企业普及私有云的概念,促进会员企业之间相关业务交流,软交所特邀请猎豹移动(金山网络)技术VP 杨钢为大家分享了猎豹移动在复杂运营环境中逐步实施私有云方案的一些经验.新致软件.中科同向.数讯达通信.广点广告传媒.IT决策人网.唐密科技.飞鸟视界科技.麒麟网.中电普华.达沃时代.简单科技等40余家会员单位的企业领导.代表参加了本期沙龙. 分享嘉宾:杨

由浅入深SCF无服务器云函数实践

欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:陈杰,腾讯云架构平台部技术专家 近年来,互联网服务从一开始的物理服务器托管,虚拟机,容器,发展到现在的云函数,逐步无服务器化,如下表所示.程序员逐步聚焦于最核心的业务逻辑开发,解放了生产力,显著提升了服务上线效率. 云函数带来了真正的计算服务,如下表所示,类比腾讯云COS对象存储,SCF以函数为单位封装计算,按需调度执行,无须关心函数的自动扩缩容,故障容灾等,无任何闲置成本. 云函数给用户带来的价值主要4点: 简化架构:函数粒度的微服

云原生实践之 RSocket 从入门到落地:Servlet vs RSocket

技术实践的作用在于:除了用于构建业务,也是为了验证某项技术或框架是否值得大规模推广. 本期开始,我们推出<RSocket 从入门到落地>系列文章,通过实例和对比来介绍RSocket.主要围绕RSocket如何实现Polyglot RPC.Service Registry. Service Discovery. IoT联结等维度,为读者们揭开RSocket的面纱,希望对大家在Java API规范的技术选型过程中有所借鉴. 第一篇文章我们将通过Servlet和RSocket的对比,快速了解RSoc

如何基于 k8s 开发高可靠服务?容器云牛人有话说

?? k8s 是当前主流的容器编排服务,它主要解决「集群环境」下「容器化应用」的「管理问题」,主要包括如下几方面:?? 容器集群管理 编排? 调度? 访问? ? 基础设施管理 计算资源? 网络资源? 存储资源?? k8s 的强大依赖于它良好的设计理念和抽象,吸引了越来越多的开发者投入到 k8s 社区,把 k8s 作为基础设施运行服务的公司也逐步增多.?在设计理念方面,k8s 只有 APIServer 与 etcd (存储) 通信,其他组件在内存中维护状态,通过 APIServer 持久化数据.管