现在,如果有程序猿说不知道Docker,这将是难以想象的。

百科是这样描述Docker的。“Docker是dotCloud开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。”而更为通俗的说法是,Docker是轻量的虚拟化技术,它拥有“统一、一次操作和随处运行”的特性。



今年是Docker三周年,Docker之父Solomon Hykesgo说出了自己的愿望,“希望Docker社区能够围绕在它的一些核心理念下不断地发展壮大,特别是我希望能够看到在社区里的每一个人更加理解彼此。这是一个非常庞大并且多元化的社区,我们有开发者、运维人员、企业、狂热爱好者、新手以及专家,我们会有不同的观点、不同的目标、不同的专业背景,这对于我们来说实际上是一件非常好的事情 。和所有社区一样,你会有争执,有时候大家会有强烈的情绪因为大家都关心事情会怎么样发展。我的愿望是这些不同的观点最后能够让我们互相学习,每一个人都能在这个社区里面成长。”

我们来看一组数据。仅2015年,Docker的贡献者增长了183%;GitHub上关于Docker的项目增长了515%;采用Docker构建的应用程序增长了934%;根据DockerHub上镜像下载量统计,容器的下载量增加了18082%!

这里放一张老图,让乃们随意感受一下。

虚拟化技术的“进化史”

从虚拟化技术的演进来看,许多人将Dcoker视为第三代虚拟化解决方案,但这一观点并不是所有人都赞同。从最早的硬件虚拟化,只有特定厂商,特殊的硬件支持的操作系统多租户访问,到运行在通用硬件上的Hypervisor技术,再到当前通过内核特性,以进程方式运行多个容器。

无论技术如何“进化”,都脱离不开性能、成本和隔离等几个关键词。

1990年,应用程序服务提供者服务(application service provider)模式出现。它的运作模式与租用大型主机相同,但租用的资源是在软件层面,包括操作系统以及运行其中的应用程序,例如ERP系统或是CRM等应用。系统可能会运行在数台不同的机器上,或是在相同的主机但共享不同的数据库,以区分并计算客户的资源使用量,藉以作为计费的标准,而此技术也有效地缩减了供应商的实体机器成本。

十年之后,也就是2000年,Hypervisor开始崭露头角。Hypervisor可叫做VMM(virtual machine monitor)即虚拟机监视器。 一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。Hypervisors是一种在虚拟环境中的“元”操作系统,它可以访问服务器上包括磁盘和内存在内的所有物理设备。Hypervisors不但协调着这些硬件资源的访问,也同时在各个虚拟机之间施加防护。当服务器启动并执行Hypervisor时,它会加载所有虚拟机客户端的操作系统同时会分配给每一台虚拟机适量的内存、CPU、网络和磁盘。

2010年,应用虚拟化进入人们视野,利用Linux Kernel中的资源分离机制,Cgroups,Namespaces,来建立独立的软件容器(Containers)。这可以在单一Linux实体下运作,避免启动一个虚拟机造成的额外负担。Kernel对命名空间的支援完全隔离了工作环境中应用程序的视野,包括进程树、网络、用户ID与挂载档案系统,而Kernel的Cgroups提供资源隔离,包括CPU、内存、block I/O与网络。从0.9版本起,Docker由Libvirt的LXC与Systemd nspawn提供支持,改为开始采用Libcontainer库直接使用由Kernel提供的虚拟化设施。

Docker与虚拟机的差异

左图虚拟机的Guest OS层和Hypervisor层在docker中被Docker Engine层所替代。虚拟机的Guest OS即为虚拟机安装的操作系统,它是一个完整操作系统内核;虚拟机的Hypervisor层可以简单理解为一个硬件虚拟化平台,它在Host OS是以内核态的驱动存在的。 虚拟机实现资源隔离的方法是利用独立的OS,并利用Hypervisor虚拟化CPU、内存、IO设备等实现的。

对比虚拟机实现资源和环境隔离的方案,Docker就显得轻量很多,只是对已有技术的封装,Docker利用的是目前Linux Kernel本身支持的方式实现资源和环境隔离。简单的说,Docker利用Namespaces实现系统环境的隔离,利用Cgroups实现资源限制,利用镜像实现根目录环境的隔离。

计算效率上,Docker有着比虚拟机更少的抽象层。由于不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上Docker将会有明显优势(最少提高10%,IBM的文章说由于Hypervisor对CPU指令集、NUMA支持的不完整性,浮点运算会提高50%,个人感觉也没那么多)。在IO设备虚拟化上,Docker的镜像管理有多种方案,比如利用Aufs文件系统或者DeviceMapper实现文件管理。

启动效率上,由于不需要Guest OS,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统内核。我们知道,引导、加载操作系统内核是一个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级的。而Docker由于直接利用宿主机的操作系统,省略了这个过程,因此新建一个Docker容器只需要几秒钟。快速启动、低系统资源消耗的优点使Docker在弹性云平台和自动化运维系统方面有着很好的应用前景。

交付与部署上,Docker做到一次创建或配置,可以在任意地方运行,大量地节约开发、测试、依赖部署等的时间。

相较于虚拟机,Docker也有一些“缺憾”。第一个是资源隔离方面,Docker利用Cgroups实现资源限制,只能限制资源消耗的最大值,而不能完全隔绝其它程序占用自己的资源。第二个是安全性方面,包括鉴权管控、fork炸弹防范等等Docker还是有一些短板,网络资源管理相对简单。另外,Docker对宿主机OS的兼容性也是短板,毕竟现在企业级部署还处在Redhat 5时代。

Docker的工作原理

典型的Linux文件系统由bootfs和rootfs两部分组成。bootfs(boot file system)主要包含Bootloader和Kernel,Bootloader主要是引导加载Kernel,当Kernel被加载到内存中后bootfs就被umount了。rootfs (root file system) 包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。

传统的Linux加载bootfs时会先将rootfs设为read-only,然后在系统自检之后将rootfs从read-only改为read-write,然后就可以在rootfs上进行写和读的操作了。

但Docker的镜像却不是这样,它在bootfs自检完毕之后并不会把rootfs的read-only改为read-write。而是利用union mount(UnionFS的一种挂载机制)将一个或多个read-only的rootfs加载到之前的read-only的rootfs层之上。在加载了这么多层的rootfs之后,仍然让它看起来像是一个文件系统,在Docker的体系里把union mount的这些read-only的rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是read-only的,此时还不能对其进行操作。当创建一个容器,也就是将Docker镜像进行实例化时,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs。

仓库是一个存储容器镜像的地方,包括搜索、下载、上传三个功能。

Docker Engine作为容器中的主体部分,首先提供Server的功能使其可以接受Docker Client的请求,而后Engine执行Docker内部的一系列工作,每一项工作都以一个Job的形式存在。Job运行过程中,当需要容器镜像时,则从Docker Hub中下载镜像,并通过镜像管理驱动GraphDriver将下载的镜像以Graph的形式存储。当需要为Docker创建网络环境时,通过网络管理驱动NetworkDriver创建并配置Docker容器网络环境;当需要限制Docker容器运行资源或执行用户指令等操作时,则通过ExecDriver来完成。

而NetworkDriver以及ExecDriver都是通过Libcontainer来实现具体的对容器进行的操作。Libcontainer是一个独立的容器管理包,Docker刚发布的时候,它是一款基于LXC的开源容器管理引擎。把LXC复杂的容器创建与使用方式简化为Docker自己的一套命令体系。随着Docker的不断发展,它开始将底层实现都抽象化到Libcontainer接口。这就意味着,底层容器的实现方式变成了一种可变的方案,无论是使用Namespaces、Cgroups技术,抑或是使用Systemd等其他方案,只要实现了Libcontainer定义的一组接口,Docker都可以运行。这也为Docker实现全面的跨平台带来了可能。

目前版本的Libcontainer,功能实现上涵盖了包括Namespaces使用、Cgroups管理、Rootfs的配置启动、默认的Capability权限集、以及进程运行的环境变量配置等。内核版本最好是3.8以上,这与内核对Namespaces的支持有关。目前除User Namespace没完全开放以外,其他五个Namespace都是默认开启的,通过Clone系统调用进行创建。

再谈Docker的优势与劣势

毋庸置疑,Docker当然是好处多多,否则也不可能在几年内发展得如此蓬勃。那么,Docker究竟有哪些好处呢?先归纳一下。

优势

因为不需要启动内核,所以应用扩缩容时可以秒速启动。

一键启动所有依赖服务,测试不用为搭建环境犯愁,PE也不用为建站复杂担心。

Docker命令简单、易用,社区十分活跃,Bug提交一周内就改好,且周边组件丰富。

镜像增量分发,由于采用了Union FS, 简单来说就是支持将不同的目录挂载到同一个虚拟文件系统下,并实现一种layer的概念,每次发布只传输变化的部分,节约带宽。

直接使用宿主机内核调度资源,性能损失小。

通过Docker能实现物理机的冷迁移(docker commit 、docker push)。

动态CPU、内存资源调整。

使用的人再也不用担心如何搭建服务,清理还原服务。镜像一次固化,随处使用,多个应用版本可以并存在机器上。Jenkins已经支持自动化构建镜像,解决了打包发布麻烦的问题。

测试、生产环境高度一致(数据除外)。

应用的运行环境和宿主机环境无关,完全由镜像控制,一台物理机上部署多种环境的镜像测试。

能实现秒级快速回滚。

在高性能计算的场景中,容器热迁移可以保证运行了许多天的计算结果不会丢失,只要周期性的进行检查点快照保存就可以。

劣势

缺乏成熟的开源资源调度、集群管理产品,目前的K8s自成体系,性能问题,使用成本高,Swarm作为官方推荐,功能相对单一,Mesos使用太复杂。

Engine发展速度快、平滑升级困难,一般不支持业务无感知升级。

存在隔离与安全的问题。

网络资源管控稍微差一些。

容器中加载、卸载内核模块会影响其他容器。

无法像qemu那样模拟嵌入式系统运行环境。

Docker的App Container体系对现有运维体系有着巨大的冲击,在企业级领域推进有很大的阻力(观念、实操等多个层面)。

原文地址:https://yq.aliyun.com/articles/48695

有了Docker的程序猿们就能开启“上帝视角”?的更多相关文章

  1. 程序猿必知必会Linux命令之awk

    前言 对于一名专业的程序员来说,Linux相关知识是必须要掌握的,其中对于文本的处理更是我们常见的操作,比如格式化输出我们需要的数据,这些数据可能会来源于文本文件或管道符,或者统计文本里面我们需要的数 ...

  2. 不懂CSS的后端难道就不是好程序猿?

    由于H5在移动端的发展如日中天,现在大部分公司对高级前端需求也是到处挖墙角,前端薪资也随之水涨船高,那公司没有配备专用的前端怎么办呢? 作为老板眼中的“程序猿” 前端都不会是非常无能的表现,那作为后端 ...

  3. 站在风口,你或许就是那年薪20w+的程序猿

    最近面试了一些人,也在群上跟一些群友聊起,发现现在的互联网真是热,一些工作才两三年的期望的薪资都是十几K的起,这真是让我们这些早几年就成为程序猿的情何以堪!正所谓是站在风口上,猪也能飞起来!我在这里就 ...

  4. 连载《一个程序猿的生命周期》-《发展篇》 - 3.农民与软件工程师,农业与IT业

    相关文章:随笔<一个程序猿的生命周期>- 逆潮流而动的“叛逆者”        15年前,依稀记得走出大山,进城求学的场景.尽管一路有父亲的陪伴,但是内心仍然畏惧.当父亲转身离去.准备回到 ...

  5. 连载《一个程序猿的生命周期》- 44.感谢,我从事了IT相关的工作

    感谢博客园一直以来的支持,写连载都是在这里首发,相比较CSDN和开源中国气氛要好的多. 节前,想以此篇文章结束<一个程序猿的生命周期>的<生存>篇,对过10的年做一个了断,准备 ...

  6. 回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议

    引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来.LZ自己当初面试完以后,除了记住一些聊过的知识点以外,具体的内容 ...

  7. zx一篇让Java程序猿随时可以翻看的Oracle总结

    一篇让Java程序猿随时可以翻看的Oracle总结 前言:Oracle学习也有十几天了,但是呢,接下来还要学习许多其他的东西,并不能提步不前,所以在此总结了以下Oracle中常用的命令和语句,没有语法 ...

  8. Java程序猿学习的建议(转)

    第一部分:对于尚未做过Java工作的同学,包括一些在校生以及刚准备转行Java的同学. 一.Java基础 首先去找一个Java的基础教程学一下,这里可以推荐一个地址,或者你也可以参照这个地址上去找相应 ...

  9. 三分之一的程序猿之社交类app踩过的那些坑

    三分之一的程序猿之社交类app踩过的那些坑 万众创新,全民创业.哪怕去年陌生人社交不管融资与否都倒闭了不知道多少家,但是依然有很多陌生人社交应用层出不穷的冒出来.各种脑洞大开,让人拍案叫起. 下面我们 ...

随机推荐

  1. Hadoop集群的配置的主机和IP

    集群配置如下: hadoop        192.168.80.100 hadoop1      192.168.80.101 hadoop2      192.168.80.102   (注:ha ...

  2. 从零到一创建ionic移动app:创建第一个app

    新建一个空项目,让它能够在你的虚拟机/手机上跑起来 第一步 新建工程   ionic start myApp blank 一个简单的Web应用我们已经创建完成了,接下来我们就要做一些部署到移动端之前的 ...

  3. 【JavaScript】写代码前的准备

    1.搭建开发环境,编辑器推荐HBuilder,浏览器用谷歌. 2.编写一个HelloWorld程序. HelloWorld.html <!DOCTYPE html> <html> ...

  4. Eclipse调试C++(Cocos2dx Android )

    原文链接: http://www.cnblogs.com/zouzf/p/4202537.html 先说windows下的,mac下的在最后 环境:win8.1.java 1.5.Eclipse 4. ...

  5. 华丽的使用sublime写lua~ sublime lua相关必装插件推荐~~

    缘起 lua脚本语言虽好,代码写得飞快,可是写错了调试起来却很困难,lua使用者经常容易犯得一个错误是--写错变量名了,if end 嵌套太多没匹配~,多打了一个逗号, --假设定义了一个变量 loc ...

  6. 什么是Zero-Copy?

    概述 考虑这样一种常用的情形:你需要将静态内容(类似图片.文件)展示给用户.那么这个情形就意味着你需要先将静态内容从磁盘中拷贝出来放到一个内存buf中,然后将这个buf通过socket传输给用户,进而 ...

  7. Mac OS X 下部分Android手机无法连接adb问题之解决方案

    [原文]  时至当今,Android山寨手机厂商已如此之多,能修改和个性化定制Android OS的能人已是多如牛毛,有的牛人修改Android系统只会影响所修改的点,不会影响其它,然后还有的就不多说 ...

  8. authentication token manipulation error

    用户服务器中修改密码,输入passwd命令后,报错authentication token manipulation error   发生该错误原因是: 1.分区没有空间导致. 2./etc/pass ...

  9. 介绍几个C#正则表达式工具

    这里将为大家推荐介绍几个C#正则表达式工具,这些小工具能帮助大家在.NET开发过程中起到事半功倍的效果,希望大家喜欢. 推荐三个C#正则表达式工具,理由如下 第一个C#正则表达式工具,REGEX 这个 ...

  10. scala学习手记9 - =和==

    = 赋值运算 scala的赋值运算和java的有着很大的不同.如a=b这样的赋值运算,在Java中返回值是a的值,在scala中返回的则是Unit(Unit是值类型,全局只存在唯一的值,即(),通常U ...