如何解决容器网络性能及复杂网络部署问题?

近两年,容器已经随着 Docker 技术的传播火遍全球,如今已经有愈来愈多的企业用户在开发、测试甚至生产环境中开始采用 Docker 等容器技术。linux

然而,目前主流的 Docker 管理平台,好比 K8S,当企业想构建一套网络方案,须要精通 Linux 提供的各类高级网络功能,这个技术门槛过高了。特别是对专一于业务开发的 Docker 用户而言,这类操做每每显得过于复杂。后端

并且,因为在虚机中部署容器,云平台和 Docker 平台都有本身的虚拟化网络实现方案,两者功能重叠,使用时会相互嵌套,致使的其网络性能损耗很是严重,甚至达到 80%。安全

因此,虽然容器技术正在逐步被你们承认与应用,但其网络性能以及配置的复杂程度一直都在被你们所诟病。今天的内容,将会给你们介绍一种容器部署方案,帮助你们解决网络这个难题。服务器

Docker的网络模型架构

首先,咱们先看看 Docker 提供了哪些网络功能,Docker 的网络模型是这样的:网络

 

图片描述

 

Docker 的网络结构分为 3 个层次:Network、Endpoint 和 Container。对比到物理设备能够这么理解:Network 是交换机,Endpoint 是网卡,Container 就是服务器。架构

决定 Network 这个交换机的工做方式的组件,就是 Network Driver。经常使用的 Driver 有两个:负载均衡

  • Bridge
  • Overlay

Bridge Driver分布式

Bridge Driver 是种比较直接的方式:Bridge 指的是 Linux Kernel 实现的虚机交换机。每一个网络在宿主机上有一个 Bridge 实例,默认是 Docker0,有对应的 IP 地址和网段,每一个 Docker 实例从网段里面分配一个地址。结构以下:性能

 

图片描述

 

在同一个 Bridge 下的 Endpoint 是一个二层网络,要实现跨宿主机的 Endpoint 之间通讯,只能走三层网络,也就是经过路由转发过去。要对外提供服务,还须要对宿主机的 IP 端口作转换(Nat)。这种状况下主要网络性能损失发生在端口转换(Nat)和路由上面。测试

同时这也和青云 SDN 1.0 里面的基础网络实现方式是彻底同样,优势是结构简单可靠,缺点也很明显: 不能把多个宿主机连成一个二层网络。这个问题会致使 Docker 实例的 IP 地址,必须跟当前宿主机定义的网段一致。若是启动到别的宿主机上,IP 就须要更换。

Overlay Driver

Overlay Driver 的做用是把位于多个宿主机的 Docker 实例链接在一个虚拟的二层网络里面。相比 Bridge,在功能上有必定进步,本质上是一个分布式的虚拟交换机。

举个送快递的例子,方便你们理解:有的公司对员工提供内部邮件的服务,位于不一样写字楼的员工能够用工位号互发邮件。公司的收发室拿到邮件后,会从新再打个包,上面写着双方写字楼的地址,交给真正的快递公司去投递。收件方的收发室会拿到邮件后,会拆掉外面的信封,把里面的邮件按工位号送给收件的员工。

这例子里面,工位号就是 Underlay 的地址, 写字楼的地址是 Overlay 的地址。Docker 的这个虚拟二层网络,就是企业内部邮件,可是真正派件的仍是快递公司。跟普通快递相比,多了个环节:收发室对邮件从新包装,不只打包费时间,多的包装也占了重量,也就带来了额外的性能损失。

目前,Overlay 模式的虚拟网络应用已经很广泛,青云给用户提供的虚拟二层网络也是相同的工做原理。

容器的部署方式

Docker 目前有两种方式部署:

  • 私有环境物理机部署
  • 公有云虚拟机部署

今天和你们分享的就是为何要在云平台上部署 Docker。

虽然看起来在公有云的虚拟机部署 Docker 的作法比较奇葩,目前也没有公有云能让用户直接部署 Docker 在物理机上,固然,Softlayer 这种物理机托管的云除外。

由于 Docker 自己的安全性还不够让人放心。虽然 Docker 已经有各类安全保护,包括 Namespace 提供的隔离机制、Selinux、Apparmor 等安全机制,以及最近才有的Unprivileged Container 功能来控制 Docker 实例在宿主机上的用户权限,可是因为容器的本质是跟宿主机共用同一个 Linux Kernel,一旦 Kernel 自己有安全漏洞,就有可能被 Docker 用户利用,侵入到云平台的物理机。

好比几个月前发现的 COW 漏洞,就有可能让 Docker 实例得到物理机的 Root 权限,实现容器的“越狱”。这个漏洞存在了十几年才被人发现,彻底有可能还有不少相似漏洞存在,只是没有被公开而已。

因此,公有云直接让用户在多租户的物理机上运行 Docker,是极不安全的作法。

所以,要在公有云使用 Docker,就只有在虚拟机里面运行 Docker 这一个选择。那么在公有云上部署 Docker 业务,存在哪些问题呢?其实,主要仍是性能和功能两方面。

网络性能

网络虚拟化的本质是用软件实现物理网卡和交换机的功能,所以虚拟网络中的全部流量都会消耗 CPU 资源。

Linux 在处理网络流量时,有几个方面会消耗 CPU:

  1. 地址转换(Nat);
  2. 三层路由转发;
  3. Vxlan 封装;
  4. 二层转发;
  5. 虚拟机的 Kernel 和宿主机 Kernel 之间的转发。

其中 1 和 2 占的 CPU 消耗较高,这是由于地址转换和路由都会对数据包的包头作修改,并从新计算 Checksum, 并且地址转换还须要查询 Conntrack 的链接表和 IPtables 的地址转换规则,这些功能都是全靠宿主机的 CPU 完成。

云平台提供的 SDN 网络,是第一层网络虚拟化,已形成必定的性能损失。可是能够经过利用物理网卡的硬卸载功能,好比 Vxlan Offload, 具体包括 Gso、Gro、Rx Checksum 等在这一层减小虚拟化带来的部分性能损失。

虽然容器自己因为跟宿主机共享 Kernel 的这个特性,相比 VM 网络性能更好,没有 第 5 条的损失,可是 Docker 搭建的虚拟网络,仍然会带来显著的性能损失。

同时,因为第二层虚拟化没法利用硬卸载功能,因此性能损失一般会高于第一层。两层网络虚拟化带来的性能损耗相叠加,将显著影响网络性能。

举个例子:

在上海一区(SH1A),使用 IPerf -C 命令进行的基本性能测试 (关闭云平台的网络限速)结果以下:
虚拟主机之间:带宽 9Gbps;
虚拟主机内:使用 Docker Overlay 插件的 Docker 实例之间带宽降低为 2.3 Gbps。

因而可知,这种使用 Docker Overlay 的方案会带来近 3/4 的性能损耗。而若是算上对外提供服务所须要的地址转换带来的性能损失,总体性能损失将更为巨大。

配置复杂

首先,Docker 自身的网络复杂。Bridge 和 Overlay 都须要配合地址转换功能使用,而地址转换的规则不只多,并且复杂。

我最近遇到个私有云客户,其在云平台上面部署基于 K8S 的业务系统。他们遇到一个问题,同一个宿主机的 Docker 实例之间,用 K8S 提供的业务 IP 没法访问,而不一样宿主机之间用相同的 IP 访问正常。

这个开发团队,通宵加班好几天,也没搞清楚怎么回事,来找我帮忙解决。这个问题其实是由于 K8S 少下发了一条 IPtables 规则,没有对同宿主机的这种状况作源地址转换。

这个问题对熟悉 Linux 网络功能的人来讲,不是什么难题,可是对专一于业务开发的 Docker 用户而言,可就很难解决了。

我说这个例子的目地就是要说明,配置 Docker 虚拟网络是件难度很高的事情。

另外一方面,要在云平台上面,使用 Docker 对外提供服务,还须要跟云平台的网络作整合。

一般是在云平台的 IP 和 Docker 的 IP 之间作地址转换。自己 Docker 实现这些功能就比较复杂,而在此基础上,再作一层地址转换,会带来额外的复杂度。

使用 Docker 管理平台的初衷是简化产品部署,而经过这样的方式跟云平台整合,却与这一方向背道而驰。

如何解决容器网络性能及复杂网络部署的问题

性能问题的根源在于云平台和 Docker 平台都有本身的虚拟化网络,两者功能重叠,使用时相互嵌套。而配置复杂的难度一个是 Docker 自身网络复杂,另外一个方面是跟云平台的网络整合也复杂。

目前青云的 SDN 直通方案经过让 Docker 实例挂载云平台提供的虚拟网卡的方式,让 Docker 实例直接使用云平台的 SDN 功能,代替 Docker 的虚拟网络。

一方面减小了第二层虚拟网络的性能损失;另外一方面,云平台的 SDN 是经过 API 和控制台封装好的服务,Docker 直接使用就能够了,不须要本身再配置 Docker 的网络,因此大幅下降了使用难度。

SDN 网络直通方案包含两个方面:

  • 云平台网卡管理:经过提供网卡接口,让虚拟主机可以挂载多个网卡。这些网卡能够属于相同或者不一样的网络,同时每一个网卡可以管理本身的私网 IP、公网 IP、负载均衡器和防火墙等功能。
  • 插件:这是青云Qingcloud 自主开发的一款 Docker 网络插件。在启动 Docker 实例的时候,经过该插件,能够将虚拟主机上的绑定的多个网卡一一挂载到 Docker 实例上, 并能够配置 IP 地址和路由。启动以后,Docker 实例就加入了云平台 SDN 提供的网络,可以使用云平台全部的网络功能。

插件已经开源,地址是 https://Github.Com/Yunify/Docker-Plugin-Hostnic

这是青云Qingcloud 自主开发的一款 Docker 网络插件。在启动 Docker 实例的时候,经过该插件,能够将虚拟主机上的绑定的多个网卡一一挂载到 Docker 实例上, 并能够配置 IP 地址和路由。

启动以后,Docker 实例就加入了云平台 SDN 提供的网络,可以使用云平台全部的网络功能。云平台网卡管理,就是可以让虚拟主机挂载多个网卡。网卡对应到 Docker 的网络组件,就是Endpoint,这个设备受云平台管理,底层由 SDN 内部的控制器下发规则,可使用 DHCP 管理 IP 地址,并接入全部云平台的网络模块。

相比 Docker 的网络功能,青云的网卡能够提供更多的功能:

VPC

前面说过,Docker 的 Overlay 网络其实是虚拟的二层网,而 VPC 提供的是一个虚拟的三层网。能够理解为一个分布式的核心交换机。青云的 VPC 最多能够建立 252 个虚拟网络,容纳超过 6 万台虚拟主机。

就技术上来看,虚拟二层网使用 Vxlan 实现,是如今较成熟的技术。而虚拟的三层网,是 SDN 技术的一个关键点,由于它背后须要有个分布式网关才能作到虚拟机数量增长时,VPC 总体网络性能不变。

目前 SDN 厂商和技术好的云计算公司都有各自的实现,尚未看到靠谱的开源产品可以作到。

当 Docker 挂载上青云的网卡时,就加入了对应的 VPC,跟其余实例连在了一块儿。用户能够根据网卡对应的网络来定义实例间是二层仍是三层联通。

公网 IP

每一个网卡能够绑定本身独享的公网 IP,也可使用 VPC 共享的公网 IP 对外提供服务。公网和私网地址的转换,由云平台的分布式网关来作,不须要 Docker 配置任何 IPtables 规则。

负载均衡器

网卡能够做为负载均衡器的后端,以集群的方式,对外提供高可用和高性能的服务。相比 Docker 的负载均衡器,青云的负载均衡器有许多优势:

  • 4层/7层全透明,后端服务器能直接拿到客户端的源 IP 地址。这个功能是我在青云作的第一个项目,到目前,在云计算的负载均衡器服务中仍然是独有的功能,世界上别的公有云都没有作到。
  • 水平扩展能力,用户能够经过修改集群节点数量,扩展网络带宽和 HTTPS 卸载能力。
  • HTTPS 转发策略等等不少配置选项,要比 Docker 或者 K8S 实现的负载均衡器的选项丰富不少。
  • 防火墙。每一个网卡均可以独立配置本身的防火墙过滤规则,这个功能在 Docker 上还没见到。

给虚拟主机挂载网卡以后,须要使用到 Hostnic 插件,有 3 步:

  1. Docker-Plugin-Hostnic 是个 Docker 像,把它启动成 Docker 实例,效果就是加载了一个叫 Hostnic 的 Docker 网络插件;
  2. 建立 Docker 网络。好比:Docker Network Create -D Hostnic –Subnet=192.168.1.0/24 –Gateway 192.168.1.1 Hostnic,其中网段和网关是网卡在 VPC 对应的网络的属性;
  3. 启动 Docker 实例,传入网卡对应的 Mac 和 IP 地址。好比: Docker Run -It –Ip 192.168.1.5 –Mac-Address 52:54:0E:E5:00:F7 –Network Hostnic Ubuntu:14.04 Bash。

这样就完成了对 Docker 实例网络的全部功能配置。

前面说的公网 IP、负载均衡器和防火墙,均可以经过青云控制台、SDK、 CLI 或者 API 的方式去单独配置。对这些功能使用上有疑问的话,能够经过工单跟咱们的工程师沟通,没必要在死磕 Docker 那些复杂的网络配置。

除了青云本身研发的 Hostnic,如今已经有另一款 Docker 插件支持青云 SDN 直通。是希云Csphere 开发的 Qingcloud-Docker-Network,一样也已经开源: Https://Github.Com/Nicescale/Qingcloud-Docker-Network

跟 Hostnic 相比,这款插件整合了青云 API,可以在启动 Docker 实例时,自动建立,并绑定网卡,使用起来更方便一些。

对于公有云,目前只能选择在虚拟主机里面使用 Docker,可是对于私有云,能够在青云提供的容器主机里面部署 Docker。

容器主机的工做原理跟 Docker 同样,都是用到了 Linux Kernel 的容器技术,可是用起来更接近虚拟主机,有着几乎相同的功能,好比:挂载 SSH 密钥、Web Terminal、镜像制做、备份等功能,跟虚拟主机镜像全兼容,还能作到在线扩容 CPU、内存、系统硬盘。

也就是说,对于私有云用户,可使用跟公有云虚拟主机彻底同样的操做方式,在容器主机里面部署 Docker,从而减小 KVM 虚拟化这一层在性能上的损失,能达到接近物理机的性能。

跟直接在物理机上部署 Docker 相比,使用容器主机能够有云平台便捷的功能,好比秒级建立或者消毁一个容器主机。云平台的副本能够保证物理机宕机后,经过离线迁移,迅速恢复业务。再加上前面说的这些云平台的网络功能,为构建用户业务集群,节省大量时间。同时青云的 SDN 网络在 Linux Kernel 上有深度优化,相比直接在物理机上使用 Docker 的 Overlay 网络性能还会好很多。

相关文章
相关标签/搜索