DockOne微信分享(一三八):白话Kubernetes网络

本文讲的是DockOne微信分享(一三八):白话Kubernetes网络【编者的话】容器的网络是在CaaS集群中无法避免的话题,作为当下最主流的一种容器集群解决方案,Kubernetes对网络进行了合理的抽象,并采用了开放的CNI模型。面对各种容器网络实现,他们有什么不同,应该如何选择?本文将带大家回顾Kubernetes各种主流网络方案的发展历程,并透过现象清本质,用形象的例子展示Weave、Flannel、Calico和Romana等网络解决方案背后的原理。

【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。

这次讲一讲容器集群中的网络。其实不同的容器集群解决方案,在网络方面的核心原理都是相似的,只不过这次我们将以Kubernetes为线索,来窥斑见豹的一睹容器网络的发展过程。

我是来自ThoughtWorks的林帆,我们从Docker的0.x版本开始就在对容器的应用场景进行探索,积累了一线的容器运用经验。这次分享会用简洁易懂的方式告诉大家我们对容器网络方面的一些知识归纳。

初入容器集群的人往往会发现,和单节点的容器运用相比,容器的网络和存储是两个让人望而却步的领域。在这些领域里,存在大量的技术名词和术语,就像是一道道拒人于门外的高门槛。

为了便于理解,我们将这些名称简单的分个类别,从简单到复杂,依次递增。今天的话题会涉及的深度大致在这个大池子的中间,希望大家看完以后会对目标线以上的内容不再陌生,目标线以下的内容我们也会依据需要适当的提及。

此外,这个话题会按照Kubernetes的网络发现过程作为时间主线,其中重点介绍CNI标准和它的主流实现。

在早期的Kubernetes中,对网络是没有什么标准的。文档中对网络的描述只有很简单的几句话,其实就是让用户在部署Kubernetes之前,预先准备好容器互联的网络解决方案。Kubernetes只对网络提出设计假设,这三条假设总结起来就是:所有容器都可以和集群里任意其他容器或者主机通信,并且通信双方看到的对方IP地址就是实际的地址(即不经过网络地址转换)。

基于这样的底层网络,Kubernetes设计了Pod - Deployment - Service的经典三层服务访问机制。

既然Kubernetes不提供底层网络实现,在业界就出现了很多企业级的以及开源的第三方解决方案,其中下面这页图中展示了这个时期的主流开源方案。

我们将这些方案依据配置的复杂度,分为“全自动”和“半自动”两类,就像是汽车中的自动挡和手动挡的差别。

“全自动”的解决方案使用起来简单,适用于标准网络环境的容器跨节点通信。

“半自动”的解决方案实际上是对底层协议和内核模块功能的封装,提供了选择十分丰富的网络连接方法,但对使用者的网络原理知识有一定要求。

在Kubernetes的1.1版本中,发生了一件很重要的变化,那就是Kubernetes全面采纳CNI网络标准。

CNI诞生于2015年4月,Kubernetes的1.1版本诞生于2015年9月,之间仅隔5个月。在这个时期,Docker也设计了一套网络标准,称为CNM(即Libnetwork)。Kubernetes采用CNI而非CNM,这背后有很长的一段故事,核心的原因就是CNI对开发者的约束更少,更开放,不依赖于Docker工具,而CNM对Docker有非常强的依赖,无法作为通用的容器网络标准。在Kubernetes的官方博客里有一篇博文详细讨论了个中细节,InfoQ上有一篇该博客的翻译,有兴趣的读者不妨一读。

几乎在Kubernetes宣布采纳CNI以后的1个月,之前提到的“全自动”网络方案就悉数实现了CNI的插件,这也间接说明了CNI的简单。

那么CNI到底有多简单呢?举几个数字。

实现一个CNI插件需要的内容包括一个Json配置文件和一个可执行的文件(脚本或程序),配置文件描述插件的版本、名称、描述等基本信息,可执行文件就是CNI插件本身会在容器需要建立网络和需要销毁容器的时候被调用。

当一个CNI插件被调用时,它能够通过6个环境变量以及1个命令行参数(Json格式文本)来获得需要执行的操作、目标网络Namespace、容器的网卡必要信息,每个CNI插件只需实现两种基本操作:创建网络的ADD操作,和删除网络的DEL操作(以及一个可选的VERSION查看版本操作)。

最新的CNI规范可以通过上图中的链接访问,只有一页网页的内容而已。同时Kuberntes社区也提供了一个利用“docker network”命令实现的简单CNI插件例子,只用了几十行Bash脚本。

那么面对这么多的社区CNI插件,我们怎样选择呢?

直观的说,既然是网络插件,在功能差不多的情况下,我们当然先关心哪个的速度快。

为此我此前专门做过一次对比测试,不过由于使用了公有云的网络环境(云上环境的不同主机之间相对位置不固定),在汇总数据的时候才发现测试结果偏离理论情况过于明显。

这个数据大家且当娱乐,不过对于同一种插件的不同工作模式(比如Flannel的三种模型)之间,由于是使用的相同的虚拟机测试,还是具有一定可参考性。

先抛开测试结果,从理论上说,这些CNI工具的网络速度应该可以分为3个速度等级。

最快的是Romana、Gateway模式的Flannel、BGP模式的Calico。

次一级的是IPIP模式的Calico、Swarm的Overlay网络、VxLan模式的Flannel、Fastpath模式的Weave。

最慢的是UDP模式的Flannel、Sleeve模式的Weave。

这里我也提供出测试容器网络速度的具体方法,以便大家重复这个测试。

要解释这些网络插件和模式速度不同的原因,我们需要先回到这些工具最初要解决的问题上来。那就是跨节点的网络不通。

如果仔细观察,会发现在3种网络速度模式中都有Flannel的身影。因此我们不妨先以Flannel为例来看这些网络工具(和相应的CNI插件)是如何解决网络不通问题的。

跨节点网络不同有几个方面的原因,首先是容器的地址重复。

由于Docker等容器工具只是利用内核的网络Namespace实现了网络隔离,各个节点上的容器是在所属节点上自动分配IP地址的,从全局来看,这种局部地址就像是不同小区里的门牌号,一旦拿到一个更大的范围上看,就可能是会重复的。

为了解决这个问题,Flannel设计了一种全局的网络地址分配机制,即使用Etcd来存储网段和节点之间的关系,然后Flannel配置各个节点上的Docker(或其他容器工具),只在分配到当前节点的网段里选择容器IP地址。

这样就确保了IP地址分配的全局唯一性。

是不是地址不重复网络就可以联通了呢?

这里还有一个问题,是对于不同的主机、以及网络上的路由设备之间,并不知道这些IP容器网段的地址是如何分配的,因此数据包即使被发送到了网络中,也会因为无法进行路由而被丢掉。

虽然地址唯一了,依然无法实现真正的网络通信。

为此,Flannel采用了几种处理方法(也就是Flannel的几种网络模式)。

早期时候用的比较多的一种方式是Overlay网络。

在这种方式下,所有被发送到网络中的数据包会被添加上额外的包头封装。这些包头里通常包含了主机本身的IP地址,因为只有主机的IP地址是原本就可以在网络里路由传播的。

根据不同的封包方式,Flannel提供了UDP和Vxlan两种传输方法。

UDP封包使用了Flannel自定义的一种包头协议,数据是在Linux的用户态进行封包和解包的,因此当数据进入主机后,需要经历两次内核态到用户态的转换。

VxLAN封包采用的是内置在Linux内核里的标准协议,因此虽然它的封包结构比UDP模式复杂,但由于所有数据装、解包过程均在内核中完成,实际的传输速度要比UDP模式快许多。

但比较不幸的是,在Flannel开始流行的时候,大概2014年,主流的Linux系统还是Ubuntu 14.04或者CentOS 6.x,这些发行版的内核比较低,没有包含VxLAN的内核模块。因此多数人在开始接触Flannel时候,都只能使用它的UDP模式,因此Flanned一不小心落得了一个“速度慢”的名声,特别是在之后的Calico出来以后(其实Flannel的Gateway模式与Calico速度相当,甚至理论上还要快一点点,稍后解释)。

这是第一种解决网络无法路由的方法。

第二种思路是,既然在无法进行路由是因为网络中的节点之间没有路由信息,但Flannel是知道这个信息的,能不能把这个信息告诉网络上的节点呢?

这就是Flannel的Host-Gateway模式,在这种模式下,Flannel通过在各个节点上的Agent进程,将容器网络的路由信息刷到主机的路由表上,这样一来所有的主机就都有整个容器网络的路由数据了。

Host-Gateway的方式没有引入像Overlay中的额外装包解包操作,完全是普通的网络路由机制,它的效率与虚拟机直接的通信相差无几。

然而,由于Flannel只能够修改各个主机的路由表,一旦主机直接隔了个其他路由设备,比如三层路由器,这个包就会在路由设备上被丢掉。

这样一来,Host-Gateway的模式就只能用于二层直接可达的网络,由于广播风暴的问题,这种网络通常是比较小规模的,但近年来也出现了一些专门的设备能够构建出大规模的二层网络(就是我们经常听到的“大二层”网络)。

那么其他的CNI插件呢?

由于Flannel几乎是最早的跨网络通信解决方案,其他的方案都可以被看做是Fannel的某种改进版。

比如Weave的工作模式与Flannel是很相似的,它最早只提供了UDP(称为sleeve模式)的网络方式,后来又加上了fastpass方式(基于VxLAN),不过Weave消除了Flannel中用来存储网络地址的额外组件,自己集成了高可用的数据存储功能。

Calico的设计比较新颖,之前提到Flannel的Host-Gateway模式之所以不能跨二层网络,是因为它只能修改主机的路由,Calico把改路由表的做法换成了标准的BGP路由协议。

相当于在每个节点上模拟出一个额外的路由器,由于采用的是标准协议,Calico模拟路由器的路由表信息就可以被传播到网络的其他路由设备中,这样就实现了在三层网络上的高速跨节点网络。

不过在现实中的网络并不总是支持BGP路由的,因此Calico也设计了一种IPIP模式,使用Overlay的方式来传输数据。IPIP的包头非常小,而且也是内置在内核中的,因此它的速度理论上比VxLAN快一点点,但安全性更差。

Cannal将Calico和Flannel做了一下组合,同时支持两者的特性。

Romana只支持与Flannel相同的Host-Gateway模式,但它在网络策略方面做了比较多的增强,通过额外引入的租户概念简化了网络策略所需的IPtables规则数量。

这是几种主流CNI工具的横向对比。

在Kubernetes的1.2版本以后开始引入了一个新的工具,叫做 kubernet,它实现了内置的网络地址分配功能。结合一些云平台上的内网路由表功能,就能够直接执行跨网络通信,相当于把跨网络功能内建到Kubernetes里面了。

这是一个从“只做假设”到“设定标准”到“内置实现”的很大的改变。

在Kubernetes的1.3版本以后,开始加入网络策略相关的支持。并且在1.7版本后结束了Beta阶段,成为正式API的一部分。

值得一说的是,Kubernetes的网络策略采用了比较严格的单向流控制,即假如允许服务A访问服务B,反过来服务B并不一定能访问服务A。这与Docker内置的Network命令实现的隔离有很大不同。

纵向的对比一下主流的容器集群对今天提到的这些网络特性的支持情况和时间点。

Q&A

Q:Kubernetes的网络策略采用了比较严格的单向流控制,即假如允许服务A访问服务B,反过来服务B并不一定能访问服务A。为什么要设计成严格单向流呢?

A:主要是安全性的原因,这是一种更精细的权限控制策略,除了方向,Kuberetes还允许对可访问的端口进行控制。

Q:Open vSwitch有测过么?

A:没有测试,Open vSwitch同样可以配置成Overlay网络或者Macvlan网络等不同的通信模式,速度也会落到相应的档位上。那个测试例子只是为了说明网络速度与采用的通信原理有关,同时引出几种主流的通信模式原理,测试数据是不准确的,建议以在自己的实际环境中测试结果为准。

Q:Calico怎么做网段间的隔离?

A:各种网络工具的网络策略基本上都是基于内核的Iptables模块实现的。比如Calico只是根据用户配置,自动管理各个节点上的Iptables规则。其他有些改进的,比如Romana设计了一种基于“租户”的规则管理机制,可以用更少的Iptables规则实现网络隔离。

Q:如果在Kubernetes里面需要做到平行网络,让每一个Pod获取一个业务IP,除了Bridge+Vlan的方式,还有更好的建议么?

A:这次讲的这些CNI插件都会让每一个Pod获得一个独立业务IP。可以根据实际网络情况和对速度的需求选择。

Q:Calico BGP IPIP NAT三种模式分别怎么配置?原理是怎样的?其中IPIP还有两种模式,区别在哪?

A:在Calico的配置中设置spec.ipip.enabled: ture就会开启IPIP模式,否则默认是纯BGP模式。IPIP的两种模式其实是指纯IPIP(ipip always模式)或者混合IPIP和BGP(ipip cross-subnet),后者指的是“同子网内路由采用BGP,跨子网路由采用IPIP”,主要用于即想在内网获得高速,又想在跨公网时能保持联通的情况。这种模式需要每个节点启动时用--ip参数预先配置节点的子网,并且所有节点版本都在v2.1以上。

Q:能麻烦具体介绍一下kube-proxy这种网络模式的优缺点吗,在测试过程中发现很不稳定,但是又没发现足够的证据。

A:kube-proxy是Kubernetes的一个组件,提供通过Service到Pod的路由,并不是一种网络模式,不同的网络插件都会使用到这个组件。

以上内容根据2017年08月15日晚微信群分享内容整理。分享人林帆,ThoughtWorks DevOps和容器技术咨询师。从事软件开发运维以及社区宣传工作,热衷于对DevOps和容器技术应用的推广,在容器规模化运维方面有较丰富实践经验,著有《CoreOS实践之路》一书。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesa,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。

原文发布时间为:2017-08-22

本文作者:林帆

原文标题:DockOne微信分享(一三八):白话Kubernetes网络

时间: 2024-11-05 20:14:37

DockOne微信分享(一三八):白话Kubernetes网络的相关文章

DockOne微信分享(一二二):探索Kubernetes的网络原理及方案

本文讲的是DockOne微信分享(一二二):探索Kubernetes的网络原理及方案[编者的话]2016年ClusterHQ容器技术应用调查报告显示,一年来容器技术应用于生产的比例增长了96%,Kubernetes的使用率达到了40%,成为了最受欢迎的容器编排工具:那么Kubernetes到底是什么呢?它是一个用于容器集群的自动化部署.扩容以及运维的开源平台:那么通过Kubernetes能干什么呢?它能快速而有预期地部署你的应用,极速地扩展你的应用,无缝对接新的应用功能,节省资源,优化硬件资源的

DockOne微信分享( 九十四):唯品会基于Kubernetes的网络方案演进

本文讲的是DockOne微信分享( 九十四):唯品会基于Kubernetes的网络方案演进[编者的话]本文主要介绍唯品会云平台PaaS在持续集成和持续部署方面,基于Docker和Kubernetes,对网络方案的选型及应用,以及随着业务需求的增加而经历的网络方案变更,包括: Kubernetes + Flannel: 基于Docker libnetwork的网络定制: Kubernetes + Contiv + kube-haproxy: 基于Kubernetes的应用容器IP固定方案. 背景简

DockOne微信分享(一三三):深入理解Kubernetes网络策略

本文讲的是DockOne微信分享(一三三):深入理解Kubernetes网络策略[编者的话]当我们逐渐向着微服务.云原生迈进的时候,传统静态的.相对简单的网络安全策略开始显得吃力. Kubernetes 的 Network Policy 特性正是来解决这个问题的.在刚刚出炉不久的1.7版本中,该特性也被扶正成为GA.让我们来一起看看 Network Policy 是什么,能为我们做什么,以及是如何实现的. [3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站]本次培训围绕基于Dock

DockOne微信分享(一二〇):基于Kubernetes的私有容器云建设实践

本文讲的是DockOne微信分享(一二〇):基于Kubernetes的私有容器云建设实践[编者的话]本次分享将为大家介绍易宝支付私有容器云从0到1的建设之路.包括技术选型.理论基础.基于Kubernetes的容器云和CI/CD落地过程中的挑战和踩过的坑. 建设背景及目标 在Docker技术流行开来之前,保证软件交付的质量和速度对于大多数企业来说都是困难的.业务的复杂性带来了应用的复杂性,面对成千上万的不同应用,运维部门需要时刻应对来自不同应用.不同环境的挑战.特别是在自动化运维程度不高的企业,"

DockOne微信分享(一零六):乐视云基于Kubernetes的PaaS平台建设

本文讲的是DockOne微信分享(一零六):乐视云基于Kubernetes的PaaS平台建设[编者的话]本次分享主要介绍乐视云两代PaaS平台的变迁过程,着重介绍第二代PaaS平台LeEngine的架构设计和遇到的问题. 背景 2014年乐视云开始尝试Docker的推广和使用,我们的团队开始开发第一代容器云平台Harbor (分享网址:http://dockone.io/article/1091 ).(在这里提醒一下,这与VMware公司中国团队为企业用户设计的Docker Registry e

DockOne微信分享(一四三):FreeWheel基于Kubernetes容器云构建与实践:应用编排与服务质量保证

本文讲的是DockOne微信分享(一四三):FreeWheel基于Kubernetes容器云构建与实践:应用编排与服务质量保证[编者的话]随着公司业务不断发展以及逐渐向微服务的转变,我们借助于Kubernetes容器化解决方案来标准化和简化应用发布的整个流程,使原来需要大量人工维护和干预的工作变为自动化.本次内容主要是FreeWheel现阶段基于Kubernetes容器化经验和实践的总结,目标是提供一个持续.稳定.高效的容器云平台. 服务健康检查与自我恢复 对线上业务来说,保证服务的正常稳定是重

DockOne微信分享(一四四):BizCloud:基于Kubernetes的私有云实践

[编者的话]随着搜狗业务的快速增长,需要更有效地控制成本,提升研发效率,我们基于Docker和Kubernetes构建了一站式私有云管理平台--BizCloud,此平台涵盖服务管理.弹性伸缩.灰度发布.自动运维.持续集成等功能.本文将简要介绍BizCloud的设计思路.架构及服务发现.授权.灰度发布等核心功能的实现. BizCloud简介 本文将的是DockOne微信分享(一四四):BizCloud:基于Kubernetes的私有云实践我们基础环境非常复杂,目前有多个版本操作系统共存,应用也常常

DockOne微信分享(一三九):基于Kubernetes的应用编排实践

本文讲的是DockOne微信分享(一三九):基于Kubernetes的应用编排实践[编者的话]近年容器的使用越来越深入,越来越多的服务采用容器的方式进行部署.但随着服务数量的增加,如何管理服务之间的依赖关系,如何对多个服务之间的更新与部署进行管理,如何在新的环境中实现多个服务的快速部署.这些问题都希望通过基于Kubernetes应用编排管理来解决,从而实现对于复杂多服务系统的快速部署和高效管理. [烧脑式Kubernetes实战训练营]本次培训理论结合实践,主要包括:Kubernetes架构和资

DockOne微信分享(七十五):应用容器化之Kubernetes实践

本文讲的是DockOne微信分享(七十五):应用容器化之Kubernetes实践[编者的话]本次分享主要以ZooKeeper.Redis.Kafka.MongoDB等应用容器化在Kubernetes平台上面实践.从计算.网络.存储方面解析应用在集成中的问题,以及部分传统应用在容器化过程中设计的应用二次开发等问题.首先介绍应用Docker化的需求和局限.接着介绍基础平台,整体环境包括Kubernetes和ECP,然后介绍具体应用如ZooKeeper在集成中的实践,最后介绍部分开源应用在容器化过程中