时隔半年,Docker 再发重大版本 1.13!

刀客info阅读(147)评论(0)

作者王涛,就职于悉尼一家数据分析公司。喜欢开源,对 Docker 有较深入的研究和实践。2017 年 1 月 18 日 Docker 1.13 新版本发布,他于第一时间发布了新版本的功能解读。道客船长授权转载,本文列出 1.13 版本的 top 10 新增功能,详情请点击 https://github.com/docker/docker/releases/tag/v1.13.0http://blog.lab99.org/post/docker-2016-11-14-what-is-new-in-docker-1-13.html#top-10-xin-zeng-gong-neng 了解 Docker 1.13 新增功能。

Docker 1.13 在 2017 年 1 月 18 日发布了。从 2016 年 7 月 29 日发布 1.12 以来,已经过去 5 个多月了,对于活跃的 Docker 社区来说,已经很久了,让我们看看都 1.13 都新增了什么内容吧。

1.13 有一千四百多个 issue/pull request,五千多个 commits,是 Docker 历史上最高的发布版本。这并不是一个简单的小版本变化,里面有大量的更新。

Top 10 新增功能 | New Features

  1. 正式支持服务栈: docker stack
  2. 正式支持插件:docker plugin
  3. 添加在 Swarm 集群环境下对密码、密钥管理的 secret 管理服务:docker secret
  4. 增加 docker system 命令
  5. 可以直接使用 docker-compose.yml 进行服务部署
  6. 添加 docker service 滚动升级出故障后回滚的功能
  7. 增加强制再发布选项 docker service update –force
  8. 允许 docker service create 映射宿主端口,而不是边界负载均衡网络端口
  9. 允许 docker run 连入指定的 swarm mode 的 overlay 网络
  10. 解决中国 GFW 墙掉 docker-engine apt/yum源的问题

新增功能解读

Docker 镜像构建

  • 从已有镜像取得缓存
  • 压扁 (squash) 镜像(实验阶段)
  • 构建镜像时支持用 –network 指定网络
  • 开始允许 docker build 中定义 Dockerfile 未使用的参数(ARG)

安装

  • 解决 GFW 影响 Docker 安装问题
  • 增加更多的系统支持

网络

  • 允许 docker run 连入指定的 swarm mode 的网络
  • 允许 docker service create 映射宿主端口,而不是边界负载均衡网络端口
  • iptables 的转发规则将默认拒绝
  • 在 docker network inspect 里显示连入的节点
  • 允许 service VIP 可以被 ping

插件

  • 插件功能正式启用

命令行

  • checkpoint 功能(试验功能)
    – 准备工作
    – 创建 Checkpoint 及恢复
  • docker stats 终于可以显示容器名了
  • 给 docker ps 增加 is-task 过滤器
  • docker inspect 将可以查看任何 docker 对象

运行时

  • 不在分别构建试验可执行文件,直接使用 –experimental 参数
  • 在 overlay2 存储驱动使用于 xfs 时可以添加磁盘配额
  • 增加 docker system 命令
  • 提升 overlay2 的优先级
  • docker exec -t 自动添加 TERM 环境变量
  • Windows 内置的运行 Windows 程序的 Docker on Windows 的改进

Swarm Mode

  • 正式支持 docker stack
  • 添加 secret 管理
  • 添加负载均衡和DNS记录对新增的健康检查的支持
  • 添加滚动升级回滚的功能
  • 补充了一些 docker service create 所缺失的参数
  • 添加命令 docker service logs 以查看服务日志(试验功能)
  • 增加强制再发布选项 docker service update –force

➤ 欢迎关注王涛的个人博客:http://blog.lab99.org/,阅读更多 Docker 干货及最新动态。

Docker迈入稳定成长期,大型云端企业比新创更爱用

刀客info阅读(167)评论(0)

Container战场已从厂商技术拉锯战,走入企业,大型云端企业采用率更破2成,若加上小规模试用者更是过半数,大型云端企业比新创小公司更爱用Docker

 

20170111143704

根据基础架构监控服务业者Datadog的Docker导入率普查结果显示,在2015年5月到2016年5月这一年间,使用私有云或公有云技术的企业,Docker导入率成长幅度超过30%。

 

容器风潮火热,大型公有云厂商Google、AWS及Azure都纷纷推出容器服务,在私有环境中,VMware也得支持Docker满足企业需求。不过令人好奇的是,容器究竟有多热?提供基础架构监控服务的Datadog,以1万家导入公有云、私有云技术的企业用户为母体,根据其搜集在线运行的一手资料,展开一场全球最大规模的Docker导入率普查。

 

20170111143726

 

在2015年5月时,研究显示仅有8.2%的云端企业开始导入Docker,仅经过1年,2016年同期,Docker使用率已经突破一成,上升至10.7%。

针对这一成使用Docker的企业,Datadog也更深入地进行分析,发现Docker采用率与基础架构规模大小,两者呈现正相关。基础架构规模超过500台服务器的公司,Docker的导入率则超过20%,加上正尝试使用的企业,其比例就超过一半,剩下只有不到4成的大型云端企业从未使用过Docker。

反之,基础架构规模小于100台服务器的中小企业,Docker导入率则低于20%,超过80%从未使用过Docker。

Datadog所进行的研究显示,容器技术虽不如Docker宣称的火爆,但的确能看见企业导入率逐渐上升的趋势。同时,Docker的使用率,随着基础架构规模成长,也能瞥见企业对于这门技术抱持一定信心。不过,如此状况,也可能出于大型企业拥有更多研发资源,因此较敢放手尝试新技术。

掀起这波狂潮的Docker技术长Solomon Hykes,在去年度DockerCon中也大喊:「现在没人关心Container了,因为应用程序才要紧」,更点出Container的重点战场,已经从各容器厂商间的技术拉锯战,开始走入各家企业的数据中心,在正式环境中,扮演运行应用程序的角色,而Docker化应用程序也已经超过了46万个。

因此,容器调度工具也是今年度的重要战场。除了KubernetesDocker Swarm以及Mesos外,去年底连AWS也推出了自家的调度工具Blox。而Google看上有8成企业在Linux环境中运行Java应用程序,或是Windows环境执行.NET应用程序,更在Kubernetes 1.5版大举支持Windows Server Container以及Hyper-V Container,使它成为目前唯一通吃Linux、Windows容器调度的利器。挟如此优势,Kubernetes应会稳坐2017年容器调度工具的龙头。

20170111143745 20170111143754 20170111143803

容器就像监狱,让我们来构造一个监狱吧!

刀客info阅读(133)评论(1)

前言

容器,近年来最火的话题,在后端的开发中,容器的运用已经是主流技术了。今天,我们就来说说容器技术。首先,虽然目前Docker技术如此火爆,但其实容器技术本质上并不是什么高大上的东西,总的来讲,就是对目前的Linux底层的几个API的封装,然后围绕着这几个API开发出了一套周边的环境。

目前来说,普遍讨论关于容器的文章,一开始都会讲到UTC隔离、PID隔离、IPC隔离、文件系统隔离、CGroups系统,今天这一篇,我们换一个视角,从以下几个方面来聊一下容器技术。

  • 第一部分,从容器和虚拟机说起,都说容器是非常轻量级的,那么和虚拟机比起来,到底轻在哪里?
  • 第二部分,通过构造一个监狱,来说明如何建立一个简单的容器,会涉及到容器的各种技术,当然还有一些没有涉及到的,我认为不影响理解。
  • 第三部分,通过代码实战一把,看看如何一步一步按照第二部分的说明启动一个容器并运行自己的代码,这一部分的全部代码都在github上。
  • 最后,我会再说一下Docker技术,因为Docker从代码来看,容器技术只是他的一小部分,完整的Docker远比单纯的容器要复杂,我会简单的说一下我对Docker的理解,包括Docker使用的其他技术点。

容器和虚拟机

要说容器,跑不了和虚拟机进行比较,虚拟机是比较古老的技术了,虚拟机的架构图如下所示。

虚拟机核心是什么?是模拟硬件,让虚拟机的操作系统以为自己跑在一个真实的物理机器上,用软件模拟出来CPU、内存、硬盘、网卡,让虚拟机里面的操作系统觉得自己是在操作真实的硬件,所以虚拟机里面的CPU啊,内存啊都是假的,都是软件模拟出来的(现在有硬件虚拟化技术了,比纯软件模拟要高级一些,但操作系统不管这些),既然操作系统都骗过去了,当然跑在操作系统上的进程同样也骗过去了呗,所以这些进程都完全感知不到底层硬件的区别,还以为自己很欢乐的跑在一台真实的物理机上了。

那么容器又是什么鬼?容器的架构图如下(图片来源于网络):

和虚拟机一个很明显的区别就是容器其实并没有模拟硬件,还是那个硬件,还是那个操作系统,只不过是在操作系统上做了一点文章【这张图中就是Docker Engine了】,让进程以为自己运行在了一个全新的操作系统上,有一个很形象的词来描述他就是软禁!就是把进程软禁在一个环境中,让进程觉得自己很happy,其实一切尽在操作系统的掌控之中,其实虚拟机也是,虚拟机是把操作系统软禁起来了,让操作系统觉得很happy,容器是把进程软禁起来,你看,一个是软禁操作系统,一个是软禁进程,这两个明显不是一个级别的东西,谁轻谁重不用说了吧。

既然容器和虚拟机的区别在于一个是通过模拟硬件来软禁操作系统,一个是通过做做操作系统的手脚来软禁进程,那么他们能达到的效果也是不一样的。

  • 对于虚拟机来说,既然是模拟的硬件,那么就可以在windows上装linux虚拟机了,因为反正是模拟硬件嘛,虚拟机内部的操作系统也不知道外面的宿主机是什么系统。
  • 容器就不一样了,因为是在操作系统上做文章,所以不可能在linux上装windows了,并且还有一点就是,容器内的操作系统其实就是外面宿主机的操作系统,两者其实是一个,你在容器内用uname -a看到的内核版本和外面看到的是一样的。本质上容器就是一个进程,他和宿主机上任何其他进程没什么本质的区别。

建造容器监狱

如何来做一个容器呢?或者说容器是怎么实现的呢?我们从几个方面来说一下容器的实现,一是最小系统,二是网络系统,三是进程隔离技术,四是资源分配。最小系统告诉你软禁进程所需要的那个舒适的监狱环境,网络系统告诉你软禁的进程如何和外界交互,进程隔离技术告诉你如果把进程关到这个舒适的监狱中去,资源分配告诉你监狱里的进程如何给他分配资源让他不能胡来。

建设基本监狱【最小系统打造】

要软禁一个进程,当然需要有个监狱了,在说监狱之前,我们先看看操作系统的结构,一个完整的操作系统【Linux/Unix操作系统】分成三部分,如下图所示【本图也是网上找的,侵权马上删,这个图是四个部分,包括一个boot参数部分,这不是重点】。

 

20170106102720

 

首先是bootloader,这部分启动部分是汇编代码,CPU从一个固定位置读取第一行汇编代码开始运行,bootloader先会初始化CPU,内存,网卡(如果需要),然后这部分的主要作用是把操作系统的kernel代码从硬盘加载到内存中,然后bootloader使命完成了,跳转到kernel的main函数入口开始执行kernel代码,kernel就是我们熟悉的Linux的内核代码了,大家说的看内核代码就是看的这个部分了,kernel代码启动以后,会重新初始化CPU,内存,网卡等设备,然后开始运行内核代码,最后,启动上帝进程(init),开始正常运行kernel,然后kernel会挂载文件系统。

好了,到这里,对进程来说都是无意义的,因为进程不关心这些,进程产生的时候这些工作已经做完了,进程能看到的就是这个文件系统了,对进程来说,内存空间,CPU核心数,网络资源,文件系统是他唯一能看得见使用得到的东西,所以我们的监狱环境就是这么几项核心的东西了。

kernel和文件系统是可以分离的,比如我们熟悉的ubuntu操作系统,可能用的是3.18的Linux Kernel,再加上一个自己的文件系统,也可以用2.6的Kernel加上同样的操作系统。每个Linux的发行版都是这样的,底层的Kernel可能都是同一个,不同的只是文件系统不同,所以,可以简单的认为,Linux的各种发行版就是kernel内核加上一个独特的文件系统,这个文件系统上有各种各样的工具软件。

既然是这样,那么我们要软禁一个进程,最基础的当然要给他一个文件系统啦,文件系统简单的说就是一堆文件夹加上一堆文件组成的,我们先来生成一个文件系统,我之前是做嵌入式的,嵌入式的Linux系统生成文件系统一般用busybox,只需要在在ubuntu上执行下面的命令,就能生成一个文件系统:

apt-get install busybox-static
mkdir rootfs;cd rootfs
mkdir dev etc lib usr var proc tmp home root mnt sys
/bin/busybox –install -s bin

大概这么几步就制作完成了一个文件系统,也就是监狱的基本环境已经有了,记得把lib文件夹的内容拷过去。制作完了以后,文件系统就这样了。

 

20170106102737

 

还有一种方式,就是使用debootstap这个工具来做,也是几行命令就做完了一个debian的文件系统了,里面连apt-get都有,Docker的基础文件系统也是这个。

apt-get install qemu-user-static debootstrap binfmt-support
mkdir rootfs
debootstrap –foreign wheezy rootfs //wheezy是debian的版本
cp /usr/bin/qemu-arm-static rootfs/usr/bin/

完成以后,这个wheezy的文件系统就是一个标准的debian的文件系统了,里面的基本工具一应俱全。OK,基本的监狱环境已经搭建好了,进程住进去以后就跟在外面一样,啥都能干,但就是跑不出来。

要测试这个环境,可以使用Linux的chroot命令,chroot ./rootfs就进入了这个制作好的文件系统了,你可以试试,看不到外面的东西了哦。

打造探视系统【网络系统】

刚刚只建立了一个基本的监狱环境,对于现代的监狱,只有个房子不能上网怎么行?所以对于监狱环境,还需要建立一个网络环境,好让里面的进程们可以很方便的和监狱外的亲友们联系啊,不然谁愿意一个人呆在里面啊。

如何来建立一个网络呢?对于容器而言,很多地方是可配置的,这里说可配置,其实意思就是可配置也可以不配置,对于网络就是这样,一般的容器技术,对网络的支持有以下几个方式。

  • 无网络模式,就是不配置模式了,不给他网络,只有文件系统,适合单机版的程序。
  • 直接和宿主机使用同一套网络,也是不配置模式,但是这个不配置是不进行网络隔离,直接使用宿主机的网卡、ip、协议栈,这是最奔放的模式,各个容器如果启动的是同一套程序,那么需要配置不同的端口了,比如有3个容器,都是Redis程序,那么需要启动三个各不同的端口来提供服务,这样各个容器没有做到完全的隔离,但是这也有个好处,就是网络的吞吐量比较高,不用进行转发之类的操作。
  • 网桥模式,也是Docker默认使用的模式,我们安装完Docker以后会多一个Docker0的网卡,其实这是一个网桥,一个网桥有两个端口,两个端口是两个不同的网络,可以对接两块网卡,从A网卡进去的数据会从B网卡出来,就像黑洞和白洞一样,我们建立好网桥以后,在容器内建一块虚拟网卡,把他和网桥对接,在容器外的宿主机上也建立一块虚拟网卡,和网桥对接,这样容器里面的进程就可以通过网桥这个探视系统和监狱外联系了。

我们可以直接使用第二种不配置模式,直接使用宿主机的网络,这也是最容易最方便的,但是我们在这里说的时候稍微说一下第三种的网桥模式吧。

网桥最开始的作用主要是用来连接两个不同的局域网的,更具体的应用,一般是用来连接两个不同的mac层的局域网的,比如有线电视网和以太网,一般网桥只做数据的过滤和转发,也可以适当的做一些限流的工作,没有路由器那么复杂,实现起来也比较简单,对高层协议透明,他能操作的都是mac报文,也就是在ip层以下的报文。

对于容器而言,使用网桥的方式是在宿主机上使用brctl命令建立一个网桥,作为容器和外界交互的渠道,也就是大家使用Docker的时候,用ifconfig命令看到的Docker0网卡,这实际上就是一个网桥,然后每启动一个容器,就用brctl命令建立一对虚拟网卡,一块给容器,一块连到网桥上。这样操作下来,容器中发给虚拟网卡的数据都会发给网桥,而网桥是宿主机上的,是能连接外网的,所以这样来做到了容器内的进程能访问外网。

容器的网络我没有深入研究,感觉不是特别复杂,最复杂的方式就是网桥的方式了,这些网络配置都可以通过命令行来进行,但是Docker的源码中是自己通过系统调用实现的,说实话我没怎么看明白,功力还是不够啊。我使用的就是最最简单的不隔离,和宿主机共用网卡,只能通过端口来区分不同容器中的服务。

监禁皮卡丘【隔离进程】

好了,监狱已经建好了,探视系统也有了,得抓人了来软禁了,把进程抓进来吧。我们以一个最最基本的进程/bin/bash为例,把这个进程抓进监狱吧。

说到抓进程,这时候就需要来聊聊容器的底层技术了,Linux提供几项基础技术来进行轻量级的系统隔离,这些个隔离技术组成了我们熟悉的Docker的基础。本篇不会大段的描述这些技术,文章后面我会给出一些参考链接,因为这类文章到处都可以找到,本篇只是让大家对容器本身有个了解。

下面所说的所有基础技术,其实就是一条系统调用,包括Docker的基础技术,也是这么一条系统调用(当然,Docker还有很多其他的,但是就容器来说,这条是核心的了)

clone(进程函数, 进程栈空间, CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET |CLONE_NEWUSER | CLONE_NEWIPC , NULL

这是一条C语言的clone系统调用,实际上就是启动一个新的进程,后面的参数就是各种隔离了,包括UTS隔离、PID隔离、文件系统隔离、网络隔离、用户隔离、IPC通讯隔离。

在go语言中,没有clone这个系统调用(不知道为什么不做这个系统调用,可能是为了多平台的兼容吧),必须使用exec.Cmd这个对象来启动进程,在linux环境下,可以设置Cmd的attr属性,其中有个属性叫CloneFlags,可以把上面那些个隔离信息设置进去,这样,启动的进程就是我们需要的了,我们可以这么来启动这个进程。

cmd := exec.Command(“./container”, args…)
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS | syscall.CLONE_NEWNET,
}
cmd.Run()

这样,通过这个cmd命令启动的./container进程就是一个隔离进程了,也就是我们把这个进程给关起来了,他已经看不到其他东西了,是不是很简单?但是你要是就直接这么运行,还是看不到什么特别的地方。

在这个之后,我们需要按照上面所说的,把监狱先建立好,监狱的建立在./container中进行,建立监狱也比较简单,基本上也是一堆系统调用,比如文件系统的软禁,就像下面的一样。

syscall.Mount(rootfs, tmpMountPoint, “”, syscall.MS_BIND, “”) //挂载根文件系统
syscall.Mount(rootfs+”/proc”, tmpMountPoint+”/proc”, “proc”, 0, “”); //挂载proc文件夹
syscall.PivotRoot(tmpMountPoint, pivotDir) //把进程软禁到根文件系统中

关于上面proc文件夹,做了特殊处理,在Linux中,proc文件夹的地位比较特殊,具体作用可以自行查文档,简单的说就是保存系统信息的文件夹。在这里,dev和sys这两个特殊文件夹也需要做特殊处理的,这里没有写出来而已。

这些都做完了以后,就可以启动真正需要执行的进程了,比如/bin/bash,或者你自己的程序,这样启动的/bin/bash或者你自己的程序就是在监狱中启动的了,那么他看到的所有东西都是监狱中的了,外面宿主机的一切对他来说都是屏蔽的了,这样,一个Docker的雏形就产生了。

这里多说一下,通过clone系统调用启动的进程,它自己看到自己的PID是1,也就是上帝进程了,这个上帝进程可以来造基础监狱【文件系统】,打造放风系统【网络系统】,然后再通过它来生成新的进程,这些进程出来就在监狱中了,我们使用Docker的时候,自己的服务实际上就是这些个在监狱中出生的进程【可能我的描述不太正确啊,我没有仔细看Docker的源码,我自己感觉是这样的】。

至此,我们来总结一下,启动一个最简单的容器并运行你自己的进程,需要几步。

  • 建立一个监狱【文件系统】,使用busybox或者debootstrap建立。
  • 建立一个放风系统【网络系统】,使用网桥或者不隔离网络,直接使用宿主机的网卡。
  • 抓一个皮卡丘【启动上帝进程】并放到监狱中【挂载文件系统,初始化网络】,配置Cloneflags的值,并通过exec.Cmd来进行上帝进程的启动。
  • 让皮卡丘生个孩子【启动你自己的程序】,直接调用exec.Cmd的run方法启动你自己的进程。
  • 完成。

通过上面几步,最简容器就完成了,是不是很简单?但是容器仅仅有这些是不够的,我们还有三个隔离没有讲,这里稍微提一下吧。

  • 一个是UTS隔离,主要是用来隔离hostname和域名的。
  • 一个是User隔离,这样容器里面的用户和宿主机用户可以做映射,意思就是里面虽然看到的是root用户,但是实际上并不是root,不能够瞎搞系统,这样容器的安全性会有保障。
  • 一个是IPC隔离,这个是进程通讯的隔离,这样容器里面的进程和容器外面的进程就不能进行进程间通讯了,保证了比较强的隔离性。

给犯人分配食物【资源配置】

我们知道,一般的监狱中的食物是定量的,毕竟不是每个监狱都可以吃自助餐的,容器也一样,要是我们就启个容器啥都不限制,里面要是有个牛逼的程序员写的牛逼程序,瞬间就把你的内存和CPU给干没了。比如像下面这个fork炸弹。【下面程序请不要尝试!!】

int main(){
while(fork());
}

在容器技术中,Cgroups【control groups】就是干这个事情的,cgroups负责给监狱设定资源,比如能用几个cpu啊,cpu能给你多少百分比的使用量啊,内存能用多少啊,磁盘能用多少啊,磁盘的速度能给你多少啊,各种资源都可以从cgroups来进行配置,把这些东西配置给容器以后,就算容器里面运行一个fork炸弹也不怕了,反正影响不到外面的宿主机,到这里,容器已经越来越像虚拟机了。

cgroups是linux内核提供的API,虽然是API,但它的整个实现完美满足了Linux两大设计哲学之一:一切皆文件(还有一个哲学是通讯全管道),对API的调用实际上是操作文件。

我们以cpu的核心数看看如何来做一个cgroups的资源管理。假设我们的物理机是个8核的cpu,而我们刚刚启动的容器我只想让他使用其中的两个核,很简单,我们用命令行直接操作sys/fs/cgroups文件夹下的文件来进行。这个配置我们可以在启动的上帝进程中进行,也可以在容器外部进行,都是直接操作文件。

关于cgroups这个东西很复杂也很强大,其实在容器出来之前,好的运维工程师就已经把这个玩得很溜了。Docker也只是把这些个文件操作封装了一下,变成了docker的启动和配置参数而已。

亲自抓一次进程吧

好了,该说的都说了,我们来实战一把,自己启一个容器吧,并且启动以后为了更直观的看到效果,我们启动一个ssh服务,打开22332端口,然后外面就可以通过ssh连到容器内部了,这时候你爱干什么干什么了。

制作文件系统

文件系统制作我们直接使用debootstrap进行制作,在/root/目录下建立一个rootfs的文件夹,然后使用debootstrap –foreign wheezy rootfs制作文件系统,制作完了以后,文件系统就是下面这个样子

 

20170106102749

 

制作初始化脚本

初始化脚本就做两件事情,一是启动ssh服务,一是启动一个shell,提前先把/etc/ssh/sshd_config中的端口改成23322。

#!/bin/bash
service ssh start
/bin/bash

然后把这个脚本放到制作的文件系统的root目录下,加上执行权限。

启动上帝进程

文件系统制作完成了,启动脚本也做完了,我们看看我们这个容器的架构,架构很简单,整个容器分为两个独立的进程,两份独立的代码。

  • 一个是主进程【wocker.go】,这个进程本身就是一个http的服务,通过get方法接收参数,参数有rootfs的地址,容器的hostname,需要监禁的进程名称(这里就是我们的第二个进程【startContainer.go】),然后通过exec.Cmd这个包启动这个进程。
  • 第二个进程启动就是以隔离方式启动的了,就是容器的上帝进程了,这个进程中进行文件系统挂载,hostname设置,权限系统的设定,然后启动正式的服务进程(也就是我们的启动脚本/root/start_container.sh)

挂载文件系统

第二个进程是容器的上帝进程,在这里进行文件系统的挂载,最重要的代码如下

syscall.Mount(rootfs, tmpMountPoint, “”, syscall.MS_BIND, “”) //挂载根文件系统
syscall.Mount(procpath, tmpMountPointProc, “proc”, 0, “”) //挂载proc文件夹,用来看系统信息的
syscall.Mount(syspath, tmpMountPointSys, “sysfs”, 0, “”) //挂载sys文件夹,用来做权限控制的
syscall.Mount(“udev”, tmpMountPointDev, “devtmpfs”, 0, “”) //挂载dev,用来使用设备的
syscall.PivotRoot(tmpMountPoint, pivotDir)//进入到文件系统中

具体代码可以看github上的文件,这样,根文件系统就挂载完了,已经进入了基本监狱中了。

启动初始化脚本

文件系统挂载完了以后,然后启动初始化脚本,这个就比较简单了,一个exec.Cmd的Run方法调用就搞定了。

cmd := exec.Command(“/root/start_container.sh”)

这样,ssh服务就在容器中启动了,可以看到一行Starting OpenBSD Secure Shell server: sshd.的打印信息,容器启动完成,这时候,我们可以通过ssh root@127.0.0.1 -p 23322这个命令登录进我们的容器了,然后你就可以为所欲为了。

 

20170106102759

 

上面那个图,我们看到登录进来以后,hostname已经显示为我们设定的hello了,这时这个会话已经在容器里面了,我们ps一下看看进程们。

 

20170106102806

 

看到pid为1的进程了么,那个就是启动这个容器的上帝进程了。恩,到这里,我们已经在容器中了,这里启动的任何东西都和我们知道的Docker中的进程没什么太大区别了。但在这里,我缺失了权限的部分,大家可以自己加上去,主要是各种文件操作比较麻烦……

关于Docker的思考

Docker这门最近两年非常火的技术,光从容器的角度来看的话,也不算什么新的牛逼技术了,和虚拟机比起来还是要简单不少,当然,Docker本身可完全不止容器技术本身,还有AUFS文件分层技术,还有etcd集群技术,最关键的是Docker通过自己的整个生态把容器包裹在里面了,提供了一整套的容器管理套件,这样让容器的使用变得异常简单,所以Docker才能这么流行吧。和虚拟机比起来,Docker的优点实在是太多了。

  • 首先,从易用性的角度来说,管理一个虚拟机的集群,有一整套软件系统,比如openstack这种,光熟悉这个openstack就够喝一壶的了,而且openstack的网络管理异常复杂,哦,不对,是变态级的复杂,要把网络调通不是那么容易的事情。
  • 第二,从性能上来看看,我们刚刚说了容器的原理,所以实际上容器不管是对cpu的利用,还是内存的操作或者外部设备的操作,对一切硬件的操作实际上都是直接操作的,并没有经过一个中间层进行过度,但是虚拟机就不一样了,虚拟机是先操作假的硬件,然后假硬件再操作真硬件,利用率从理论上就会比容器的要差,虽然现在有硬件虚拟化的技术了能提升一部分性能,但从理论上来说性能还是没有容器好,这部分我没有实际测试过啊,只是从理论上这么觉得的,如果有不对的欢迎拍砖啊。
  • 第三,从部署的易用性上和启动时间上,容器就完全可以秒了虚拟机了,这个不用多说吧,一个是启动一台假电脑,一个是启动一个进程。

那么,Docker和虚拟机比起来,缺点在哪里呢?我自己想了半天,除了资源隔离性没有虚拟机好以外,我实在是想不出还有什么缺点,因为cgroups的隔离技术只能设定一个上限,比如在一台4核4G的机器上,你可能启动两个Docker,给他们的资源都是4核4G,如果有个Docker跑偏了,一个人就干掉了4G内存,那么另外一个Docker可能申请不到资源了。

而虚拟机就不存在这个问题,但是这也是个双刃剑,Docker的这种做法可以更多的榨干系统资源,而虚拟机的做法很可能在浪费系统资源。除了这个,我实在是想不出还有其他缺点。网上也有说权限管理没有虚拟机好,但我觉得权限这东西,还是得靠人,靠软件永远靠不住。

最后,代码都在github上,只有非常非常简单的三个文件【一个Container.go是容器类,一个wocker.go没内容,一个startContainer.go启动容器】,那个http服务留着没写,后面写http服务的时候在用一下。嗯,Docker确实是个好东西。

参考链接:
rootfs:https://olimex.wordpress.com/2014/07/21/how-to-create-bare-minimum-debian-wheezy-rootfs-from-scratch/
Cgroups:http://tech.meituan.com/cgroups.html
namespace:http://man7.org/linux/man-pages/man7/namespaces.7.html

作者:西加加语言 订阅号(ID:XJJ267)吴坚

2017容器发展趋势预测:更快速的采纳和创新

刀客info阅读(118)评论(0)

容器编排框架的快速采用

随着越来越多的公司开始在生产环境中使用容器,编排框架(Kubernetes、Mesoscale、Cattle和Docker Swarm)的采用量将会大大增加。这些项目在稳定性、社区和合作伙伴生态系统方面发展迅速,对于未来企业更广泛地将容器应用于生产环境,这些项目将成为必要的、有利的技术。

容器基础架构服务的更大创新

尽管目前市场上已有一套强大的容器存储和网络解决方案,但在明年将出现更多的相关产品,来支持生产环境中的容器的工作负载的增长和规模,特别是随着Kubernetes使用的CNI的规格的继续成熟。 StorageOS、Portworx和Quobyte等公司的产品将会被更多地采用。

基础架构集群将以代码形式大量涌现

为了强化“一次编写,随处运行”的能力,编排集群将越来越多地从蓝图变得模板化和实例化,就像将容器化应用程序以Docker Compose文件的形式被部署一样。用户将自行定义他们需要的Kubernetes、Swarm或Mesos部署配置,以及他们需要的任何基础架构服务,然后将其部署到任何他们选择的云或虚拟化基础架构上。用户已经要求这个功能一年多了,最新版本的Rancher采取措施实现这一愿景,使用户能够以模块化、可定制的模板的形式,搭建完整的、container-ready的环境。

Docker将加速ARM服务器的采用

我们可能离真正的“ARM Server之年”有点距离,但容器肯定会加快在数据中心采用ARM的速度。容器在ARM服务器上运行的方式与在英特尔服务器上的运行方式相同,但具有大幅降低成本的潜力。像Packet这样的托管公司现在可以按小时增量提供ARM服务器;在某些特定情况之下,容器和像RancherOS这样的轻量级Linux分发版可以利用这些托管解决方案,让ARM服务器成为工作负载的值得考虑的选项之一。

2016国外容器使用调查报告:走向生产环境,工具与系统排名谁是赢家?

刀客info阅读(699)评论(0)

眨眼2016就到了尾巴,年底是总结与展望的好时机,小数为大家带来一篇来自Anchore的国外容器技术调查报告,帮助大家全面了解这一年国外容器发展和使用情况。

本次报告数据的采集来自各个领域和方向,包括容器计划和使用、管理工具、操作系统、CI工具和安全。其中,报告重点关注容器和CI的数据。

使用者分布

我们的受调查人口中,有60%工作在100人以上的公司,并且在各个职位都有分布。

 

qq%e6%88%aa%e5%9b%be20161208100451

 

容器技术使用分类

和其他使用场景相比,大约有三分之一的用户将容器技术应用于生产环境,开发使用则更高一些。

 

qq%e6%88%aa%e5%9b%be20161208100502

 

安全成为问题

本次调查最有趣的发现之一就是大家对于安全的关注。特别是生产环境和非生产环境下企业选择安全策略的对比,差别非常显著。

 

qq%e6%88%aa%e5%9b%be20161208100629

 

有自定义适当安全策略的公司更有可能运行在生产环境。有很多潜在的方面需要深入,但是最高级别的开发者很少会将热情投入到安全方面,而且几乎从不考虑一些合规的细节,这些恰是企业必须考虑的。

安全成为了一个壁垒,延缓保守派接受新的技术。

CI/CD

CI/CD在云原生上的重要性不言而喻,Jenkins在众工具之上遥遥领先。数据上Jenkins和CloudBees(商业版Jenkins)占据了50%。

 

qq%e6%88%aa%e5%9b%be20161208100634

 

如我们预期的那样,受调查者中CI/CD的使用水平比其他领域高很多。

 

qq%e6%88%aa%e5%9b%be20161208100640

 

容器编排工具

现在说编排工具市场很火热都只是轻描淡写。出于分析的目的, Kubernetes我们选择了红帽的OpenShift和CoreOs Tectonic,Mesos则选择了Apache Mesos和Mesosphere。

 

qq%e6%88%aa%e5%9b%be20161208100646

 

我们可以看到Kubernetes和Docker Swarm在市场占有率上位居前两位,前者比后者略微领先。
重要的是Mesos在架构上依然功能强大。我们经常会看到架构师在大数据环境下选择Mesos,并且试图为他们的容器策略寻找一个通用的方法,这表明整个技术市场依然充满了变化。

 

qq%e6%88%aa%e5%9b%be20161208100651

 

容器操作系统

主机操作系统

意料之中,Ubuntu在容器主机操作系统中位居首位,但是其他两个方面的数据也值得讨论。首先,Amazon Linux的高使用率反映了ECS的增长,而Alpine Linux则反映了Docker在Mac的应用。

 

qq%e6%88%aa%e5%9b%be20161208100657

 

观察前五名的主机操作系统的用户属性,可以发现Ubuntu在开发者和架构师上占据主导地位。

 

qq%e6%88%aa%e5%9b%be20161208100702

 

专业操作系统的使用也在增长,但是达到了一个分叉点。在专业操作系统中,CoreOS位于第一,Alpine持续增长,反映了Docker在Mac上应用。

 

qq%e6%88%aa%e5%9b%be20161208100707

 

容器镜像操作系统

容器的好处之一就是简化应用堆栈,把它们捆绑在一起,或者把应用的组件打成一个简单的包。然而在容器和更简单的VM二选一中,人们还是经常会有困惑。数据也表明了这种情况,我们可以看到受调查者中选择完整操作系统镜像的占大多数。

 

qq%e6%88%aa%e5%9b%be20161208100715

 

镜像的选择中,Ubuntu再次第一,CentOS和RHEL分别在二三位。

 

qq%e6%88%aa%e5%9b%be20161208100720

qq%e6%88%aa%e5%9b%be20161208100727

 

这些增长带来了教育认知上的普遍问题。对于大多数应用来说其实并不需要一个完整的OS镜像。然而,现实是许多应用仍然被构建在这种镜像之上,理由各种各样——开发简单的选择,操作的原因例如要符合程序,安全策略等等。

也就是说,搭建完整OS镜像容器的想法,引发了运维、安全、部署等角度的多重问题。基于容器应用的微服务带来的快速变化也引发了一系列有趣的挑战——从一个开发者的角度,滚动和发布新版本变得非常方便。

这就给我们带来了一个非常困难的操作难题——我们如何确保安全性,以及在开发加速的同时理解应用的构成。在安全面前,我们看到开发者把CVE分数视为足够的安全——然而那只是一个有用的底线,却远远不够。

本文作者:fryan
原文链接:http://redmonk.com/fryan/2016/12/01/containers-in-production-is-security-a-barrier-a-dataset-from-anchore/

容器,你还只用Docker吗?(下)

刀客info阅读(272)评论(0)

作者介绍
周晖,Pivotal大中国区云计算首席架构师,有丰富的PaaS云实际建设经验,负责过国内某知名银行已经生产上线一年的PaaS云的架构设计和部分功能的实现,参与过某超算PaaS、某超市电商PaaS、某电力PaaS等项目的建设。

我们在上篇文章中谈到CaaS生态圈的公司如何应对Docker用捆绑方式从容器入侵CaaS领域,CaaS厂商通过容器抽象、标准化容器运行时RunC以及容器功能外化插件来重新定义容器。下面我们继续来看CaaS厂商的具体方案。

一、CaaS业界通过分解重组Docker技术来替代Docker的方案

1、K8s通过CRI-O取代Docker容器管理引擎架构

和Cloud Foundry的架构模式类似,K8s也发展了CRI-O来取代Docker,架构图如下:

 

20161129091506

 

CRI-O是Google的Kelsey和Docker CTO所罗门论战之后的结果。论战之后,Google就提出一个设想,要让K8s调度的容器去Docker化,虽然他们一开始说的是要分支出一个Docker的分支来做容器,但是后来考虑到这样做属于刺刀见红,杀伤力太大,所以在2016年6月先弄了一个OCID(OCI守护进程),就是RunC的守护进程,和Docker Daemon有异曲同工之妙,该项目的维护人员此地无银三百两的说“这不是Docker的分支”。

由于OCID过于和Docker Daemon类似,随后Google又把这个项目重新命名为—CRI-O(Container Runtime Interface,容器运行时接口,O表示OCI,也就是RunC的运行时接口),这也反映了Google的心态,一方面通过CRI对容器进行抽象,什么容器我都支持,另外加一个O,我重点支持OCI的RunC,显得不是那么白刀子进红刀子出,大家表面上还是和平共处,而且显得立意更高,通过容器抽象层进一步标准化容器,RunC只是标准化容器运行时,CRI把对容器的调用管理等也标准化,潜台词是Docker Daemon是非标准的、独家的。

同时,Google也在向Mesos推销其CRI-O,希望Mesos也采用其CRI-O的架构。

CRI-O对容器运行时提供基本管理功能,同时Google的K8s提供镜像管理功能(Container/Images),完全可以取代Docker的镜像仓库。K8s一方面支持容器插件技术,另一方面自己也制定实现一些容器插件,最典型的就是容器网络插件,自己定义并实现了CNM的容器网络插件。

因为K8s之前一直支持Docker,为了保持一定的兼容性,K8s继续支持Docker容器,但是不再支持Docker超出标准容器之外的特定功能,也就是把Docker的定位和RunC等同化,Docker做的再多功能也不用。

2、Mesos通过UnifiedContainer取代Docker容器管理引擎

和K8s类似,Mesos也不再只支持Docker容器,而且对容器进行了抽象,项目名字直接就叫”Unified Containerizer”—统一容器。目前还是支持 Docker 和 Mesos Containerizer 两种容器机制,未来就统一到”Unified Containerizer”。架构图如下:

 

20161129091516

 

Unified Containerizer也支持插件架构,但是和Docker的插件不是完全一样,设计的插件类型更丰富,包括三大类:

  • 第一类是进程管理,支持容器之前的进程,这也是Mesos一贯的调度管理策略。
  • 第二类是隔离器: 在容器生命周期的各个阶段提供扩展接口,保护了Docker的几类插件,如网络、磁盘、文件系统、卷插件。
  • 第三类是容器镜像管理,除了容器镜像,还将支持虚机镜像等。

Mesos的统一容器基本就包含了DockerDaemon、Docker仓库等功能。

当然,由于之前一直支持Docker容器,目前阶段Mesos还继续支持Docker,但是也有自己的Mesos Containerizer容器机制。

3、Cloud Foundry通过Garden取代Docker容器管理引擎

从RunC逐步成熟,Cloud Foundry的容器引擎Garden就采用了RunC作为容器运行时,如下图:

 

20161129091524

 

Garden取代DockerDaemon(Docker Daemon有内有Docker Server,Docker Server内有Docker引擎),直接调用RunC来生成容器运行环境,同时CFGarden也支持容器插件,容器插件是独立进程,在网络插件方面优先支持K8s的CMN插件标准。CF Diego有自己的镜像仓库管理,也可以从Docker仓库中获取Docker镜像部署。

这里,我们不得不对Garden的设计多说几句,Garden包括之前的Warden,从一开始的设计就是容器抽象,使得可以支持不同的容器运行时,而且Garden做了三层抽象,所以Garden从一开始就支持.Net应用,不是通过Windows 2016的容器机制来实现,而是在.Net运行时模拟了一个容器的实现,所以Garden支持Windows的几乎所有版本的.Net应用。

K8s CRI-O和Mesos的UnifiedContainerizer都借鉴了Garden的容器抽象设计思路,所以Garden也是第一个支持RunC的CaaS/PaaS。

从这个架构可以看出,Cloud Foundry的Garden基于RunC和容器插件,就替代了Docker的容器功能,共同的是RunC和容器插件,而Garden取代Docker Daemon的容器管理功能。

当然,Garden也支持直接部署Docker镜像。

二、容器生态的演进

1、各方以RunC为核心重新构建容器生态圈,Docker容器被弱化

在对开源Docker分支进行了反复斟酌、放风声、试探和讨论之后,各方觉得杀伤力太大的方案。而重新回到了折中方案,以RunC为核心重新构建生态圈,并且通过插件来弱化容器在CaaS生态圈的重要性。

我们来看看生态圈的演进示意:

 

20161129091532

此图标识了容器生态圈或是CaaS的演进变化

最早只有Docker和Garden两大主流容器,Mesos和Google都专注于CaaS,容器就全部采用Docker,CloudFoundry由于在Docker之前就推出了Warden(后升级到Garden)容器,CF采用自己的容器打造了PaaS平台,形成了一个和谐的生态。

在Docker捞过界了,并且确实有些不符合企业生产系统的因素,包括后向兼容性、商标问题、稳定性问题,于是各CaaS/PaaS生态厂商组建OCI联盟,打造RunC容器引擎,只需要一个简单的容器起停、管理等引擎,把Docker的容器功能一分为二,RunC作为一个简单明了的运行环境,降低复杂度,提升稳定性,适合生产系统。而对于Docker容器的其他功能,则在各自的容器抽象层,依据需要去实现,而且因为Docker本身集成了太多功能,不利于生产环境稳定性要求,各个容器抽象层都采用插件模式,维持容器的简洁性,需要什么功能再插入容器,比如需要网络就可以插入网络插件,需要存储和卷访问,就插入存储和卷的插件。

目前的形势,就形成了Docker和各个CaaS/PaaS厂商在同一层面竞争,在CaaS/PaaS平台,Docker并没有什么优势,但是Docker想把其容器的广泛使用的优势在CaaS中延续,目前看来并不容易。容器的主要用户还是个人用户、开发者用户、运维用户,而CaaS是企业系统,二者目标客户不同、技术要求不同。

随着这个生态的演进,Docker容器会更多的用于开发、测试环境,而RunC在各个CaaS厂商的推动下会在生产环境得到广泛的应用。

K8s目前基本只支持RunC容器,对于Docker超出其容器抽象层之外的功能,一概不支持。同样,Mesos也通过其Unified Containerizer只支持RunC容器,目前还支持Docker,但是未来的规划是只支持Unified Containerizer。CF也通过Garden只支持RunC,不支持Docker超出RunC之外的功能。

2、RunC生态的快速发展

由于Docker的消极抵制,RunC的发展好像并不为人所知,但是RunC的发展还是很快的,RunC本身就简单,通过版本的持续的迭代更新,目前已经达到生产可用,而且主流的PaaS/CaaS纷纷采用。Docker也从1.11开始内置RunC容器运行时。

除了RunC本身的发展,RunC的生态圈也在快速发展,这个生态圈就脱离了的Docker。比如最近的Riddler,就是一个把Docker容器转换为RunC镜像。

详见https://github.com/jfrazelle/riddler。

三、你还只用Docker吗?

Docker作为目前最热的容器开源项目,受到广泛的追捧。但是也要清醒地看到Docker和容器生态圈的种种争斗,Docker通过注册商标和在Docker中内嵌容器集群管理,挤压生态圈其他公司的生存空间,而受到生态圈联盟以RunC和相应的技术来制约Docker。

如果你是开发测试用Docker,那么基本不受影响,可以继续,这也是很多公司对Docker的定位。如果你是生产系统采用Docker(包括Swarm),你就要注意,如果是你自己定制开发基于Docker/Swarm的CaaS(Container As a Service),那问题也不大,出现漏洞或是定制可以自己打补丁,但是要意识到你的补丁不一定能合并到Docker的主干版本。如果是你采用的是第三方给你定制的基于Docker和Swarm的CaaS,你就一定要当心了,他们针对Docker做的定制要合并到Docker的后续版本有相当的难度,因为对于Docker的补丁定制合并,除了Docker公司其他公司几乎是没有什么控制力度的,还包括后向兼容性问题。

作为用户或是容器生态圈的创业公司,不能一棵树上吊死,如果在容器层面只考虑Docker,而不考虑RunC,可能会和CaaS/PaaS生态圈的标准越来越远,未来和CaaS/PaaS的标准容器差异越来越大,主流的CaaS/PaaS厂商和技术,如K8s/Mesos/CloudFoundry均不再支持Docker容器超越RunC之外的功能,而只支持插件对RunC功能的扩展。

业界更普遍的定位是Docker用于开发测试环境,而RunC用于生产环境,所以对于要在生产环境采用容器技术的,一定要研究RunC。

作为容器创业公司,很多是在Docker的风口成立的,但是由于Docker一家独大和Docker注册商标的法务问题,可能还没有在风口起飞。应当可以考虑在OCI/RunC的生态圈进行相关技术的发展,OCI/RunC的生态圈受到实力强大的几家公司的强力支持,如Google、CF基金会、Pivotal、Redhat、Mesos、CoreOS等。而且RunC的生态圈还刚刚起步,还有很大的发展空间。而且作为技术创新,对于技术的前瞻性判断非常重要,方向判断正确,一路辛苦是披荆斩棘,方向判断错误,一路辛苦也是前程堪忧。

国内的公司对RunC的贡献度越来越高,特别是华为,可能是国内公司中对RunC贡献最大的。还有EasyStack、南大索芙特等的贡献,反倒是一些著名的Docker创业公司看不到对RunC的贡献。这一方面反应了华为、EasyStack技术眼光和对社区的贡献,另外也反映了为什么华为和EasyStack在商业上也更成功一些。

四、对一些问题的提前答复

1、RunC也是Docker的,用Docker和用RunC不是一样的吗?

Docker对RunC有重大的贡献,RunC的早期也是基于DockerLibcontainer,但是RunC在OCI下独立发展,有贡献的厂商远远不止Docker。在RunC项目后,在OCI的推动下,各个厂商积极贡献,Docker的代码贡献并不占主导,更谈不上主要是Docker在维护,更准确的说Docker是RunC的重要维护力量之一。

 

20161129091542

 

上图是Git上RunC的代码贡献者排名

前10个贡献者中,Docker只占2位,不得不提国内的公司华为代码贡献排名是相当的靠前。而且RunC的代码贡献者超过100人。

除了Kubernetes/Mesos/CloudFoundry支持RunC容器运行时,Docker的容器从1.11开始也内置RunC作为容器运行时,说明RunC受到最为广泛的支持。

而K8s/Mesos/CloudFoundry明确表示在容器抽象层不再支持Docker超越RunC之外的功能。

RunC属于OCI,不再受Docker注册商标的影响,对RunC的代码贡献不再受限于Docker。

用RunC相当于给你一个干净简单的容器运行时,用Docker相当于不管你要不要,强塞给你一堆可能你不想用的东西。

对于RunC和Docker的详细技术区别,请参考《容器,你还只用Docker吗?(上)》中的4.5章的内容。

2、在Docker如日中天的时候这么说是哗众取宠

Docker现在是如日中天,但是3年前也是刚起步,也许可以说RunC就是3年前的Docker。Docker由于Docker公司自身的商业特征,对容器生态圈其他公司的生存空间的挤压,已经造成了容器生态圈的裂变。

“风起于青萍之末”,如日中天的时候可能就是走向下坡路的开始。Docker一家和其他CaaS生态圈分裂,这条路注定是不平坦的。

3. 黑Docker黑出翔来了

黑Docker的资料很多,所有资料都有出处,有参考内容链接,详见后面的引用。

Docker已经被布道师们说成”无所不能”,稍微有几个不能,我觉得大家还是能区别得出来。

4. RunC是没人管的孩子

RunC的自身发展远不如Docker那么有名气,因为RunC本身就是一个很小的容器运行时,不是针对开发者的,开发者往往是通过Docker接触到RunC,所以RunC的受众远比Docker要少。

但是对于CaaS项目来说,K8s/Mesos/CloudFoundry往往就是基于RunC容器运行时。

RunC的社区也很活跃,除了RunC本身的更新很快,各大CaaS/PaaS生态圈如Google/Pivotal/Redhat/华为/CoreOS等都有专人在贡献代码。

RunC相应的生态空间也在活跃,也有不同的项目在进行中。

RunC是CaaS/PaaS/OCI等生态圈共同的孩子,不是没人看的孩子。

5、容器不需要标准更好

业界也有一些人持这个观点。其实,标准的价值是常识,当然总会有反常识的言论出来。没有标准就没有合力,没有合力哪来的发展。如果Docker公司把闭源,那可以没有标准。既然是开源,又想要生态圈的其他公司和力量做贡献,就要让大家有合力,就要让大家在标准的基础做贡献,而不是把生态圈的其他公司当作免费打工的。

五、总结和展望

Docker和CaaS生态圈在容器上的分裂已经是现在进行时了,虽然大家都没有明说。这也将是容器和CaaS生态圈重要转折事件。让我们来看看目前正在发生的和在未来一年中很有可能发生的事情:
Cloud Foundry率先采用RunC作为容器运行时,而且刚刚做了一个25万个容器集群的测试,https://www.cloudfoundry.org/cloud-foundry-approaching-250000-containers/ 验证了PaaS+RunC的大规模集群的支持。

K8s的CRI-O也会尽快发布,等CRI-O成熟以后,内置的容器运行时就应当是RunC,而不再是Docker了。

Mesos的Unified Containerizer 也应当会在1年之内成熟,随后内置的容器应当也是RunC,而不再是Docker。

在Docker被科普以后,客户更关注的是CaaS而不是容器,再给客户去科普Docker体现不出容器创业公司的价值。

一些不适合容器的Docker应用场景的案例会被证伪,在Docker和容器鲜为人知的时候,各种各样的Docker案例层出不穷,包括一些明显和常识有违的案例,比如交易系统采用Docker, 交易极严格的延时的要求不适合Docker。有的是故意混淆概念,交易本身不在Docker容器中,交易系统相关的一些模块在Docker中,为了突出宣传效果,说交易系统采用Docker。

Docker创业公司分化,越来越多的容器创业公司给别人介绍自己的时候会说我们是K8s初创公司(或我们是Mesos创业公司),不是Docker创业公司,强调自己是CaaS厂商,突出自己不是Docker厂商。当然,也有纯Docker的创业公司,但优势会变成劣势,毕竟在CaaS领域,Docker没有优势。

Docker在容器失去了K8s/Mesos/CloudFoundry的支持之后,会更专注于Swarm,和CaaS的其他厂商的竞争将更直接,但是Docker公司一贯的对企业生产环境特性的不在乎,Swarm很难对其他CaaS形成竞争优势。

RunC的生态圈将越来越丰富,第一个就是把Docker镜像转换为RunC标准镜像(这个已经有了),其次就是各种各样的插件和RunC可以交互,中间还可以衍生出各种插件的功能,如即插即用(动态性)、自动发现之内的。

一年以后,我们再来复盘。

容器,你还只用Docker吗?(上)

刀客info阅读(357)评论(0)

作者介绍
周晖,Pivotal大中国区云计算首席架构师,有丰富的PaaS云实际建设经验,负责过国内某知名银行已经生产上线一年的PaaS云的架构设计和部分功能的实现,参与过某超算PaaS、某超市电商PaaS、某电力PaaS等项目的建设。

一、从一场容器的撕逼战开始说起

从2016年7月底开始,Google Kubernetes布道师 Kelsey Hightower 和Docker的CTO Solomon Hykes在Twitter上发生了一场撕逼大战,主题是要不要用RunC或其他容器来取代Docker引擎以及OCI的意义。

首先是Google的Kelsey挑事,说:“很多平台都可以跑Docker镜像,已经不再需要Docker Daemon了。哪个会成功呢?”

Docker CTO Solomon马上接招:“其他平台跑Docker镜像是假的,其中只有90%能正常工作,其余10%则随时可能会出问题。而且Docker还在演进中。”“所以嘛,声称‘可以跑Docker镜像’的都是在撒谎。”

Kelsey Hightower反讽:“好吧,那我们就没必要再提支持Docker了。我们实际支持的只是Docker的容器格式”,“Docker拥有创建和分发镜像的最佳工作流,而运行时,还是留给它的竞争者们吧。”

所罗门继续强调Docker的不兼容性:“这些都是不完整的、不兼容的支持”,“他们也并不支持镜像格式,镜像的很多信息都会丢失”。

后来,所罗门急眼了,说“OCI就是个伪标准”。

此言一出,惊诧四方,因为OCI有50多家厂商参与,而且Docker还是重要贡献者,有说“标准不是一个人可以决定对错的”,有反讽的 “我相信工程师们乐于听到他们创始人说他们做的工作是假货”。

K8s的老大Tim Hockin直接就说“不爽你就走,不要假装参与”。

所罗门不得不改口说“OCI标准的初衷是好的,只可惜扩展太早,我不认同就得走?”

有人随即反驳“只有你一个人说扩展的太早,这是明显的利益投射”。

所罗门还嘴硬“就因为我是唯一的不认同者,那我就必须离开?”

Kelsey随后则直点主题,“有两个问题在台面上,一是容器需不需要标准化,二是需不需要由Docker来领导这个标准化的工作?”

Kelsey再以嘲讽的口吻自问自答“如果是Docker来回答这些问题,对第一个肯定是说不,那干脆对第二个问题也同样说不吧,这可不是对和错的问题”。

因为事关OCI,Docker现在这么鄙视RunC,OCI不得点出Docker你也是参与者就别闹了, “Docker参与在OCI运行时和镜像规范,也参与了每周的开发会议”。

Kelsey乘胜追击,代表业界吐了个槽,“我一直相信Docker会给容器带来很多,但是我真的担心一个人想控制的太多”。Docker公司的控制欲早成为人们的吐槽点,什么都想做,把整个生态圈其他的参与者逼到墙角去了。

看业界大佬撕逼,感觉和咋人民群众撕逼没太大差别。所罗门的撕逼技巧明显略逊一筹,有点像祥林嫂反复说“其他容器就是和Docker不兼容,包括RunC”,但是没说出个哪里不兼容的道道。

二、容器撕逼之争反应了容器生态面临的问题

我们来总结这次著名的撕逼事件的来龙去脉,这会成为容器界一个关键的历史转折事件。容器之争始实际上是很早之前就起源于Docker生态面临的问题。

1、Docker商标的注册围剿了容器生态圈

从表面上看,是容器标准之争,其实,反应的是赤裸裸的利益问题。Docker从容器开始,在获得社区的热烈响应之后,就进入了圈地过程,而且第一招圈地就非常凶悍,把公司从dotCloud改名为Docker,然后注册Docker商标,商标意味着当其他公司使用未经Docker社区许可的补丁、代码或软件包的时候时可能面临法律责任。这种情况下,一个公司可能因为补丁尚未经过Docker公司许可,抑或尚未被合并到项目中,而不能为客户提供技术支持。

这不只是法务上的圈地,对于很多采用Docker名字的,Docker公司给予了实际行动—口头警告(谁叫Docker是人家注册的名字呢,就好比weibo.com就是微博),包括你建一个群名不加修饰限定的叫Docker,或是你要写本书,不加修饰的叫DockerXXX,都容易受到Docker的警告。从法务上看这确实也属于侵权,就看Docker要不要告你。

其后果就是第三方Docker生态厂商被迫忍受Docker公司任何对该开源项目作出的决定,在问题出现的时候等待Docker公司的补丁。最好的结果与Docker达成某种协议,由Docker公司来保证提供稳定的发行版本。那Docker的生态公司就沦为Docker公司的代理商了。

2、Docker携容器引擎优势进入容器集群管理,挤压了容器生态圈的其他厂商生存空间

如果只是口头撕逼,那大伙儿看看热闹就可以了,事实上这涉及到巨大的利益和整体生态环境的分歧。

在Docker获得广泛关注以后,就利用Docker容器的广泛性优势来挤压生态圈其他伙伴的生存空间。直接把Swarm内置在Docker中。和当年的Microsoft通过Windows捆绑IE来打击NetScape有异曲同工之妙。

Docker公司原来只在容器领域发展,K8s/Mesos等做容器集群管理,属于CaaS(Container as a Service),相互补充,互不竞争。等Docker容器被广泛关注以后,Docker进入容器编排市场,收购了相关的技术以后推出Swarm的容器集群管理,从容器进入CaaS市场。2016年7月发布的Docker 1.12把Swarm内置到Docker中去了,Docker Swarm作为容器集群管理软件,内置在Docker中,几乎就是Windows捆绑浏览器IE的模式,这就是用不平等的市场优势打击了Google的K8s和Mesos等,Google也不是吃素的,所以7月底马上就是和Docker CTO口头开撕。

对于Docker生态圈的集群管理软件K8s和Mesos等来说,不但是不平等的竞争,最关键的是在容器生态圈最能带来商业价值的就是容器集群管理,单单容器本身并没有太多的商业价值,容器没有集群管理是很难进入企业运行环境的。因为容器的直接商业价值并不大,CaaS厂商也没有自己做容器。容器用于生产系统,就必须有容器的集群管理,而K8s和Mesos已经进入了这个商业领域并且取得了一定的优势。现在Docker进入这个领域,就直接和容器集群管理的公司竞争,但Docker又是必须进入这个领域,如果不进入这个领域,很难取得商业成功, Docker本身又经过多轮风投,风投给Docker带来了巨大的盈利压力,如果久久不能盈利,那风头的脸色不会那么好看了。

如果是公平竞争还好,比如Docker单独发布Swarm的Docker集群管理,但是Docker直接把Swarm内置到Docker中去,安装部署Docker就带了Swarm,而Swarm的很多功能和K8s和Mesos是重叠的,K8s和Mesos再用Docker就显得功能有大量重叠,而且带来了系统的复杂性和不稳定性。

三、Docker的问题——业界对Docker的吐槽

在Google和Docker口水战之后,业界对Docker的吐槽越来越多,主要包括以下几点:

1、Docker向后兼容性问题

Docker被业界诟病最多的就是后向兼容性,Docker的新版本更关注的是革新性,而不是兼容性,但是,对于一个生产系统来说,后向兼容性至关重要,没有后向兼容性,意味着每次Docker升级都带来巨大的风险。

这也和Docker的企业文化有关,Docker更倾向于采纳新技术,实现突破性的功能,这是典型的初创公司的企业文化,不断的追加新功能,而不考虑企业级特性,更不考虑后向兼容的束缚。这个好处是能在个人粉丝中取得共鸣,这也是Docker快速流行的一个重要原因。任何特征都可能是双刃剑,这种企业文化并不适合企业级,不考虑生产运行的可用性,对企业级应用来说可能是灾难性的。

我们看看业界人士是怎么说的:“Docker不断地破坏向后的兼容性”,RackN公司的CEO Rob Hirschfeld说。RackN公司的应用程序生命周期管理平台同时使用和提供了Docker组件,因此对后端的改动将会对其支持的客户的业务造成影响。

“Docker将Docker Engine用作一个产品,而不是一个社区用来构建自有服务的组件”,Hirschfeld指责道。这种基于产品的策略意味着使用者被逼着在Docker发布新的革新特性或者合并新的组件(如Swarm)的时候去修复其破坏的向后兼容的问题。

“尽管我们会使用这些发布的特性,然而这些改动会带来一系列与稳定性、版本、迁移和后端兼容相关的问题”。

Bob Wise,一名三星SDS云工程师,也同样呼吁Docker放慢其容器创新的脚步,该公司同样提供了基于云的容器相关支持服务。

“如果你的团队在深度使用Kubernetes、Mesos或Cloud Foundry,你需要一个稳定、简单、无奇的容器实现方案,仅有最少的基本功能,由社区协商镜像的创建、命名和发布”,Wise的一篇博客中写道。“你需要使用每个都人都在使用的一个相同的、简单的、无奇的容器实现方案。作为一个社区,我们需要放缓对于基本构建组件的变更速度。唯有稳定性才能让构建其上的系统蓬勃发展。”

2、Docker容器在企业级方面还有待提高

Docker虽然一直宣称Production Ready,但是在实际的生产系统中同样受到不少诟病。

看看业界人士的说法:

Apcera技术产品经理 Phillip Tribble在个人博客中,以一种外交辞令的口吻,让Docker不要再把其新推出的特性鼓吹成一个完工的企业级可用的产品。Tribble写道:“让互联网或者大会充斥着营销材料,宣扬各种令人振奋的新特性,但实际上却不如所说那样能用,不是一个明智的做法”,Apcera的商业模式一部分是基于提供Docker容器的支持。

Tribble的帖子引发了其他人在Hacker News上表达他们的Docker经历,包括一些新版本带来的让人伤心的bug。一位读者谈到一天中启动70,000到90,000个容器,约9%左右的会因为“各种Docker bug”遇到问题,这个比例最近的一次升级后下降到了4%。

但也有一些人在称赞Docker的稳定性,“我们一直在生产中使用Docker约3年了,还没有发现什么大的问题”,另一外读者评论说,“它将一些很炫的Linux内核特性用简洁的方式封装了起来”。

当然也有不少Docker的支持者认为Docker公司的软件是稳定的。同一个产品,在不同的客户有截然相反的反应说明有的用的好,有的用的碰到不少问题,在不同的环境下缺乏一致性,这也是企业生产系统的大忌。

3、Docker捞过界了,越过了红帽的操作系统界限?

哪些功能应该有Docker来实现,哪些功能应该由底层操作系统或者技术栈中的其他组件来负责处理?

在今年的很多会议上,包括 LinuxCon North America 2016,红帽工程师 Dan Walsh 说红帽陷入了困境,一方面客户越来越多的使用 systemd 来初始化Linux系统,而另一方面Docker似乎不愿使用systemd,取而代之使用Docker Daemon来提供初始化,服务激活,安全和容器日志的相关功能。

“在过去的三年里,我们一直试图使systemd和Docker更好的整合,而我却发现,两个领导人都非常强烈的坚持己见”,Walsh说,两个领导人指 Hykes和systemd的创造者-Lennart Poettering

“所以,当机器的时候,谁来负责启动系统服务,是systemd还是Docker?”Walsh问到。一个拙劣的系统实现可能会导致systemd和Docker互相冲突。

红帽为自己的客户维护着自己的Docker版本分支,红帽分支中的补丁Docker有一天可能会合并,或者永远不。红帽也冒着巨大的风险,红帽的客户也冒着巨大的风险。所以红帽对Docker的支持其实远不如Ubuntu,因为Docker已经侵入到OS的领域了。

即使是面对以上种种吐槽,Docker也不打算折中一下,甚至也不打算照顾这些意见,而是继续我行我素。

四、容器生态圈集群管理厂商的应对

——不用Docker,把容器引擎拆解重组

撕逼只是矛盾爆发的阶段总结,后面就开始进入实质性的对抗阶段了。容器生态圈的集群管理厂商如Google/Mesos也不是吓大的,快要被Docker断了财路——— “人为财死鸟为食亡”,其反应也直取Docker命门——在其CaaS中废弃Docker,对容器进行抽象,用谁的容器都可以。容器运行时不再用Docker,而直接采用RunC,容器扩展功能通过插件来实现,基本就是全抛弃Docker了,这对Docker来说几乎是生死之战。

其实,容器技术本身的壁垒不高,Docker 2013年一开始也就是几十人的开发队伍,到现在也只有200多人,各大厂商一直没有重视这一块,因为单单容器的商业价值比较低。真正要投入做容器,也只是分分钟的事情,只不过Docker已经在容器领域形成了气候,所以要走些变通的曲折路线。

各大厂商一起做个RunC,大家再只用RunC还是轻而易举的。

我们再来看容器最主要的两个的技术来源:

  • Namespace—来源于IBM
  • cGroup—-来源于Google

其他的容器核心技术都是Linux操作系统的功能,容器的核心技术是和Linux操作系统密切相关的,Docker本身在容器核心并没有什么贡献,NameSpace和cGroup都不是Docker的,也和Docker无关。Docker也不是最早用容器技术的,Cloud Foundry比Docker更早把容器用于PaaS。

所以容器生态圈的公司撇开Docker做一个容器标准并不是什么难事。

我们再从时间线来梳理这个撕逼事件,让大家更直观的理解:

 

20161125090920

 

1、提前铺垫:先通过RunC把容器运行时分离出Docker

2012年,随着Cloud Foundry的PaaS率先引入了容器技术,容器技术发展的愈发火热,特别是Docker成为流行技术,形成了广泛的生态圈,由于Docker一贯的控制欲,让生态圈的其他大小伙伴难以参与,为破解这种状况。Google先是支持CoreOS打造了Rocket容器,在Rocket和CF容器Garden的竞争压力下,Docker终于同意容器标准化—-RunC项目成立,通过RunC对容器运行时进行标准化。

于是容器生态圈终于达到了拆解Docker技术堆栈第一个小目标—通过RunC把容器运行时独立于Docker之外。在 2015年6月成立OCI(Open Container Initiative)组织,挂在Linux基金会旗下。旨在围绕容器格式和运行时制定一个开放的工业化标准。该组织超过50家大小成员,包括谷歌、Pivotal、Docker、CoreOS、微软、亚马逊、华为等一系列云计算厂商,按照该开放容器格式标准(OCF, Open Container Format)制定的一种具体实现,当然Docker是RunC的重要贡献者。

OCI对Docker意味着什么,Docker不是不清楚, 知道RunC是来抢食的,除了会削弱自己的优势,也还会被OCI标准束缚住,限制自己的发挥,所以Docker对OCI是消极抵制,但是无法和整个生态圈抗衡,不是不接受OCI和RunC。

面对Google、RedHat或者Microsoft这样的大公司,不管从技术实力还是财务实力,以及政治关系处理上,Docker应该都很难占到太多便宜。但是技术大势所趋,Docker也无法抗拒。

2、RunC容器格式标准是什么?

制定容器格式标准的宗旨概括来说就是不受上层结构的绑定,如特定的客户端、编排栈等,同时也不受特定的供应商或项目的绑定,即不限于某种特定操作系统、硬件、CPU架构、公有云等。

最核心,是通过格式标准化来脱离Docker,有利于CaaS生态圈的公司各自发展,但是在标准层面汇聚。

3、RunC容器标准化宗旨

标准化容器的宗旨具体分为如下五条。

  • 操作标准化:容器的标准化操作包括使用标准容器感觉创建、启动、停止容器,使用标准文件系统工具复制和创建容器快照,使用标准化网络工具进行下载和上传。
  • 内容无关:内容无关指不管针对的具体容器内容是什么,容器标准操作执行后都能产生同样的效果。如容器可以用同样的方式上传、启动,不管是php应用还是mysql数据库服务。
  • 基础设施无关:无论是个人的笔记本电脑还是AWS S3,亦或是Openstack,或者其他基础设施,都应该对支持容器的各项操作。
  • 为自动化量身定制:制定容器统一标准,是的操作内容无关化、平台无关化的根本目的之一,就是为了可以使容器操作全平台自动化。
  • 工业级交付:制定容器标准一大目标,就是使软件分发可以达到工业级交付成为现实。

RunC标准化是瞄准工业级交付和运行时的,和Docker定位不一样。各个CaaS/PaaS生态厂商需要一个标准的容器运行时,然后围绕着这个标准运行时各自发挥自己的技术优势,做编排的、做集群管理的、做资源调度等等,形成真正的容器生态圈。

4、第一步:虚张声势扬言对Docker容器另起分支,废弃Docker公司对Docker的独一控制权

在和Docker撕逼之后,引起了业界的集体吐槽,然后Google进入第一步:虚张声势,先来个大杀招吓唬Docker——尝试分支开源Docker来废除Docker公司对Docker容器的独家控制权。

先是Google方放出风声,要对开源的Docker Engine重起炉灶—分支出一个容器,马上在业界引起巨大的波澜。

“在诸多正在考虑的选项之中,包括可能会将整个开源的Docker Engine一起重起炉灶(fork)。据一些接近讨论的人士透露,相关代表来自Red Hat、Google、CoreOS、华为和两家大量使用Docker的客户。”

随后大家对Docker的代码库稳定性不足表达了各自的忧虑,因为这可能会在生产环境下基于Docker构建附加服务或者向客户提供技术支持的时候招致各种麻烦。在表达各种对Docker公司在Docker Engine上管理的失望之后,没有得到Docker的正面响应,相当多的技术专家和公司是支持分支的。因为Docker也不是吓大的,对种种指责不予理会。

但是,也有很强的声音担心Docker从此支离破碎:

“目前发生的这件事情,如果处理不得当,会让让容器生态系统支零破碎,并导致单个的容器再无可能适配多种目标运行时环境。” 一位Hacker News上的观察员指出。

鉴于直接分支对整个生态会产生不可预知的影响,属于杀敌三千自损八百的,虽然Docker CTO所罗门当初说OCI是个伪标准就是“杀敌三千自损八百”的招,但是碰到猪队友不能把自己也变成猪。直接分支停留在口头上。

5、第二步:通过RunC和插件来拆解Docker技术堆栈

在和Docker撕逼之后,引起了业界的集体吐槽,然后Google和业界进入第二步:

随着RunC标准化的发展,RunC逐步成了构建容器运行隔离环境的标准,和Libcontainer的功能类似,Libcontainer对RunC也有很大的贡献。那到底RunC和Docker是什么关系,如下图:

 

20161125090946

 

Docker从1.11开始就采用了右边的架构,这其实是Docker公司折中妥协的结果,因为面对Rocket和Garden的竞争,如果不支持RunC,那么在容器马上就会进入分裂竞争状态。

而OCI业界希望能够在容器的运行环境标准化,也就是构建出一个容器运行环境的这部分能标准化,在容器运行环境下不需要Docker庞杂的功能,容器运行时这部分占Docker的整体功能比重很小,所以OCI组织很快就达成的一致,发展RunC容器运行时。

所以,理解Docker和RunC的关系,你可以理解为RunC是Docker一部分,而且是构建容器隔离运行环境的一部分,而这一部分,也恰恰是CaaS的厂商所需要的,他们只需要一个生产环境下的容器环境构建,不需要容器的镜像打包等,这属于开发测试所需。

通过RunC,也基本确定了CaaS/PaaS产品如Cloud Foundry/K8s/Mesos等只需要RunC这个容器生产时的运行环境,而Docker更多的用于开发测试时。

除了RunC,容器插件也是一个关键的公有技术,把容器的功能扩展和外部交互的功能插件化,而插件在开源社区相当活跃,插件主要是四类:安全认证、存储卷管理、网络、IP池。比如各个存储厂商都在开发或是已经开发了自己的存储插件。

而这些插件也可以和RunC交互,通过上面一层的集成,可以让RunC用到这些插件。而插件也基本外化了Docker的功能。

虽然Docker定义和开发了很多插件,但是插件可以各自开发。插件只要提供接口就可以容器运行时交互。不再局限于某个公司的插件。这里不得不提到K8s开发的网络插件CNM和Docker自身提供的CNI就不一样,虽然理论上是可以相互兼容,但是实际上是两套实现机制,而且CNM得到了CaaS/PaaS厂商更广泛的支持。

通过RunC和插件,把Docker容器引擎的功能进行了分拆,而且分拆的部分都有了替代品,只等下一步。

6、第三步:CaaS生态厂商通过容器抽象、RunC和插件来重组自己的容器技术堆栈

如下图是各个业界厂商对Docker容器技术堆栈的进一步分拆,然后进行组合,形成各自自己的容器堆栈。分拆不是目标,是手段,组成成自己的容器才是目标。和我们的国产化替代是不是有点类似?

首先把Docker的技术堆栈分解为容器运行时RunC、插件、容器管理进程和容器仓库。因为已经有了RunC的基础,而且插件可以公用,各个厂商只要做容器进程管理和容器镜像管理,既然是新的技术架构,各个厂商也考虑到容器的兼容性,大家很一致的做了一个模块,称为容器抽象,无论是Mesos还是K8s。有的把容器镜像也一起做在容器抽象层,有的是单独再做一个镜像管理。

看下图右边的重组后的技术架构,完全没有了Docker,也不需要Docker,但是很自然而然的取代了Docker的容器。这就是很典型的对Docker技术栈分解,先取代最核心的容器运行时RunC,再把功能外化到插件,然后再做一个容器抽象层,彻底肢解并取代了Docker。

 

20161125090954

 

注意红色的框架,通过RunC和插件,CaaS/PaaS业界把他们所需的容器功能从Docker中独立出来了,也就是有了RunC和插件,CaaS/PaaS完全可以不需要Docker就构建出CaaS/PaaS运行环境。

行文至此,大家应当对容器生态圈的撕逼事情的来龙去脉、各个厂商的应对、撕逼原因以及整个容器生态圈的巨大变化有个初步了解,欲知后事,且听下回分解。

Docker实战:一部奋斗史

刀客info阅读(241)评论(0)

前段时间,一篇《Docker实战:一部失败史》的文章在2b这个圈子惊起一片哗然,其关注度不亚于c端消费者的双十一。原文作者(国外)写这篇文章的主观意愿不得而知,当然我们也不是一个动机论的拥趸,仅作为一个再普通不过的容器技术创业者身份,聊聊我们的Docker实战:一部奋斗史。

Docker并不是一门新技术。

如果诸位之前就使用其他容器技术,那么上手Docker很简单。如果之前不了解容器技术也没有问题,只是一些容器的思维需要你去了解然后再去使用。就像使用智能机之前,并不需要你一定使用过非智能机作为铺垫。Docker公司推出的以容器管理为核心的一整套工具是在已有技术(LXC,并借助SCM的设计思想)的基础上做的延续性改进,所以Docker并不是一门新技术,他的创新在于思想层面,我总结以下几点:

1.打包(封装)

Docker利用容器技术将软件的代码和环境打包在一个镜像中,这是它的技术特性。从思想层面考虑,它改变了软件交付方式,让软件的生产者将软件做出了之后交付到最终用户那里保持绝对的一致性。通俗地讲,容器技术将软件的运行与环境彻底隔离了。

给大家举个例子:

windows系统大家都用过,微软花了10几年的时间,自从windows系统问世以来,一直到win7才基本上解决一个困扰了多年的问题——共享动态链接库的隔离。说得通俗一点就是隔离每个软件的依赖文件使之互相不受影响。

问题是怎么产生的呢?

软件是由不同公司编写的,但库又是共享的,因此随着软件的发布,软件厂商会将自己的动态库打包发布,到了用户那里直接安装,大家别忘了这个是共享库,A软件用A版本的,B软件用B版本的,最终我们可爱的操作系统就因为安装一些软件被搞崩溃蓝屏,坠入到平均1个月重装一次系统的循环当中。

 

20161114181652

注释:软件把机器搞死了,如何破? 你重装系统试试。

 

注释:大家都知道这个对话框的提示是开玩笑的对吧,即使你重新装一遍软件又怎样呢?可能其他的软件又不能运行了,怎么破? 你再重装系统试试。

注释:大家都知道这个对话框的提示是开玩笑的对吧,即使你重新装一遍软件又怎样呢?可能其他的软件又不能运行了,怎么破? 你再重装系统试试。

 

微软的共享链接库隔离说白了就是要减少软件对系统的依赖性。但微软做了这么多年都没有做到彻彻底底的隔离。

但到了2013年Docker做到了。他用了巧妙的方式将软件和依赖的文件(环境)封装成包(镜像)。当我看到这种方式来解决软件交付问题的时候,仿佛感到一丝带着情感的风吹到我的心坎里一样!“Docker太TM了解我们这帮开发者了”。当我将这种方式(思想)传达给运维兄弟的时候,运维兄弟迷茫的双眼顿时发出一道闪电,恶狠狠的扔出来一句: “我 *和谐和谐*再也不用一次次折腾环境了!”

2.隔离

新技术都是在旧有技术上“生长”出来的,Docker最早基于LXC技术并进行技术革新。但任何技术的演化都与其当时所处的时间点是有关系的。2013年虚拟化技术正在逐步成熟,处于快速增长期,业界都在围着虚拟化技术来争抢市场份额。目的是为了抓住云计算这杆大旗。

但虚拟化技术是“生长” 在物理设备上的技术。它本质上是优化物理设备的使用效率。它没有抓住云计算的要害。但以Docker为代表的容器技术的出现,它与虚拟化技术完全不是在一个维度上的产品。容器技术解决的是软件交付效率和成本的问题,它直达了用户的最终诉求。云计算的最终目的不就是为了提升产品的交付效率,降低交付成本吗?虚拟化技术提供土壤,容器技术才得以开花结果!

既然是隔离,那么容器技术的隔离只需要保证软件和主机之间的隔离就可以了。谈什么隔离性不好,拿容器当虚拟机用的同学们可能还需要调整下思路。
任何事物都有其适用性,技术也是如此,“不要因为手里拿把锤子,看什么都像钉子。”

3.发布

截至目前,镜像仓库可以说是Docker最伟大的发明!他将镜像以代码仓库的形式进行版本管理,并支持通过Push/Pull的方式来发布和分发镜像。它为软件的交付提供了载体。

我们已经感受到了代码管理和分布式开发的便利,镜像仓库为我们提供了软件的版本管理和全球分发。想想我们以前经历,以及正在经历的获取软件的方式吧。你用或者不用,镜像仓库就在那里。

额外说一句,那次全球的docker大罢工对企业生产环境会造成影响,尤其是前一篇文章作者说的互联网金融公司的场景,我觉得这个问题大家看看就好,这应该是作者开的玩笑。

我们的奋斗史【简短且主观】

13年初,我们开始接触Docker。Docker在刚推出时虽然还是个带着实验性质的产品,但完全可以进行完整的测试。请注意这里面的完全和完整两个词,Docker虽是个新鲜货,但是实践证明测试环境下是没有问题的,所以我们尝试将其用在生产环境下。

2014年初,公司内部自行研发出了一套容器管理系统,使用在内部开发和部分服务的生产环境中,又一次证明生产环境下也是没有问题的。(注:们在2014年3月份已经将容器应用到生产环境中, 当时Docker的版本是0.9.0 ,我们生产环境的规模是4台2U的惠普服务器,32G内存。没有发生任何线上事故。)

2015年4月我们从之前的公司出来创业,三年的落地经验和不断迭代迭代的产品进行商业化运作,最终面向用户的是产品基于容器技术的应用管理平台。我们为什么能放弃现有的一切,投身于才刚刚出现2年的技术来创业呢?

一是因为我们看到了未来的发展方向,发现了另外一个维度的市场。容器技术能真正发挥云计算‘简捷高效‘的特点。

二是考虑到还有很多在努力填坑的朋友和公司,为了让他们更快的享受云计算和容器技术带来的红利(《一部失败史》恰恰验证了我们的这个想法)。

结语

只要有解决问题的思想,能用钱解决的问题都不是技术问题。

Docker实战:一部失败史

刀客info阅读(276)评论(0)

背景信息。我们是一家小公司,有几百台服务器。在核心部分,我们运行一套财务系统,每天处理的资金大约数百万美元(每年几十亿美元)。

可以说,我们的预期要求比一般公司要高,我们对于生产环境相当重视。

总的来说,如果你没有在生产环境下大规模使用Docker,及/或如果没有长期使用Docker,未遇到所有这些问题很“正常”。

我想要指出的是,这些问题和变通方法是一年多点的时间里面出现的,但用一篇只需10分钟看完的文章加以概述。

无论怎样,过去发生的一切都已经是过去的了。最重要的部分是路线图。这就是你运行Docker(或改而使用自动扩展组)所需要知道的方面。

引言

我生平第一次遇到Docker还是在2015年初的时候。我们试用Docker是想一探究竟,看看它能不能给我们带来好处。那时候还无法在后台运行容器,也没有任何命令可以查看什么进程在运行、调试或者通过ssh进入到容器。那次尝试很快宣告结束,Docker毫无用处,它更像是一个测试版原型,而不是正式版本。

快进到2016年。新工作、新公司、围绕Docker的炒作都在疯狂增多。我们的开发人员把Docker部署到生产项目,结果被卡住了。从好的方面来看,运行(run)命令总算管用了,我们可以开启、停止和查看容器。容器还算实用。

截至本文截稿时,我们在生产环境中有12个容器化的应用程序,散布在31个基于AWS的主机上,每个主机1个Docker容器(注意:下文介绍了原因)。

下面叙述了我们使用Docker的历程,这个过程充满着危险和意想不到的转折。

Docker在生产环境中的问题

Docker的问题:破坏性的变化和回归

我们运行了所有这些版本(或试着运行):
1.6 => 1.7 => 1.8 => 1.9 => 1.10 => 1.11 => 1.12

每个新版本都带来了破坏性的变化。今年初,我们从docker 1.6开始入手,运行单单一个应用程序。

3个月后我们更新了版本,因为需要一个只有后期版本才有的修正版。1.6分支已经被遗弃。

版本1.7和版本1.8无法运行。于是我们升级到了版本1.9,结果两周后发现它存在一个严重漏洞,于是我们又升级到了版本1.10。

Docker版本之间存在各种各样的细微的回归。它不断带来意想不到的破坏。

我们不得不调试的最棘手的回归与网络有关。Docker完全抽象了主机网络部分。这牵涉端口重新定向、DNS技巧和虚拟网络,可谓一团糟。

另外,去年Docker从官方的Debian软件库中删除,后来软件包由docker.io更名为docker-engine。这一变更之前的说明文档和资源过时了。

Docker问题:无法清理旧的镜像

Docker中最受期待也是最缺乏的功能就是清理旧镜像的命令(早于X天或X天不用的镜像)。考虑到镜像经常更新,每个镜像占用的空间超过1GB,存储空间是个重大问题。

清理空间的唯一办法就是运行这个命令,最好是每天按计划运行:
docker images -q -a | xargs –no-run-if-empty docker rmi

它列出所有镜像,然后清除。运行中的容器目前使用的镜像则无法清除(给出错误信息)。很麻烦,但还算管用。

Docker之旅始于一段清理脚本。这是每家企业组织都要经历的一种初始化仪式。

可以在互联网上找到许多尝试的方法,但没有一个很有效。没有API可以列出标有日期的镜像,有时虽有,但是在6个月内就被废弃了。一个常见的策略就是,从镜像文件读取日期属性,并调用“docker rmi”,但是命名变化后,这一招失灵了。另一个策略就是读取日期属性,直接删除文件,但要是没做好,这会引起损坏,除了Docker自己,别人根本做不好这项工作。

Docker问题:内核支持(或者缺少内核支持)

内核、发行版、Docker和文件系统之间的交互方面有着没完没了的问题。

我们在生产环境中使用带backports的Debian稳定版。我们开始在2015年11月发布的Debian Jessie 3.16.7-ckt20-1上运行。这个版本存在一个重大的关键漏洞,导致主机莫名其妙地崩溃(平均每几个小时就崩溃一次)。

Linux 3.x:不稳定的存储驱动程序

Docker有各种存储驱动程序(https://docs.docker.com/engine/userguide/storagedriver/selectadriver/)。唯一得到广泛支持的驱动程序就是AUFS。

AUFS驱动程序不稳定。它存在几个关键漏洞,会引发内核崩溃(kernel panic)、导致数据损坏。

它至少在所有“linux-3.16.x”内核上都出过问题。至于原因,我们毫无头绪。

我们非常密切地关注Debian和内核更新版。Debian在常规发布周期外还发布特别的补丁。2016年3月左右,AUFS有了一个重大的修正版。我们原以为它是真正的修正版,到头来却发现并不是。之后,虽然内核崩溃不常发生了(每周发生,而不是每天发生),但是这个问题依然存在,很碍眼。

今年夏天重大更新版中出现了一次回归,又带来了之前的严重问题。它开始逐台终止持续集成(CI)服务器,平均每2小时就终止一台服务器。有人迅速发布了应急补丁,以修复这个回归。

2016年发布了AUFS的多个修正版。一些严重问题得到了修复,但是还有更多的问题依然存在。AUFS至少在所有“linux-3.16.x”内核上不稳定。

Debian稳定版在内核3.16上卡住了。它不稳定。除了换成Debian测试版(可以使用内核4),没有什么其他法子。
Ubuntu LTS运行内核3.19。无法保证这个最新的更新版修复这个问题。更换我们的主操作系统会带来太大的破坏,但我们实在无计可施了,于是有一段时间考虑这一招。
RHEL/CentOS-6在内核2.x上,RHEL/CentoS-7在内核3.10上(Red Hat后来开发了许多backports)。

Linux 4.x:内核正式叫停对Docker的支持

众所周知,AUFS有没完没了的问题,它被开发人员视作累赘。作为一个由来已久的目标,AUFS文件系统在内核版本4中终于被丢弃了。

没有非官方补丁支持它,没有可选模块,没有任何backport,什么都没有。AUFS完全不见了。

那么,没有了AUFS,Docker如何运行?它无法运行。

于是,Docker的人员编写了一种新的文件系统,名为overlay。

“OverlayFS是一种现代的统一文件系统,类似AUFS。相比AUFS,OverlayFS的设计更简单,并且自版本3.18以来就在主线Linux内核中,可能速度更快。”— Docker Overlay文件系统驱动程序

请注意:它并不向后移植到现有的发行版中。Docker从来不关注向后兼容性。

补充说明:Overlay这个名称既指支持它的内核模块(由Linux维护人员开发),又指使用它的Docker存储驱动程序(这是Docker的一部分,由Docker开发)。它们是两个不同的组件(历史和开发人员可能会有重叠)。问题似乎主要与Docker存储驱动程序有关,而不是与文件系统本身有关。

Overlay大失败

文件系统驱动程序是一个复杂的软件,它需要很高级别的可靠性。老读者会记得Linux从ext3迁移到ext4。编写要花时间,调试要花更多时间,将其作为流行发行版的默认文件系统来发布要花的时间就更长了。

一年内搞出一种新的文件系统是不可能完成的任务。考虑到这项任务派给了Docker,这实际上很可笑,因为Docker的版本一向不稳定,时常有灾难性的破坏性变化,我们绝不希望这种情况出现在文件系统中。

长话短说。这方面进展不大顺利。你在网上搜一下还是能找到可怕故事。

在最初发布1年内,Overlay的开发工作就被叫停了。

然后出现了Overlay2。

“overlay2驱动程序旨在克服overlay的局限性,但是只与Linux内核4.0[或以后版本]和Docker 1.12兼容”— Overlay vs Overlay2存储驱动程序。

1年内搞出一种新的文件系统仍是不可能完成的任务。Docker刚试过,但失败了。不过它又在尝试!我们会看看几年后结果怎样。

眼下,它在我们运行的任何系统上都得不到支持。我们无法使用它,甚至无法测试它。

汲取的教训:正如你从Overlay以及后来的Overlay2中可以看到,没有backport,没有补丁,没有向后兼容性。Docker一味向前迈进,结果破坏了系统。如果你想要采用Docker, 也得向前迈进,密切关注来自Docker的版本、内核、发行版、文件系统和一些依赖项。

补充内容:全球性的Docker故障

2016年6月2日,大概上午9点(伦敦时间)。新的软件库密钥被发到了Docker公共软件库。

直接后果是,只要在配置了故障软件库的系统上运行“apt-get update”(或同等命令),就会失败,出错信息是“错误https://apt.dockerproject.org/哈希值总和不匹配”

这个问题波及全球。它影响了配置Docker软件库的全球所有系统。它在所有的Debian和ubuntu版本上得到了证实,与操作系统和Docker版本无关。

全球依赖Docker安装/更新或系统安装/更新的所有持续集成管道都受到了破坏。不可能在现有系统上运行系统更新或升级。不可能创建一个新的系统、将Docker安装在上面。

一段时间后,我们拿到了Docker员工发来的更新版:“发布更新版;我在内部提出了这个问题,但需要修复这个问题的人在旧金山(时差与伦敦相差8小时),所以还没有到位。”

我个人在内部向开发人员宣布了这一点。如今,没有Docker持续集成,我们无法创建新的系统,也无法更新依赖docker的现有系统。我们的希望全寄托在旧金山的那个家伙,他目前在呼呼大睡。

在佛罗里达州的Docker人员大概在下午3点(伦敦时间)发布了更新版。他醒着,发现了这个问题后编写修正版。

密钥和软件包随后重新发布。

大概下午5点(伦敦时间),我们试图核实修正版。

由于Docker,出现了7个小时的全球性故障。那次故障之后留下的就是GitHub issue上的几则消息(https://github.com/docker/docker/issues/23203)。没有事后分析。尽管这次故障带来了灾难,却几乎没有什么科技新闻或媒体报道。

Docker注册中心

Docker注册中心负责存储和提供Docker镜像。

自动化持续集成构建 ===> (成功后)将镜像发送到===> Docker注册中心
部署命令<=== 获取镜像,来自<=== Docker注册中心

有一个公共注册中心是由Docker运营的。作为一家企业组织,我们也运行自己的内部Docker注册中心。它是在Docker主机上的Docker里面运行的Docker镜像。Docker注册中心是最常使用的Docker镜像。

Docker注册中心有三个版本。客户机可以从下面任何注册中心独立获取:

  • 注册中心v1(https://github.com/docker/docker-registry),现已被废弃和丢弃
  • 注册中心v2(https://github.com/docker/distribution),用Go完全重写,2015年4月首次发布
  • 可信注册中心(https://www.docker.com/products/docker-datacenter),这是在文档到处提到的一种(收费?)服务,不确信它是什么,干脆忽视它。

Docker注册中心问题:丢弃和淘汰

Docker注册中心v2是完全重写的。注册中心v2一发布,注册中心v1被停用了。
就为了让Docker可以正常运行,我们不得不再次安装新的版本。它们改变了配置、URL、路径和端点。

迁移到注册中心v2的过程并非很顺畅。我们不得不修复安装的系统、构建的版本和部署脚本。

汲取的教训:别信任任何Docker工具或API。它们被不断丢弃和淘汰。

注册中心v2的目的之一就是,带来更好的API。它在此(https://docs.docker.com/registry/spec/api/)有记载,我们不记得9个月前有这个说明文档。

Docker注册中心问题:无法清理镜像

不可能从Docker注册中心清理镜像。也没有垃圾回收机制,文档提到了一个,但并不真实。(镜像确实有压缩和重复数据删除,但那是另一回事)。

注册中心一直在变得庞大。我们的注册中心每周就会增大50GB。

我们不可能有存储量无限制的服务器。我们的注册中心有几次用完了空间,导致构建管道一团糟,然后我们把镜像存储到了S3。

汲取的教训:使用S3来存储镜像(S3在默认情况下得到支持)。

我们总共执行了3次手动清理。无论在什么情况下,我们都要停止注册中心,删除所有存储的内容,开启一个新的注册中心容器(幸好,我们可以借助自己的持续集成,重新构建最新的Docker镜像)。

汲取的教训:从Docker注册中心存储系统手动删除任何文件或文件夹会造成损坏。

时至今日,不可能从Docker注册中心删除镜像。也没有API。(v2的目的之一就是有一个更好的API。任务失败)。

Docker问题:发布周期

Docker发布周期是Docker生态系统中唯一不变的:

1.丢弃任何存在的东西

2.制作新的内容并发布

3.忽视现有的用户和向后兼容性

发布周期适用但并不局限于:docker版本、功能特性、文件系统、docker注册中心和所有API……

从Docker的过往历史来判断,我们可以大致推测:Docker开发的任何东西其半存留期只有大概1年,这意味着现在存在的一半东西一年后被丢弃和淘汰。通常会有替代版本,但是与它所取代的对象并不完全兼容,是否可以在同一生态系统上运行是个未知数。

“我们开发软件不是为了供人们使用,而是由于我们喜欢开发新的东西。”— 未来的Docker墓志铭

目前Docker在我们企业组织的现状

方兴未艾的Web服务和微服务

Docker最初是因Web应用程序而出现的。那时候,它是开发人员包装和部署应用程序的一种简易方法。他们试过Docker后迅速采用了它。后来,Docker扩散到了一些微服务,我们开始采用微服务架构。

Web应用程序和微服务很相似。它们是无状态应用程序,可以不假思索地启动、停止、终止和重启。所有棘手的方面交给了外部系统(数据库和后端系统)。

Docker的采用始于次要的新服务。最初,一切在开发、测试和生产环境下运行顺畅。由于更多的Web服务和Web应用程序采用容器化,内核崩溃慢慢开始出现。到了后来,稳定性问题变得更突出、影响更大。

一年内发布了几个补丁和回归。一段时间来,我们在Docker方面一直在想变通方法。它令人痛苦,但似乎没有打消人们采用Docker的热情。在企业组织内部,支持和需求仍呈增长势头。

注意:没有一次故障曾经影响任何客户或资金。我们在遏制Docker方面相当成功。

被禁止用于核心系统

我们在运行的几个关键应用程序是用Erlang编写的,由“核心”团队的几个人来管理。

他们试图在Docker中运行几个应用程序,但行不通。由于一些原因,Erlang应用程序和docker无法兼容。

那是很久前搞的,我们记不起所有细节了。Erlang对于系统/网络应如何运行有特定的想法,预计的负载是每秒数千个请求。 任何不稳定性或不兼容性都会导致显眼的故障。(我们现在确信,尝试过程中使用的版本存在多个重大的不稳定性问题)。

尝试发出了危险信号。Docker没有准备好用于任何关键系统。这是个正确的信号。后来的崩溃和问题证实了这点。

我们只用Erlang来编写关键应用程序。比如说,核心团队的人员负责一套本月处理了96544800美元的交易的支付系统。该系统包括几个应用程序和数据库,它们都归核心团队负责。

Docker是危险的累赘,可能会让数百万美元岌岌可危。它被禁止用于所有核心系统。

被禁止用于数据库

Docker旨在是无状态的。容器没有永久性磁盘存储,发生的一切都是短暂的,容器停止后,不复存在。容器并不是用来存储数据。实际上,设计它们的初衷是不存储数据。谁要试图违背这个理念,注定会招惹灾难。

此外,Docker通过抽象机制将进程和文件锁起来,它们接触不到,就好像不存在似的。如果出了什么岔子,它阻止执行各种恢复。

长话短说。按照设计,Docker不可在生产环境下运行数据库。

情况比这还要糟糕。还记得Docker存在的内核崩溃这个老大难吗?

崩溃会摧毁数据库,并影响与之连接的所有系统。它可能是个异常错误,在频繁使用情况下更常被触发。数据库是终极的输入/输出密集型负载,保证会引发内核崩溃。另外,另一个错误会破坏docker挂载(毁灭所有数据),可能还会破坏系统的文件系统(如果在同一个磁盘上)。

恶梦般的场景:主机崩溃,磁盘受到损坏,在此过程中摧毁了主机系统和所有数据。

结论:Docker不可在生产环境下运行任何数据库,万万不行。

偶尔会有人过来问:“为何我们不把这些数据库放入到docker中?”我们会告诉经历的几个难忘的可怕故事,到目前为止,没人再问第二遍。

个人观点

Docker日益受到追捧,得到了一些狂热的支持。Docker炒作不再是一种技术累赘,它还演变成了一个社会问题。

眼下,其外围受到了控制,局限于一些无状态Web应用程序和微服务。如果是不重要的东西,可以容器化,哪怕每天崩溃一次,我也不在乎。

到目前为止,想使用docker用于重要东西的所有人在快速讨论后打消了念头。我最担心的是,有一天,docker发烧友听不进道理,一意孤行。

恶梦般的场景:未来的会计集群改造,目前保管2300万美元的客户资金。已经有个人认真地问架构师“为什么你不把这些数据库放入到docker?”架构师脸上是什么样的神情难以言表。

我的责任就是保护客户及其钱财。

让Docker在生产环境下存活下来

密切关注版本和变更日志

密切跟踪内核、操作系统、发行版、Docker以及其他一切的版本和变更日志。寻找错误,寄希望补丁,认真阅读一切。
ansible ‘*’ -m shell -a “uname -a”

任由docker崩溃

任由docker崩溃。这不言而喻。
我们偶尔看一下哪些服务器已完蛋,强行重启它们。

每个服务都有3个实例

高可用性需要每个服务至少有2个实例,那样实例故障后才会存活下来。

使用docker用于任何不太重要的系统时,我们应该有3个实例。Docker一直在死亡,我们需要误差幅度,以支持同一服务的连续2次崩溃。

大多数时候,崩溃的是持续集成或测试实例。(它们运行大量密集的测试,问题来得尤其突出)。我们有许多这种实例。有时候,一个下午会出现3个实例连续崩溃的情况。

别将数据放入到Docker

存储数据的服务无法容器化。

Docker旨在不存储数据。别违反这一点,那样只会招惹灾难。

之外,目前有些问题在终止服务台,可能摧毁数据,所以这确实是一大禁忌。

别在Docker里面运行任何重要的东西

Docker会崩溃。Docker会摧毁它触及的一切内容。

它局限于可能崩溃,但不引起停运的应用程序。这意味着大多数无状态应用程序,它们完全可以在其他某个地方重启。

把docker放入到自动扩展组

Docker应用程序应该在自动扩展组中运行。(注意:我们还没有完全到那一步)。

无论实例何时崩溃,它都在5分钟内自动更换。不需要手动操作。自我愈合。

未来路线图

Docker

Docker方面不可能克服的挑战就是,提出一种切实可行的组合:内核+发行版+ docker版本+ 文件系统。

眼下,我们并不知道任何运行稳定的组合。我们在积极寻找这样一种组合,不断测试新的系统和补丁。

目的:找到一种可运行docker的稳定的生态系统。

开发一款优秀、稳定的软件需要5年,而Docker v1.0问世才28个月,它没有时间来成熟。

硬件更新周期是3年,发行版的发布周期是18-36个月。Docker在之前的周期并不存在,所以系统无法考虑与它的兼容性。导致情形更糟糕的是,它依赖许多高级的系统内部组件,它们比较新,也没有时间来成熟,无法进入到发行版。

5年后它可能是一款还不错的软件,敬请拭目以待。

目的:等待情况有所改善。在此期间尽量不要破产。

使用自动扩展组

Docker局限于无状态应用程序。如果某个应用程序可以包装成Docker镜像,它可以包装成AMI。如果某个应用程序可以在Docker中运行,它可以在自动扩展组中运行。

大多数人忽视了,可是Docker在AWS上毫无用处,它实际上后退了一步。

首先,容器的意义在于通过在同一个大大的主机上运行许多容器,以此节省资源(不妨暂且忽略当前的docker漏洞,这个漏洞导致主机及在其上面运行的所有容器崩溃,迫使我们只好每个主机运行1个容器,以确保可靠性)。

因此,容器在云提供商上毫无用处。始终有一个大小合适的实例。就为应用程序创建一个拥有适当内存/处理器的容器(AWS上的最基本实例是t2.nano,512MB和处理器的5%资源,每月仅需5美元)。

其次,容器周围有一个完整的编排系统,可以自动管理创建/停止/开启/滚动更新/金丝雀版本发布/蓝屏部署,容器才会显现其最大好处。目前不存在可以做到这一点的编排系统。(这时候,Nomad/Mesos/Kubernetes最终会应运而生,但它们的现状不够好)。

AWS有自动扩展组来管理实例的编排和生命周期。这款工具与Docker生态系统完全毫无关系,但是它可以获得更好的结果,没有任何缺点和混乱。

为每个服务创建一个自动扩展组,并为每个构建AMI(提醒:使用Packer来构建AMI)。如果在AWS上进行操作,人们已经熟悉管理AMI和实例,没有太多的东西要学习,也没有陷阱。因而获得的部署是完全自动化。采用自动扩展组的安装系统比Docker生态系统领先3年。

目的:将docker服务放入到自动扩展组,以便能够自动处理故障。

CoreOS

补充说明:Docker和CoreOS由不同的公司开发。

如果只给Docker一次机会,它需要和依赖许多新的高级系统内部组件。一款典型的发行版无法在主要版本之外升级系统内部组件,即便它想这么做。

Docker有必要拥有一款特殊用途的操作系统,并且有适当的更新周期。这也许是拥有能够运行Docker的内核和操作系统这对组合的唯一途径。

目的:试用CoreOS生态系统,评估稳定性。

总的来说,把用来运行容器的服务器(基于CoreOS)与正常服务器(基于Debian)分离开来是切实可行的。容器没必要了解(或在乎)它们在运行什么操作系统。

麻烦在于管理新的操作系统家族(安装、配置、升级、用户帐户、日志和监控)。不知道我们会怎么做,或者这可能需要多大的工作量。

目的:随意部署CoreOS。

Kubernetes

未来的重大突破之一就是,能够管理从它们最终运行的机器抽象出来的大批容器,能够自动启动/停止/滚动更新和调整容量。

Docker的问题在于,它并不处理这任何任务。它就是一个哑的容器系统。它有容器的缺点,却没有好处。

目前市面上没有一种优秀的、久经考验的、生产环境就绪的编排系统。

  • Mesos并不是面向Docker的
  • Docker Swarm不可靠
  • Nomad只有最基本的功能特性
  • Kubernetes是新的试验性项目

Kubernetes是唯一旨在解决容器方面棘手问题的项目。它得到了其他任何项目所没有的资源的支持,即谷歌在大规模运行容器方面有着丰富的经验,谷歌拥有大量的资源可供支配,而且知道如何编写切实可行的软件。

眼下,Kubernetes是一个年轻的试验性项目,缺少说明文档。进入壁垒令人痛苦,远谈不上尽善尽美。不过,它取得了一定的成效,已经造福于一小批人。
从长远来看,Kubernetes是未来所在。它是重大突破(或者准确地说,它是容器在基础设施管理领域掀起重大革命所需要的最后一块拼图)。

问题不是是否采用Kubernetes,问题是何时采用它?

目的:请密切关注Kubernetes。

注意:Kubernetes需要docker才能运行。它会受到所有docker问题的影响(比如说,别在除CoreOS之外的任何系统上试用Kubernetes)。

谷歌云:谷歌容器引擎

正如前面所说,没有已知稳定的操作系统+ 内核+ 发行版+ docker版本这对组合,因而没有稳定的生态系统可以用来运行Kubernetes。这是个问题。

可能有一种变通方法:谷歌容器引擎(Google Container Engine,https://cloud.google.com/container-engine/)。它是一种托管的Kubernetes(和Docker)即服务,是谷歌云的一部分。

谷歌得解决Docker问题来提供目前提供的服务,别无选择。顺便说一下,也许只有谷歌能够为Docker找到稳定的生态系统,修复错误,并将这作为一种云托管服务来销售。我们可能会有一个共同的目的。

谷歌已经在提供这项服务,所以这意味着它已经在解决Docker方面的问题。因此,要让容器在生产环境下切实运行起来,最简单的办法可能就是使用谷歌容器引擎。

目的:改用谷歌云,从未被AWS锁定的子公司开始入手。忽视路线图的其余部分,因为那些无关紧要。

谷歌容器引擎:这是证明谷歌云是未来、AWS过时的另一个原因(除此之外,平均而言,实例要便宜33%,网络速度和IOPS要高出3倍。)

容器云 – 为电商双十一大战保驾护航

刀客info阅读(215)评论(0)

又到一年双十一,一场由电商网站主导,社会全民参与的购物狂欢盛宴再一次准时上演。事实上,双十一,不仅是剁手党们热热闹闹的「 狂欢节 」,同时也是电商网站们悄无声息的「 技术大考 」。不得不提的是,剁手党们年年狂欢,电商网站们却有着一段不堪回首的过去。

往事不要再提:

曾几何时,在剁手党们还没成长为秒杀老司机,还没有看破电商那些“先涨价再降价”的猫腻,对大促还很有新鲜劲的时候,各大电商摩拳擦掌几个月,呈现出来的大促结果却是让人大跌眼镜的宕机、宕机、宕机……

犹记得,尼玛凌晨就开始守在电脑前准备秒杀,却永远是登录失败状态。现在看来都不可能发生的“事故”,比如网站瘫痪、服务器断电、运营商链路挂掉、CDN故障、400电话不通等几乎都发生了,捂脸……

如今成功蜕变:

不过如今,当剁手党们对电商大促习以为常,习惯“6·18”、“11·11”、“12·12”等电商造节术,开始不过“光棍节”,只过双十一时,电商的技术也早已不可同日而语,神马百万级流量峰值都是浮云,电商的心态就是一个爽:「 任尔东西南北风,吾自岿然不动!」得意……

看到这里,大家肯定会好奇,电商的技术啥时候变得这么厉害了!大促不宕机,能抵挡住数倍于日常的流量洪峰的法宝究竟是什么呢?

法宝就是容器技术!容器技术!容器技术!(重要的事情说三遍!)

接下来看看各大电商巨头在容器技术应用方面的现状是怎么样的(在这么好的广告位给几位打广告,小编的内心其实是拒绝的):

京东对容器技术的使用和推崇在圈内是可圈可点的。据公开资料显示,京东拥有目前世界上 「 规模最大 」的Docker集群,今年或将达到20万个。基于Docker和OpenStack的京东弹性云,支撑了京东数次6.18和双十一大促的考验,以及数千亿的交易业务。目前京东所有的应用已经100%通过容器技术来发布。

唯品会的私有容器云管理平台,主要用于提高资源利用率,快速/自动部署多数据中心等。

唯品会数据库备份恢复容器化项目实践经验总结

蘑菇街基于Docker的私有云在2014年圣诞期间正式上线,目前已经历数次双十一、双十二的实际检验。Docker的稳定性和容灾能力是其重点关注方向。此外,它还自研了基于Docker的PaaS层编排调度,Jenkins持续集成组件等。

铺垫了这么多,终于可以说说正题了:既然容器技术这么靠谱牛掰,电商巨头纷纷用它来对抗大促的流量洪峰,那么容器技术究竟是如何助力电商大促的?

先来看看大促时面临的具体挑战有哪些:

1. 流量短时间内达到峰值,系统面临宕机危险。电商大促时流量会在短时间内迅速攀升,达到平常的几倍甚至几十倍,一方面对服务器数量和网络带宽资源提出高要求,另一方面,面对瞬间的高并发,机器负载高,系统不稳定性增强,面临宕机危险,将会极大影响用户体验。

2. 计算资源需求突增,技术上如何做到弹性自如,也是一个挑战。电商对于系统的稳定性和性能要求极高,尤其是在大促时如何扛住瞬间急剧增长的流量压力,不会出现服务不可用状态,同时在大促之外的其他时间还能保证资源不被浪费,这对技术的弹性收缩提出挑战。

3. 紧急故障处理能力。电商大促中由于流量的急剧暴涨,如果系统故障、服务不可用,用户在页面浏览、点击、抢购、秒杀、支付等环节都会因此受到影响,如何迅速处理紧急发生的各种问题,考验着电商技术团队的应变能力。

一句话,电商大促对系统的最高要求就是:承担得了100%的业务和流量、稳定性超强、具备容灾能力、可以紧急处理各种故障。

重点来了,基于Docker的容器云在电商大促的系统挑战面前发挥了什么作用呢?

相比于传统虚拟机,容器技术的优势是:

  • 启动快,虚拟机一般在分钟级别,而容器则是秒级,甚至毫秒级;
  • 体量小,虚拟机一般几个G,而容器只需要几百M,甚至几百K,而且可以分层共享;
  • 迁移简单,虚拟机需要提供额外的工具来在不同平台迁移,而容器可以在不同Linux平台之间轻松迁移,镜像的标准化让容器技术更加简单易用;
  • 资源利用率高,一个虚拟机上,可以运行多个容器,相互之间资源共享,提高了资源利用率。

基于此,容器云在电商大促中可以实现以下功能:

— 1 —
高弹性计算

① 自动伸缩,快速扩容,让系统从容应对突发流量。基于Docker的容器云平台,集群中节点和运行中Pod的数量能够动态调整负载,以适应终端用户的需求,非常适合商品秒杀、商品详情页的需求,可大大减轻运维压力,实现自动伸缩;

② 流量自动调度。容器云平台的服务负载可通过算法实时调度到性能最高的容器实例,缓解瞬时流量压力;

③ 节点横向扩展。根据流量变化,当容器实例启动数量快速增长时,系统可自动扩展底层备用资源池;

— 2 —
多平台混合云

① 接入多家主流IaaS平台API,自动组成多云平台,防止某家资源售罄导致的服务有损;

② 支持私有物理机IDC,实现物理机&线上虚拟机组成的协同资源池;

③ 对网络的再封装,实现网络层面的一致性,多平台混合云架构一并支持业务高可用,高性能;

— 3 —
自动化运维

① 自动迁移,容灾容错。容器实例始终保证冗余一定数量,资源池异常可自动迁移至有效资源,提高系统容灾容错能力;

② 解耦与隔离能力。可实现业务与底层计算平台的解耦,容器之间的隔离性也同时保证了业务服务之间的隔离;

③ 不健康节点,自动降级。底层资源池不健康,可自动踢下线,实现节点的有效性保证和资源池的健康度展示;

④ 全方位监控的能力。支持集群级别,应用级别,容器级别的多维度监控,并集成业务维度告警,系统配置好后,可以实现自动化运维。

讲到这,小编要严肃的打个广告了!以下通过一个具体实践案例,来看看时速云企业级容器云PaaS平台是如何为某垂直电商客户解决难题的。

客户痛点:

电商系统和营销系统服务组件众多,每次部署需要耗费很长时间,且容错能力比较薄弱,无法应对大规模并发访问。

时速云解决方案:

 

20161108205929

 

针对电商行业的特点,如应用架构复杂,部署时间长,业务迭代缓慢,采用时速云容器云平台,将电商应用组件容器化,进而将单体应用微服务化,再采用应用编排统一部署,使得整个电商系统的部署运行时间大大缩短,由于容器服务具有优秀的弹性伸缩能力,通过此平台显著提高了系统应对大规模并发的能力。

总结:每年双十一,最热闹的是巨头们不断刷新纪录的交易额,但热闹背后却离不开技术团队默默地支持和付出。在这场年度技术大考中,容器云正成为电商通关的最有效法宝。大促时,它是应对流量洪峰,保证系统稳定的扛把子;大促之余,它是提高生产效率、缩短审批流程、简化开发运维、降低运营成本,提高资源利用率的有效工具。如果你的业务有上述痛点,那就开始考虑搭建一个私有容器云平台吧!

基于Mesos的当当作业云Elastic Job Cloud

刀客info阅读(185)评论(0)

本文是当当网架构专家张亮在CNUTCon北京2016 全球容器技术大会上的演讲整理而成。

作业在互联网电商行业中是很常见的技术手段。当当具有成千上万的作业规模,大致分为业务类、归档类、监控类和大数据类。

当地分布式调度原方案

当当原有的作业解决方案是Elastic Job,以下称为Elastic Job 1.X。主要关注以下4个方面:

1、高可用。这里高可用指主从热备。主节点提供服务的同时从节点处于等待状态。一旦主节点失效,其中一个从节点通过选举成为主节点继续提供服务,原来的主节点再次生效后,作为从节点继续等待选举机会。

2、线性扩展。可理解为高可用的高阶功能。既然多节点参与服务提供,若从节点只负责热备,难免造成资源浪费,将主备调整为分片,则可大幅提升处理能力。中心化分布式服务基本都是提供独立的调度中心和执行节点,调度中心提供主备,执行节点可以弹性的线性扩展。Elastic Job1.X采用无中心化架构,并无调度中心,而是各个执行节点通过Zookeeper选举主节点进行分片、清理等动作,作业调度由执行节点自行触发。Elastic Job 1.X通过分片进行线性扩展,每个执行节点负责处理被分配到的分片项,应用开发者负责分片项和业务逻辑的对应关系。代码示例:

public class MyElasticJob implements SimpleJob {

@Override public void process(ShardingContext context) {
 switch (context.getShardingItem()) {
 case 0:
 // do something by sharding item 0
 break;
 case 1:
 // do something by sharding item 1
 break;
 case 2:
 // do something by sharding item 2
 break;
 // case n: ...
 }
 }}

1、容错性。主要包括节点失效重分片、失效转移、错过任务重执行以及分布式场景下的脑裂,网络抖动容错等。

2、异构语言。Elastic Job支持Java和Shell,基本能做到异构语言支持。

Elastic Job 的核心组件图如下:

 

20161103195755

 

绿色部分是Elastic Job 1.X对开发者提供的API。蓝色部分为内部实现,主要有选举模块、分片模块、调度模块、持久化模块以及分布式协调模块。持久化和协调均基于Zookeeper。

部署架构图如下:

 

20161103195808

 

Elastic Job 1.X与应用代码部署在一起,作为lib提供服务。Elastic Job 1.X和运维平台通过注册中心进行交互。

Mesos对云平台解决方案的革新

花了这些篇幅介绍背景,目的是让大家了解当当原有的分布式作业解决方案,接下来将阐述新一代的平台化作业解决方案。

随着时代发展进步,分布式操作系统、容器以及各式各样的容器编排治理方案层出不穷,站在巨人的肩膀上,可以更快速稳定的搭建云平台,基于这样的考虑,我们决定拥抱革新。我们首先将目光投在了Docker上,希望将Elastic Job容器化,然后再选择一个容器治理方案。经过调研,我们转而倾心Mesos,因为我们的目标不是容器化,而是云化,容器是实现云的一种手段,但合理的分布式编排系统更加关键。Docker本身有网络、日志采集等问题需要解决。而Mesos将Docker作为可选容器支持,为了最小化采用新技术带来的风险,我们决定将Docker容器化推迟,先将Elastic Job迁移至Mesos。这也得益于Mesos对Docker的无缝支持,以后加入对Docker的支持非常容易。

下图是Mesos的核心概念:

 

20161103195830

 

蓝色是Mesos的基础组件,由Mesos Master、Mesos Agent和运维界面/API组成。Master/Agent的形式在分布式系统中很常见,如Hadoop map-reduce的JobTracker/TaskTacker。Mesos Master节点通过Zookeeper实现高可用,用于分配资源至注册在Mesos的 Framework,Mesos Agent用于收集宿主机资源,如可用CPU、内存、甚至GPU等,并负责执行Mesos Framework分发的任务。Mesos Master与Slave间使用内部API交互,通过远程执行部署在Mesos Agent的程序无需Mesos Agent所在服务器提供免登录账号。

紫色是Mesos Framework的组成部分。Mesos只有基础组件并不能独立使用,需要注册Framework接收Mesos Master分配的资源并决定如何执行,目前常见的Marathon和Chronos都是Mesos Framework。Framework的两个重要组成是Scheduler和Executor。Scheduler和Mesos Master通过Scheduler API交互,负责将分配的资源生成任务并分发。Executor通过Executor API与Mesos Agent交互,负责执行分配的任务并回告状态。

红色是Scheduler中两个最重要的回调方法,resourceOffers和statusUpdate。

resourceOffers用于将资源转化为任务并调用Executor执行。资源分配算法,任务业务逻辑都应在此方法中实现。

statusUpdate用于处理Executor回传的状态。可通过Executor的状态传递和Scheduler的statusUpdate实现失效转等的分布式协调功能。

Executor分为两种。

 

20161103195830

 

Marathon和Chronos都使用Command Executor,这也是Mesos提供的内置的Executor,可以直接执行命令行脚本,也提供了基本的状态回传功能,对于普通应用使用Command Executor是不错的选择。

自定义Executor可提供更多灵活性。下面举几个例子,但不限于仅实现这些功能。

1、日志重定向。Command Executor的日志会输出到Mesos提供的沙箱中,通过自定义Executor可将日志重定向到其他文件,或对接其他日志收集工具。

2、多任务复用。Command Executor与任务是一对一的关系。有些初始化资源非常耗时的场景,可以复用Executor,多线程并发处理多任务。

3、执行进度报告。Command Executor仅回告状态变化,如需更加细化进度回告功能,需定制化处理。
心跳检测。可以通过Executor定时传递消息做心跳检测。
简单的介绍了Mesos,是该讨论下Mesos能带来什么好处的时候了。Mesos可作为部署平台和运行平台使用。

作为部署平台,Mesos可以做到应用分发自动化。将应用上传到网络地址(或Docker仓库),Mesos能够自动将应用分发至需要执行相关任务的Mesos Agent,省去人工部署成本。由于应用自动分发,那么CMDB将大大简化,只需要管理Zookeeper服务器即可,Mesos Master、Mesos Agent以及其他部署在Mesos内部的应用均可用Mesos界面统一管理。美中不足是Mesos目前缺乏管理数据类服务器的成功案例,数据库等部署在Mesos之外的应用仍需独立的CMDB管理。

作为运行平台,Mesos可以将资源收集至统一资源池,做到硬件资源与应用一体化,按需分配资源,自动资源回收,减少资源闲置和浪费。

应用分发、资源分配和安全管理,即可形成云平台的雏形,由于当当仅搭建私有云,安全管理暂时不是重点。

现在再分析Elastic Job 1.X的解决方案,应用分发和资源分配部分是缺失的。

基于Mesos开发作业云Elastic Job Cloud

决定基于Mesos搭建作业云,我们开始调研实现方案。首先想到自然是拥抱开源,不重复发明轮子。方案A是使用Marathon作为调度框架。

 

20161103195838

 

方案A的优点是可以实现应用分发和资源分配,并且是高可用的解决方案。

但缺点同样明显:

  1. 资源分配静态化,作业无论执行与否均需预分配资源;
  2. Executor无法复用,对于Elastic Job这种对内部状态报告有要求的框架,需要在框架中通过第三方存储汇报状态;
  3. 跨机房等定制化功能较困难;
  4. 使用繁琐,需要使用Mesos、Marathon和Elastic Job 3个管理界面。

另一种类似的方案是使用Chronos,可以做到动态资源分配,但缺点是:

  1. 不支持CRON表达式,对于原crontab或Quartz的应用迁移不友好;
  2. 不适合低延迟作业,每次启动初始化资源会消耗时间,导致作业延迟,反复初始化也容易造成资源浪费;
  3. 定制功能仍然困难。

说到这里需要抛出常驻作业和瞬时作业概念了。

常驻作业是作业一旦启动,无论运行与否均占用系统资源;瞬时作业是在作业启动时占用资源,运行完成后释放资源。

常驻作业适合初始化时间长、触发间隔短、实时性要求高的作业,要求资源配备充足。

瞬时作业适合初始化时间短、触发间隔长、允许延迟的作业,一般用于资源不太充分,或作业要求的资源多,适合资源错峰使用的场景。

由于上述缺点,我们最终选择方案B。

 

20161103195845

 

我们决定自行开发Mesos Framework,项目的名称叫做Elastic Job Cloud。优点:

  1. 包含方案A的全部优点;
  2. 资源分配静态与动态相结合,常驻与瞬时作业分离处理;
  3. Elastic Job 1.X的核心理念仍可沿用,包括分片,以及之前未提及的功能,如多种作业类型,事件统计等;
  4. 易于定制化需求开发。

Elastic Job Cloud核心组件图如下:

 

20161103195854

 

绿色的API部分变化不大;红色的内部实现部分,无论是模块本身,还是模块的内部实现均有大幅度调整。

选举模块由执行节点主节点选举变更为主Mesos Framework选举,仍然依赖Zookeeper。

Sharding模块功能未变,但从执行节点主节点分片调整为Mesos Framework集中分片。Elastic Job 1.X的分片以IP为依据,Elastic Job Cloud更改为以运行任务实例为依据。

调度引擎从去中心化执行节点调度转变为Mesos Framework的中心节点调度。

通过调度作业向任务队列中写入待执行作业。

日志输出方式变更为事件发布,可自行监听发布的事件,收集Elastic Job Cloud的运行状态,默认提供日志和数据库(推荐)两种事件收集方式。

通过Executor和Scheduler API配合进行分布式协调,替换通过Zookeeper协调的方案,有效的减少了与Zookeeper的连接数。

Elastic Job Cloud作为Mesos Framework独立部署,将作业信息存入Zookeeper。

虽然Elastic Job Cloud可以提供中心化云解决方案,但Elastic Job 1.X作为无中心化解决方案,仍适用于中小规模的分布式作业调度场景。我们并未放弃Elastic Job 1.X,将其更名为Elastic Job Lite。Elastic Job Lite和Elastic Job Cloud共同组成Elastic Job,核心组件全景图如下:

 

20161103195902

 

Elastic Job Lite和Elastic Job Cloud使用统一的Elastic Job API,开发者在开发时无需关心最终的部署方式。部署在Lite或Cloud环境无需修改业务作业代码,秩序调整配置和启动方式即可。Lite和Cloud的差别仅在于云平台需要的应用分发和资源调度一体化。

目前Elastic Job Cloud已开发完成并在公司内部试用。日前对接监控系统的万余作业,全天运行峰值百万左右。

Elastic Job Cloud的roadmap是:

  1. 公司内部大规模推广使用;
  2. Docker支持;
  3. 任务优先级、依赖以及编排的支持;
  4. 跨机房部署、物理机隔离等功能开发。

回馈开源社区

目前Elastic Job已全部开源。欢迎感兴趣的人踊跃尝试。

最后我分享下我们这4个月以来的里程碑。

 

20161103195916

Uber如何使用Mesos的?答曰:和Cassandra一起用

刀客info阅读(192)评论(0)

如果你是Uber公司,你需要存储司机和乘客APP每30秒发出的位置信息,有大量的实时数据需要实时使用,你该如何做呢?

Uber的解决方案是综合性的。他们建立了一套系统,将Cassandra跑在Mesos上面。在一个演讲中Uber的软件工程师非常好的解释了这个系统(https://www.youtube.com/watch?v=4Ap-1VT2ChU&feature=youtu.be,小数表示是非常纯正的印度英语)。

如今的开发们总是有太多艰难的决定要做。我们应该全部都投入到云吗?哪一个云?贵不贵?会不会厂商锁定?我们是否应该两条路一起来尝试然后做个混合架构?因为担心平台毛利达不到50%,我们是否应该全部自研?

Uber决定打造他们自己的系统,或者说他们打算把当下两个十分能干的开源组件结合在一起。让Cassandra和Mesos一起工作,就是Uber选择的方式。

Uber做出这个决定并不困难。他们资金充足,有着顶级的人才和资源去开发、维持以及升级这个复杂的系统。

自从Uber的目标确定为让每个人、每个地方的运输实现99.99%的可用,在扩大规模的同时想要控制开销就变得非常有意义。

用金钱来换时间通常是一笔好交易。用金钱来买技能也常常是很有必要的。考虑到Uber可靠性的目标,10000个请求只有一个允许失败,他们需要运作多个数据中心。Cassandra被证明可以处理数据中心大量的负载和工作,于是数据中心就帮Uber做了这个决定。

如果你想让运输系统可靠到达每个人每个地方,那么就需要高效地利用你的资源。这是使用数据中心操作系统例如Mesos背后的想法。通过统计相同机器上的复用服务,就可以减掉30%的机器,节省了一笔不小的费用。Mesos之所以被选中,是因为在那时它是唯一生产环境里被证实可以管理数万集群的工具,这正是Uber需要的,Uber要做的系统规模确实很大。

还有哪些更有趣的发现呢?

  • 你可以在容器里运行有状态的服务。Uber发现几乎没有任何差别,对比在裸机上跑Cassandra和在一个由Mesos管理的容器里跑Cassandra,大概仅有5-10%的差别。
  • 性能很优秀:读延迟均值:13ms;写延迟:25ms;P99s看起来也不错。
  • 他们能支持的最大集群每秒有超过一百万次的写和十万左右的读。
  • 敏捷比性能更重要。在这种架构下Uber得到的是敏捷:很轻松地就可以在集群上创建和运行工作负载。

最初

  • 静态分区机器横跨不同的服务
  • 50台机器用于API,50台用于存储,并且它们毫不重叠。

现在

  • 一切都运行在Mesos上面,包括有状态的服务如Cassandra和Kafka。
  • Mesos是数据中心操作系统,能够让你的数据中心变成一个单个的资源池。
  • 在当时Mesos是唯一可以管理数万台机器的工具,现在或许也有了其他的选择。
  • Uber 在MySQL上建立了他们自己的Sharded数据库,命名为Schenmaless。Cassandra和Schenmaless将会成为Uber的两个数据存储选择。而现有的Riak设备将会移到Cassandra上。
  • 一个单独的机器可以跑不同类型的服务。
  • 在同一机器的静态复用服务可以带来减少30%机器使用。这是一个来自Google Borg系统的实验发现。
  • 举例,一个使用了很多CPU的服务和一个使用了很多存储或者内存的服务可以很好地匹配,这两个服务可以很效率地跑在同一服务器上,机器利用率得到了提升。
  • Uber现在有20个Cassandra机器,计划将来增加到100个。
  • 敏捷性比性能更重要。你需要有能力管理这些集群并且在它们上面以一种平滑的方式进行不同的操作。
  • 为什么在一个容器里运行Cassandra而不是在整个机器上?
  • 你想要存储数据数千个千兆字节,但是你希望它能在多个机器上复制甚至跨数据中心。
  • 你同样希望在不同的集群实现资源隔离、性能隔离。
  • 很难在一个共享集群做到上述这些。举例,如果你创建了一个1000节点的Cassandra集群,它要么不能大规模,要么就会在不同集群之间有性能干扰。

生产环境

  • 在两个数据中心间(东海岸和西海岸)有大约20个的集群复制。
  • 最初有四个集群,包括中国。但是和滴滴合并后,这些集群就关闭了。
  • 在两个数据中心有大约300台机器。
  • 最大的两个集群:每秒超过一百万次读和十万次写。
  • 其中的一个集群用来存储每30秒来自司机和乘客app的位置信息。
  • 平均读延迟:13ms;平均写延迟:25ms
  •  大多数使用LOCAL_QUORUM的一致性级别(即强一致性)。

Mesos

  • Mesos从机器中抽象了CPU、内存和存储。
  • 你看到的不再是单独的机器,编程的对象是一整个资源池。
  • 线性扩展。可以跑成千上万台机器。
  • 高可用。Zookeeper被用来在可配置数量的复制中进行leader选举。
  • 容器上可以使用Docker containers或Mesos containers。
  • 可插拔的资源隔离。比如Linux可用Cgroups memory和CPU isolator。有一个Posix isolator。对于不同系统有着不同的隔离机制。
  • 二级调度。来自Mesos agent的资源被提供给不同的framework。Framework在这之上调度他们的任务。

Apache Cassandra

  • Cassandra非常适合Uber的用例。
  • 水平扩展。读和写规模随着节点增加线性扩展
  • 高度可用。容错率有着可调的一致性水平。
  • 低延迟。在同一数据中心维持毫秒级的延迟。
  • 操作简单。它是一种同构集群。没有master。集群中没有特殊节点。
  • 丰富多样的数据模型。它有column、compositekey、 counter、 secondary index等多种模型。
  • 和其他开源软件有很好的集成。Cassandra和Hadoop、Spark、Hive都有连接。

Dcos-Cassandra-Service

20161025200245

  • Uber和Mesosphere合作搭建了mesosphere/dcos-cassandra-service——一个自动化的服务可以轻松部署和管理。
  • 在最上面的是WebInterface或者ControlPlane API。你只要说明需要多少节点,需要多少CPU,指定Cassandra配置,然后提交到Control Plane API。
  • 在Uber使用部署系统,始于用来跑无状态服务的Aurora的上面,可以自启dcos-cassandra-service framework。
  • 在示例中dcos-cassandra-serviceframework有两个集群和Mesos master对话。Uber在他们的系统中使用了5个Mesos master。Zookeeper用来leader选举。
  • Zookeeper也用来存储框架元数据:哪一个任务在跑,Cassandra配置,集群健康等。
  • 在集群中Mesos agent跑在每一台机器上。Agent为Mesos master提供资源,master将它们离散地分发出去。分发可以被framework接受也可以被拒绝。多Cassandra节点也可以跑在同一机器上。
  • 使用的Mesos Container,而不是Docker。
  • 在配置中override 5个端口(storage_port,ssl_storage_port, native_transport_port, rpcs_port, jmx_port),所以多个容器可以跑在同一机器上。
  • 使用了persistent volume,所以数据被存放在沙箱目录之外。如果Cassandra挂掉,数据仍然在persistent volume,挂掉重启之后还可以提供给同一任务。
  • 动态预留被用来确保挂掉的任务重启后资源可用。
  • Cassandra服务操作
  • Cassandra有一个seed node的理念,当新节点加入集群时自启gossip process。创建一个定制的seed provider用来启动Cassandra节点,让Cassandra节点在Mesos集群可以自动地roll out。
  • Cassandra集群的节点数量可以使用一个REST请求来增加。它会启动附加节点,给它seed nodes,以及自启附加的Cassandra daemons。
  • 所有Cassandra的配置参数都可以改变。
  • 使用API,一个挂掉的节点可以被替换掉。
  • 在复制之间同步数据是需要修复的。修复的大致范围是在一个一个节点的基础上进行。它并不会影响性能。
  • 并不需要清理移走数据。如果节点被加进来,数据会移到新的节点,这时清理被用来删除被移过来的数据。
  • 多数据中心复制通过framework来配置。
  • 多数据中心支持
  • 在每个数据中心设置Mesos独立安装。
  • 在每个数据中心设置Framework的单个实例。
  • Framework互相对话,并且定期交换seed。
  • 这些都是Cassandra需要的。通过自启其他数据中心的seed,节点可以gossip拓扑结构,指出这些节点是什么。
  • 数据中心之间ping延迟是77.8ms。
  • P50的异步复制延迟:44.69ms;P95: 46.38ms; P99: 47.44 ms。
  • 调度执行
  • 调度执行被抽象成计划(plan)、阶段(phase)和区块(block)。一个调度计划有不同的阶段,一个阶段又有多个区块。
  • 第一阶段,一个调度在进行中出现reconciliation时,它会前往Mesos然后指出哪些在运行。
  • 有一个部署阶段会检查如果配置中节点的数量已经存在于集群中,有必要的话就会部署它们。
  • 一个block就相当于一个Cassandra节点规格。
  • 还有其他的阶段:备份,恢复,清除和修复,根据REST端点触及的是哪一个。
  • 集群可以每分钟一个新节点的速度来启动。
  • 每个节点启动时间希望能降到30秒。
  • 在Cassandra不能够多节点同时启动。
  • 通常给每个Mesos节点2TB的硬盘空间和128GB的内存。给每个容器分配100GB,32GB给每个Cassandra进程(数据并不完全准确)。
  • G1garbage collector被用来替代CMS,没有任何调优的情况下它有更好的延迟和性能表现。

文章来源:High Scalability  版权归原作者所有

http://highscalability.com/blog/2016/9/28/how-uber-manages-a-million-writes-per-second-using-mesos-and.html

如何向公司高管们推销容器技术

刀客info阅读(288)评论(0)

如果你是一名程序员或者管理员,你明白容器是什么,容器为什么是有价值的。但是,你怎么说服公司高管容器是值得投资的呢?本文会给你一些建议。

就像其他复杂的技术一样,对于没有IT背景的人来说,容器是难以理解的。在某种程度上,向公司决策者解释容器,是尤其困难的。例如,用非技术的方式描述容器和虚拟机的区别是很困难的。由于存在各种不同的容器技术,所以定义“容器”到底是什么,也是很困难的。

当然,帮助公司管理层理解容器的价值,这是很重要的。如果你想在你的组织里使用容器技术的话,你就需要获得他们的支持,来投资新的软件架构。

向公司高管们解释容器

你需要怎么做呢?以下是一些窍门,来向公司高管们介绍容器:

  • 强调容器是由虚拟机发展进化而来的下一代技术。当你将容器定位成虚拟机的进化版时,而不是某种完全新奇的东西,这对于高管们接收容器技术更加容易,原因是你的公司已经在使用虚拟机了。
  • 讨论“容器”,而不是Docker如果你和高管们讨论Docker而不是容器的话,他们可能担心被供应商锁定,尽管目前来说Docker是唯一可用于生产环境的应用容器平台。他们会担心,接受Docker意味着将他们的基础设施与某个特定的公司绑定。(事实上,Docker公司和Docker开源项目是有区别的,但是向不关注Docker的人们解释这一点,是有点麻烦的。)
  • 向高管们说明容器几乎可以运行在任何地方。担心平台锁定的高管们如果知道容器既可以运行在on-premises环境,也可以运行在云里,他们会非常开心的。如果你使用Docker的话,容器是可以运行在Linux或者Windows服务器上的。对于环境的不敏感性(environment-agnosticism)意味着更多的灵活性。
  • 描述容器对于下一代开发者的吸引力。如果你的组织想吸引顶尖的IT精英的话,那么就需要接受那些开发者和管理员喜欢使用的技术。容器技术就是其中一种。理解这一点的高管们会更喜欢容器的。
  • 向高管们说明容器软件是免费的。可以确定的是,迁移到容器总会带来一些成本。你需要雇佣更多的人,在容器管理和监控工具上投入更多资金。然而,底层的容器软件本身(主要是指Docker)是免费下载和使用的。高管们会喜欢这一点的,尤其是与虚拟机相比,因为企业级虚拟机是有一定成本的。

如果你方法得当的话,向高管们推销容器就很容易了,即便决策者们并不能从技术层面上了解容器。这种推销是值得的,因为容器可以大幅简化软件开发和发布流程。

原文链接:Selling the C-Suite on Containers

SOA还是微服务?

刀客info阅读(158)

在构建新的项目时应该总会考虑SOA或者微服务的方式。无论是新建还是重构。都请注意:考虑仍保持开放的选择不采取这种方法。在读完本文之后,关于是否建立多个小部件,你将会有一个更好的方法。

这篇文章是假定你有一些软件架构和服务方面的经验。我将谈一些微服务或SOA,同时在你的项目中该如何做。

是微服务?还是SOA?都用?都不用?

有人说,微服务与SOA差别很大。也有人说,微服务与SOA有相同点,但是是SOA的下一代,轻量级和less-enterprisey什么的。

 

完美构架不存在

你已经知道了没有完美的软件构架方法。Microsoavices可能不适合你的项目,甚至你的公司。什么是microsoavice呢?首先,我想说明这个两个简单的关键点:

  • 细粒度的责任
  • 内置的容错

他们是所有项目的基础,无论你的项目是大还是小。

 

细粒度的责任

Microsoavices可以是单任务或单个域。下面是一个单任务microsoavice的一个例子。

所有的项目不仅包括业务逻辑和应用领域。总有一些会涉及普通工具。我曾经在一个需要将RTF文件转换为HTML的项目。我们使用了一个库,这是很容易的。另一方面,在更新库时要求我们重新部署应用程序的所有实例。部署是自动化的,同时我们不需要发送新版本给客户,但是对于只有三个人的团队维护几十个实例是要花点时间的。

将相同库封装到一个独立的应用中然后去监听所有的HTTP请求,把它变成一个microsoavice是必要的。总之,从那天起,更新该库只是一个再部署一个单独的组件的事(只要API保持稳定)。

除了单任务microsoavices,还有足够多的用例覆盖应用领域,而不只是单一任务的。拿一个购物车的例子来说。

  • 添加商品到购物车
  • 删除商品
  • 更改商品数量

没有人为这些任务创建单独的服务认真考虑过,这就是为什么它是细粒度的。

 

内置容错

进程内的方法调用,与外部组件间的调用替换。最大的区别在于,外部调用更容易失败。它需要关注,但适当地考虑了它使整个系统更加稳定和容错设计。

容错真的是一个核心问题。早期把它弄对是microsoavices成功的关键。

 

问题

构建,部署和维护许多小的,独立的组件组成的系统也带来了许多的问题。你不仅要面对容错的问题,还包括这些问题:

  • 配置(我在哪里实现这一服务?)
  • 监控(提供哪些服务?)
  • 部署(多少实例吗?在哪些主机上运行它们)
  • 测试(在服务呼叫失败的情况下怎么办?)
  • 等等问题

测试和部署应该考虑到持续集成和部署工具可用。中央microsoavice环境的配置可能是一些可以通过使用一些ESB-like工具解决。

似乎有一切的解决方案,你只是不太满意。老实说,我认为我们没有完全到那一步,当涉及到的工具。将来会带来很多很好的工具,使构建,部署和维护microsoavices容易得多。

 

心态

从我自己的经验来看,我可以说microsoavice不只是关乎技术问题,这真的是还有一些关于心态问题。

如果你担心因为没有单一故障的服务增加的失败的概率,那么你可能需要重新考虑一下了。如果你看到那些小的组件帮助你降低失败的机率,你可能就能很快解决。

不要忘了你是一个开发人员。确保他们用mircosoavices的思想解决问题。我将在以后的工作中,microsoavices如何改变和提高开发人员的工作。

 

我的经验

我做软件开发近十年了。那段时间我的工作是不同类型的项目。我做了大约90%的网络用的东西Java和JavaScript,以及一些C#.NET,Visual Basic中(预DOTNET),Perl,PHP,Python等等,我做了几年的资深开发人员和架构师,也没遇到过一个人处理从开发到部署和维修的团队。

回想起来,我做了一些项目,一些人会从microsoavice方法中真正受益,一些人可能还没有。我做过一个必须用SOA的项目,非常的不实用,这就是为什么我想写的务实的话题,并从实用角度看待项目。

Docker管理平台 云帮解析 设计思想 | 技术架构 | 核心组件

刀客info阅读(287)评论(0)

设计思想

概述

云帮可以创建符合 12要素的云原生应用。平台使用Docker作为基本的计算单元来封装应用,利用Kubernetes对应用进行编排和容器调度。好雨将Kubernetes 与 Docker 进行了深度整合,并针对企业级服务特性自主研发了应用引擎、运维平台、持续交付引擎、自动化运维、云应用市场等功能模块,底层的分布式存储、SDN、日志收集、实时统计则采用了扩展性极强的插件式设计,增强了平台的灵活性和扩展性。

十二要素

符合12要素原则(实践方法)构建的应用可以在分布式系统中灵活的伸缩与迁移。
12要素 的贡献者参与过数以百计的应用程序的开发和部署,并通过 Heroku 平台见证了数十万应用程序的开发,运作以及扩展的过程。
云帮的设计完全兼容了12要素原则,可以实现云原生应用的高可用、弹性伸缩,灵活迁移等特性。
平台集成环境自动构建功能,不但支持Dockerfile构建应用,还提供了源代码级别的应用构建,您无需了解Docker,也不需要写Dockerfile,平台可以将您的源代码自动构建成应用并运行起来。

应用

云帮平台提到最多的名词就是 应用 ,云帮中可操作的对象也是应用,这里的应用指的是可独立提供服务的单元,请不要与手机应用,APP混淆。
应用 可以通过下列三种形式来创建/获取:

  • Git仓库中的源代码
  • Git仓库中Dockerfile文件以及相关的源代码
  • 应用市场 或 云市中通过 “一键部署” 安装

应用 可以有不同的类型,不同应用有各自的属性和行为,如:Web应用的属性包含 应用名称,默认域名,开放端口,行为包含 绑定域名、扩容节点、启动、关闭等。 MySQL应用的属性和行为都是针对MySQL服务所特有的,如备份恢复,数据库管理等等。

构建,发布与运行

20161014113818

构建阶段

构建组件处理来自git push的请求,或者用户触发构建(一键部署)操作。
如果您提交的是源代码,构建组件会进行源代码的构建操作,检查代码语言,利用语言的包管理工具安装相关环境依赖和代码库依赖。源代码构建程序还会将本次源码语言的类型、包依赖关系存入应用属性中。
如果构建模块发现您的代码中包含一个 Dockerfile 文件,会按照Docker标准的镜像构建的方式解析Dockerfile,生成Docker 镜像并推送的内部私有的镜像仓库中。

发布阶段

发布阶段由应用引擎来完成,它负责将本次构建的应用注册为一个新的版本,并将源码、Dockerfile在构建阶段识别出来的属性存储下来。为应用存储版本信息是为了上线后方便回滚,存储构建信息是为了下次构建时缓存状态。

运行阶段

运行阶段主要由 应用引擎 和 Kubernetes 来完成,首先由应用引擎初始化租户网络(如果租户网络已经存在,该步骤跳过),然后应用引擎调用Kubernetes的控制器服务部署租户应用,应用的属性信息由应用引擎设定。容器创建成功后,会将信息写入到etcd服务中,应用层负载均衡的自动发现机制感应变化后更新负载均衡节点信息。

后端服务

云帮将所有持久化存储服务如:数据库、缓存、存储、消息系统等均看成是应用的附加资源,这些服务与应用是分开的,我们不建议将应用和后端服务放到一个应用中,这样做违背了12要素的设计原则。
应用程序通过环境变量的形式与后端服务进行关联。这样做是为了将应用与后端服务解耦,无论是应用还是后端服务都可以实现独立的灵活伸缩。

技术架构

架构

云帮是按照面向服务的架构来设计的。目前大多数集群组件都是通过容器镜像的形式发布和运行的。后续我们会将所有的组件都容器化,通过Kubernetes集群保障组件的高可用。

概述

20161014113836

Kubernetes负责容器的编排和调度,它的所有行为都是由应用引擎发起的。应用引擎将容器相关的操作都进行了封装,云帮通过抽象出了一个应用的概念来屏蔽底层所有与技术(容器、调度、网络……)相关的概念。用户通过对应用进行属性和行为的设置来操作应用,通过应用与应用直接的依赖关系来进行微服务架构的设计。

技术架构

20161014113843

  • 云帮所有的对外服务都配置在负载均衡上,平台使用者、最终用户、开发者都是通过负载均衡转发到对应的应用与服务:
  • 开发者除了可以通过Web控制台管理应用,还可以通过平台API来完成所有Web控制台的操作。详情参见:云帮API手册
  • 运维人员可以在系统层面维护平台服务,也可以通过云帮的管理后台来管理计算资源,维护平台服务。

路由层

用户可以访问到的应用都是配置在路由层服务中,它主要由负载均衡组成,通过路由规则分离不同的应用与访问域名。控制层的服务根据容器的服务状态维护负载均衡中的节点。

20161014113850

控制层

控制层服务是平台最核心的功能模块,其内部包含了多个子模块:

  • 应用管理平台:通常也称之为控制台,是用户操作和管理应用的web端程序。
  • 应用中心:云帮内部的应用市场,包含了常用的应用,当然用 户也可以在云市安装更多的应用。
  • 自动构建:基于源代码和Dockerfile的自动构建模块。
  • 应用引擎:云帮核心子模块,负责将各种容器操作命令发送到后端服务,同时也将应用、容器状态保存到后端的etcd服务中。
  • Git仓库:选装模块,可以使用外部或内部的Git服务

20161014113856

计算层

计算层负责容器的运行、监控以及收集汇总容器中的日志。容器的启动与关闭由控制层发起,容器运行后会将状态注册到路由层。

20161014113902

后端服务

后端服务云帮集群的核心服务,包括Kubernetes、etcd、数据存储、日志处理、监控等。

20161014113908

部署结构

20161014113916

负载均衡

  • 负载均衡组件通常部署在计算节点上,推荐至少使用3个计算节点作为负载均衡的最小集群规模。
  • 计算节点
  • 计算节点是实际跑容器的主机,每一个团队账号(租户)的容器可以跨主机运行,团队账号中可以有多个应用,每个应用由1~n个容器组成,应用的多个容器运行在不同的主机中。
  • 管理节点
  • 云帮集群的管理服务都运行在管理节点的机器中,包括自动构建服务、容器调度、SDN网络管理、应用引擎、日志汇总与实时处理等等……
  • 分布式存储
  • 存放应用持久化数据以及自动化构建所需要的公共文件。

核心组件

自动构建组件

20161014113928

云帮支持2种类型的自动构建:

1. 源代码构建

2. Dockerfile构建

两种构建方式分别走2套构建流程,其中Dockerfile的构建流程与Docker官方构建镜像的步骤一致。这里不再赘述,咱们重点介绍基于源代码的自动构建。
源代码构建背后的理论是:代码即环境 ,什么类型的代码从根本上来说已经决定了它的环境,比如说 PHP代码,已经决定它的环境是WebServer+PHP,而不应该是Python的环境。代码即环境实际上就是在这个基础之上在代码中添加一些环境的标示而已,当源代码提交到平台后,平台的自动构建程序检测环境描述文件,然后根据需求自动构建环境。

应用引擎组建

应用引擎是好雨自主研发的分布式,多数据中心的应用管理引擎。其主要功能不仅衔接各个功能组件,而且还实现了原生高可用、性能分析、业务监控等诸多业界首创功能特性。

逻辑结构

20161014113935

SDN组件

目前我们为云帮设计了2套SDN组件,分别是基于Calico的三层网络组件和基于OVS自己研发的一套二层网络组件——GoodNet。他们所实现的目的是一样的:
1. 为了隔离租户间的网络
2. 保证同租户不同宿主机之间的网络可以互通。
不同之处在于网络组件的应用场景:
1. Calico 适用于私有云
2. Goodnet适用于公有云

概述Calico网络结构

20161014113944

GoodNet网络结构

20161014113951

同一租户下的容器通过统一的租户路由器上链到Provider Router,通过Provider Router做外网路由集中转发,并且租户路由器上是在宿主机上虚拟出一个路由器,同一租户下的容器互通通过租户路由器做gre/vxlan封装和转发。