日前,由国内容器社区DockOne 组织的专为一线开发者和运维工程师设计的顶级会议--容器技术大会在京召开,会议围绕容器、运维、云计算等技术领域,全方位、多角度为参会者解读了容器技术。
众所周知,Docker是近几年最火的虚拟化技术,从社区到业界,都吸引了广泛的关注。为此,美团云作为国内领先的公有云服务商,在此次会议上专门分享了半年多以来,美团云在Docker/容器方面的积极探索。
(以下为分享内容实录)
从技术上讲,Docker脱胎于Linux Control Group(Cgroup)和Namespace,属于进程级的虚拟化。在Docker之前,Cgroup,LXC已存在多年,并未像Docker现在这样广受关注。Docker之所以火爆,我们认为主要原因有几点:
1.Docker将复杂的LXC管理配置简化成了一套自己的API;
2.分层的镜像管理体系,为业务提供独立的运行环境,实现build, ship and run everywhere;
3.进程级虚拟化相比操作系统级的虚拟化更轻量,更高性能。
我们目睹了Docker技术正在逐渐改变云计算的生态链,过去可能只有为数不多的厂商敢于在生产场景尝试Docker,随着Docker的快速迭代,目前已经到了1.9.1版本,有理由相信Docker已经具有生产场景所需的成熟度。因此将原有业务Dockerize是目前业界的普遍趋势,但如何使用好Docker,如何使业务平滑过度到Docker,如何管理、运维大量的Docker实例,这是摆在各家云计算厂商面前的一个现实的问题。
美团云从2013年起,就承载了美团网所有的业务和交易,在VM主机、网络、运维等方面积累了相当多的技术经验。面对Docker这种新技术,我们不能简单地抛开已有的架构另起炉灶,还需要考虑现有业务如何从VM平滑迁移到Docker上的问题。这里还要注意时效性,因为互联网技术、业务更新太快,迭代基本都以月为单位,所以还要考虑如何低开发成本、快速迭代的方式达到我们的目标。
0. 怎么用好Docker:
在如何用好Docker技术这个问题上,我们有一些基于美团现有情况的考虑。美团云一开始以私有云起家,架构上并没有完全使用当时还不成熟的openstack。除了Swift,Glance,keystone之外,美团云所有的组件都是自主研发。例如,我们开发的宿主机这块的host_server,负责管理VM的qemu实例,storage,network,API等。VM主机的功能和数据结构已经相当完善,举几个例子,我们VM的网络是通过控制节点管理IP,在宿主机上通过OVS接入每个VM,并通过OVS流表对多tenant进行隔离,通过TC对VM进行限速,通过Cgroup实现IO隔离。这些功能的需求也是来自于公司的日常业务。直接拿来Docker的方案,需要从头搭建,另建运维团队管理不说,我们在美团云平台上开发的很多feature也都无法应用在Docker之上。这里我们将美团云主机和Docker容器做一个对照,如表1所示:
表1:美团云和Docker主要组件比较
从表1可以看出,Docker和美团云已有组件有较高的重合度。有人说为什么不用Swarm,Kubernetes?首先,利用这些项目搭建Docker云,与我们既有的云平台不能统一管理,无论是镜像仓库,宿主机,网络还是调度,都需要另建团队搭环境,运维,开发定制,业务和VM迁移也不容易协调管理。其次,直接使用开源社区会不得不跟着开源社区走,很难保持独立地去做功能开发,也难以做出有竞争力的feature,我们对开源的理解更多的是借鉴思想,形成自己的特色和优势。最后,对这些开源项目,我们策略是小团队、小范围内测试和摸底,待踩了一些坑,比较了解了之后才敢应用于生产环境。
综上,在如何使用Docker技术上,我们的想法是为现有业务提供Docker服务的同时,尽量复用美团云已有的架构和组件,通过扩展,定制的方式使美团云支持Docker容器,对外保持美团云API的兼容性,从技术上保障美团云客户业务的平滑迁移。因此对于公司业务和其他外部用户,几乎不用修改他们的美团云接口代码,就可以像使用VM一样使用Docker承载他们的业务。
在实施层面将这个问题打开来看,主要有几点:(1)存储:如何管理Docker本地存储和镜像?(2)如何构建Docker网络,并且同现有云平台网络统一管理?(3)如何发挥Docker轻量、敏捷、高效的特色,实现业务的快速部署和弹性伸缩?
1.改造我们的镜像仓库
我们知道,镜像仓库是云计算平台不可缺少的关键组件。提供Docker服务,云平台必须提供Docker Image的仓库功能。美团云的镜像仓库是基于Openstack的Glance开发的,我们使用、改造、运维Glance三年多,对其相当熟悉。而对于Docker,它有官方提供的镜像仓库Docker Registry,如果采用Docker registry,我们将考虑云平台镜像API的问题,而且Docker registry缺少鉴权功能,无法复用云平台的keystone鉴权框架。在做Docker的调研时,我们就提出个问题,能否使用同一个镜像仓库,同时管理VM镜像和Docker镜像呢?这样我们就可以用一个仓库管理Docker镜像和VM镜像,同时可以为Docker镜像提供多租户和鉴权功能,大大降低运维成本。为了实现这个目标,我们首先要分析清楚Docker Image的本质是什么?
Docker独树一帜的技术是它的镜像构成和FS。Docker FS基于Overlay FS,每一层都是一个FS。在运行时,镜像所包含的FS都是Read Only的,容器在最上面增加一层可读写FS。将Docker镜像的内部加以分析,它其实可以看做一个由多个镜像合并在一起的tar包。我们通过docker save命令就可以将Docker 镜像保存为一个tar文件。而这个tar文件里面包含的是多个目录,每一个目录对应一个layer,也是一个镜像。总之,Docker 镜像的形式如图1所示:
图1:Docker镜像结构
Docker Registry是Docker的官方提供的镜像仓库,它维护一个Docker 镜像layer数据库,记录每一个layer的父节点ID(parent-id),镜像保存在存储后端(storage driver)中,支持多种Object存储后端,如Swift,AWS S3。
Docker push/pull实质上是将镜像内的每一个layer,也就是子镜像单独上传下载,每一个子镜像都有一个ID,通过ID保证镜像的唯一性,避免重复上传或下载。图2所示为Docker镜像和Glance镜像的layer对应。
图2:Glance镜像与Docker镜像对照
理解了Docker 镜像结构和Docker Registry原理之后,我们就知道如何扩展Glance支持Docker 镜像了。Glance镜像的数据结构里缺少Parent字段,而且Glance的ID是UUID格式,和Docker ID格式也不一样,我们希望每一个Glance Image能够对应一个Docker Layer,所以经过修改,Glance Image数
据结构变成图3所示:
图3:扩展后的Glance Image表字段
我们为每一个Glance镜像增加了一个parent_id字段,指向其父镜像的UUID。将Glance 镜像对应的Docker ID和Docker Parent ID放入了Glance镜像仓库的Property表中,通过查询Images表和Property表,就可以查询一个Docker镜像是否保存在Glance中,查询其和父镜像对应的Glance ID和Docker ID。
这样我们的Glance就具备了Docker 镜像存储功能,经过如此扩展,带来的好处是:
1)我们不必另外搭建Docker Registry了;
2)运维同学可以统一管理Docker 镜像和VM 镜像,大大减少运维工作量
3)Docker Registry本身不具备账号和鉴权功能,而Glance结合Keystone自然具备了账号和鉴权功能,我们不需要为此付出额外工作;
4)云平台Glance的后端存储目前是swift,以后会改成美团云自研分布式存储系统,Docker 镜像可以保存在高性能、高可靠的分布式存储系统中,如果使用Docker Registry,我们还需要考虑其后端存储的接入问题。
综上,通过扩展Glance实现Docker 镜像仓库功能,我们付出很小的代价,换来的是对Docker 镜像低成本的运维和灵活的控制能力。
2. 自定义Docker网络,并同VM统一管理
Docker是基于容器、Namespace的虚拟化技术,经过Docker社区的不断努力,为业务的运行环境提供了许多灵活的功能支持。自定义网络便是其中之一。
Docker容器支持4中网络模式:
1)container:-net = container: | ,网络NS与指定container共享
2)host:-net = host,网络NS与Host共享
3)bridge:-net = bridge, Docker创建一个Docker0的bridge,容器通过这个bridge走NAT,分配IP一般是172.17.0.0/16网段,这是默认网络模式
4)none:无网络配置
在考虑用何种网络模式之前,先看一下美团云的网络设置。
美团云目前是所有VM共享一个大二层网络,内网的网段和网关是在机房交换机和路由器上先分配好的,IP是由美团云控制节点管理和分配。因此VM都会分配我们指定的内网IP,如果要访问外网,还需要分配一个外网IP。
在宿主机上,由一个OVS实例管理所有本地的网络,VM的虚拟网卡配置上指定的内网IP后,接入OVS,再更新流表,即可连接外部网络。
我们希望Docker 容器也能像VM一样配置网络,这样云平台的网络代码不需要修改,相应的网络功能,例如限流,网络隔离,也都可以照常使用。按照Docker提供的网络模式,只有None这种模式满足我们的需求。
图4. Docker容器和VM网络配置
在实现上,我们复用了宿主机的OVS组件。如图4所示,VM的虚拟网卡桥接到OVS bridge上,Docker容器也是一样。Docker的容器本质上是Linux Namespace(以下简称NS),因此在容器启动后,由云平台Host-srv开始配置容器网络。先在宿主机上创建一对eth-pair,这其实是两个背靠背的netdevice设备,就像管道一样从一端发出的包会从另一段接收到。我们利用了这个机制,将eth-pair的一端放入启动后的容器NS中,然后按照云平台分配的IP、路由和网关进行配置;另一端桥接到宿主机OVS上,这样容器便有了自己的eth0网卡连接到了外部网络。
OVS的流表也是我们来管理的,我们利用它实现网络隔离,这样可以控制不同租户之间的VM是不可达的。目前网络隔离做得还比较简单,在2016年我们将开发VPC,基于VxLAN实现更好的隔离性,这一块我们在此不赘述。
配置完网络的Docker容器和VM拥有一样的、平等的网络能力,从外部看,容器和VM没什么不同了,如果容器开启了sshd,一样可以ssh登陆控制。
我们相信在管理层面将容器和VM统一起来,可以显著简化云平台管理和运维工作。预计未来相当长的一段时间,容器和VM都会共存下去,如何简化云平台的管理和运维,发挥VM和容器各自的优势,是一件值得探索的工作。
总之,我们使用Docker容器网络的none模式,自定义了容器内部的网络配置,复用了云平台现有的网络架构和基础设施,运维工程师、网络工程师都可以像管理VM一样管理Docker容器,而原有网络的隔离、负载均衡、限速甚至整形,都可以不加修改地应用到容器之上。
3. set 多容器管理单元,弹性伸缩的基本单位
如果说Image仓库和网络是为了和现有的云平台适配,从工程方法论上讲复用已有的轮子,那么set的设计我们在PaaS层面有一定创新探索的成分的。在怎么用好Docker这个问题上,我们做了一些调研工作。业内有一种趋势,不仅将Docker当作IaaS,而且当作PaaS,以至有了合并IaaS和PaaS,称之为CaaS(Container as a Service)的概念。近两年火爆的Google Kubernetes (k8s), Docker Swarm等项目应运而生,这些项目在容器的编排,调度,部署等方面应用了许多创新的理念,例如K8s的Pod。
Docker的哲学是实例简单化,一个容器内运行一个进程,复杂业务需要多个容器。如果一个业务有多个相互依赖的进程怎么办?办法一:都放到一个容器里,这样是把容器当作VM使,这样不是使用容器的好方式;办法二:每一个进程单做建一个容器,那样很可能使容器都调度到不同的宿主机上,同一个业务的两个进程通信还要跨宿主机,甚至跨交换机、跨机房?这样显然有弊端。
K8s建议将几个容器捆绑在一起,形成一个Pod,pod是K8s调度和运行基本单位,里面的容器都是共享网络、共享Volume的。这样既保持一个容器一个进程,简化容器,又能实现同一个业务的进程高效通信。
图5. set示意图
我们借鉴了Pod的理念,根据自己的理解实现了类似的模块,即将同一业务的多个容器组成一个set,如图5所示。每个set代表一个业务实例,是云平台调度的基本单位。set内的容器共享网络、volume、ipc等设置,因此容器共用ip,域名和本地volume。这样大大提高了业务内部的通信效率,降低云平台网络负载。
在实现上,每个set和VM对应,所以VM的资源例如8C8G(8核8G)都可以直接复用在set上。VM的数据盘对应set的volume大小。
对于set内部的资源分配,我们定义了set-conf,如图6所示:
图6. set-conf结构
每个容器主要有以下几个字段:
index - 容器index,也是容器启动顺序的标识
options - 容器run参数,大部分的参数在此设置
cpu、mem:表示所占set资源的百分比
volumes:volume设置
command:启动的cmd参数
美团的业务的标准set模型包含3个容器:
1) infra-container:index为0,是首先启动的容器,也是一个非常轻量的容器,只有几M大小,cpu、mem占用几乎可以忽略。主要用以设置网络、volume、IPC。我们将infra-container赋予privileged权限,并禁止ssh访问登陆,这样可以在运行时重载内核参数,例如kernel.msgmax参数,这样业务容器的ipc指向infra container,共享msgmax设置。
2) agent container:业务日志容器
3) applicatoin container:业务容器
不仅如此,我们按照业务的需求做了一些定制和改进工作。
其一,我们支持set运行时的灰度更新,如图7所示。所谓灰度更新是指在不中断set服务的情况下,更新其中容器的image版本。这是基于有些业务容器的image更新相对较为频繁,为了使已上线的set不至于跟着频繁更新,我们开发了灰度更新功能。即容器image有新版本要上线时,先停止并删除对应容器,然后按照新的image创建新容器。这个过程很快,所以对set的业务影响
很小。
图7. set灰度更新示意图
其二,我们开发了动态scaleup功能,即在线运行的set当发现mem资源比较紧张时,可以不中断set服务,动态提高mem配额,从而实现scaleup
最后,我们还为set提供ssh访问能力,这是配置在Docker基础镜像里面的,所以业务RD可以选择是否使用ssh,可以认为这是容器的debug版本,待正式上线时可以选择没有sshd的基础镜像。
对业务的发布和弹性伸缩通常需要在IaaS和PaaS两个层面去做。公司有一个团队专门做Docker容器的弹性伸缩,批量创建和删除,为此我们在云平台主机接口上做了改进,可以保证数百台Dockers容器的批量部署。对于Docker容器的创建、调度、删除等流程,我们也在不断的改进,最终打到端到端性能的优化。目前,在私有云上我们已经开始接入公司业务,以后将有越来越多的VM业务转移到Docker上来。2016年将是美团业务Dockrize的关键一年,我们也对此做了充足的准备。
未来已来
Docker未来在美团云的应用场景非常清晰。由于Docker技术本身非常适合私有云,2016年,我们将大规模推广Docker解决方案,来服务美团自身业务。同时,在公有云方面,由于Docker存在隔离性、安全性不足的问题,导致Docker上公有云十分具有挑战性。目前业界的Docker的公有云服务也有诸多形态,美团云在对客户的需求进行深刻地调研之后,也将推出有差异化的解决方案,终极目标是为用户提供更便捷、稳定、可靠、安全和高性能的Docker云计算服务,帮助用户大幅降低运维成本,实现更高的业务效率。
第四十一届CIO班招生
国际CIO认证培训
首席数据官(CDO)认证培训
责编:chenjian
免责声明:本网站(http://www.ciotimes.com/)内容主要来自原创、合作媒体供稿和第三方投稿,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证有关资料的准确性及可靠性,读者在使用前请进一步核实,并对任何自主决定的行为负责。本网站对有关资料所引致的错误、不确或遗漏,概不负任何法律责任。
本网站刊载的所有内容(包括但不仅限文字、图片、LOGO、音频、视频、软件、程序等)版权归原作者所有。任何单位或个人认为本网站中的内容可能涉嫌侵犯其知识产权或存在不实内容时,请及时通知本站,予以删除。