Dockek系列之-Docker介绍

一、Docker概览

Docker是⼀个⽤于开发、交付和运⾏应⽤的开放平台,Docker被设计⽤于更
快地交付应⽤。Docker可以将应⽤程序和基础设施层隔离,并且可以将基础
设施当作程序⼀样进⾏管理。使⽤Docker,可以更快地打包代码、测试以及
部署,并且可以减少从编写到部署运⾏代码的周期。
Docker将内核容器特性(LXC)、⼯作流和⼯具集成,以帮助管理和部署应
⽤。
在这里插入图片描述

二、什么是Docker

核⼼是,Docker了⼀种在安全隔离的容器中运⾏近乎所有应⽤的⽅式,这种
隔离性和安全性允许你在同⼀个主机上同时运⾏多个容器,⽽容器的这种轻
量级特性,⽆需消耗运⾏hpervisor所需的额外负载,意味着你可以节省更多
的硬件资源。
基于容器虚拟化的⼯具或平台可提供:

  • 将应⽤(包括⽀撑组件)放⼊Docker容器中
  • 分发和交付这些容器给团队,便于后续的开发和测试
  • 将容器部署到⽣产环境中,⽣产环境可以是本地的数据中⼼,也可以在
    云端。

⾃从上世纪 90 年代硬件虚拟化被主流的技术⼴泛普及之后,对数据中⼼⽽
⾔,发⽣的最⼤的变⾰莫过于容器和容器管理⼯具,例如:Docker。在过去
的⼀年内,Docker 技术已经逐渐⾛向成熟,并且推动了⼤型初创公司例如
Twitter 和 Airbnb 的发展,甚⾄在银⾏、连锁超市、甚⾄ NASA 的数据中⼼
都赢得了⼀席之地。当我⼏年前第⼀次直到 Docker 的时候,我还对 Docker
的未来持怀疑的态度,我认为他们是把以前的 Linux 容器的概念拿出来包装
了⼀番推向市场。但是使⽤ Docker 成功进⾏了⼏个项⽬ 例如 Spantree 之
后,我改变了我的看法:Docker 帮助我们节省了⼤量的时间和经历,并且已
经成为我们技术团队中不可或缺的⼯具。 GitHub 上⾯每天都会催⽣出各式
各样的⼯具、形态各异的语⾔和千奇百怪的概念。如果你和我⼀样,没有时
间去把他们全部都测试⼀遍,甚⾄没有时间去亲⾃测试 Docker,那么你可以
看⼀下我的这篇⽂章:我将会⽤我们在 Docker 中总结的经验来告诉你什么
是 Docker、为什么 Docker 会这么⽕。

2.1.Docker 是容器管理⼯具

Docker 是⼀个轻量级、便携式、与外界隔离的容
器,也是⼀个可以在容器中很⽅便地构建、传输、运⾏应⽤的引擎。和传统
的虚拟化技术不同的是,Docker 引擎并不虚拟出⼀台虚拟机,⽽是直接使⽤
宿主机的内核和硬件,直接在宿主机上运⾏容器内应⽤。也正是得益于此,
Docker 容器内运⾏的应⽤和宿主机上运⾏的应⽤性能差距⼏乎可以忽略不
计。 但是 Docker 本身并不是⼀个容器系统,⽽是⼀个基于原有的容器化⼯
具 LXC ⽤来创建虚拟环境的⼯具。类似 LXC 的⼯具已经在⽣产环境中使⽤
多年,Docker 则基于此提供了更加友好的镜像管理⼯具和部署⼯具。

2.2.Docker 不是虚拟化引擎

Docker 第⼀次发布的时候,很多⼈都拿 Docker 和
虚拟机 VMware、KVM 和 VirtualBox ⽐较。尽管从功能上看,Docker 和虚
拟化技术致⼒于解决的问题都差不多,但是 Docker 却是采取了另⼀种⾮常
不同的⽅式。虚拟机是虚拟出⼀套硬件,虚拟机的系统进⾏的磁盘操作,其
实都是在对虚拟出来的磁盘进⾏操作。当运⾏ CPU 密集型的任务时,是虚
拟机把虚拟系统⾥的 CPU 指令“翻译”成宿主机的CPU指令并进⾏执⾏。两个
磁盘层,两个处理器调度器,两个操作系统消耗的内存,所有虚拟出的这些
都会带来相当多的性能损失,⼀台虚拟机所消耗的硬件资源和对应的硬件相
当,⼀台主机上跑太多的虚拟机之后就会过载。⽽ Docker 就没有这种顾
虑。Docker 运⾏应⽤采取的是“容器”的解决⽅案:使⽤ namespace 和
CGroup 进⾏资源限制,和宿主机共享内核,不虚拟磁盘,所有的容器磁盘
操作其实都是对 /var/lib/docker/ 的操作。简⾔之,Docker 其实只是在宿主机
中运⾏了⼀个受到限制的应⽤程序。 从上⾯不难看出,容器和虚拟机的概念
并不相同,容器也并不能取代虚拟机。在容器⼒所不能及的地⽅,虚拟机可
以⼤显身⼿。例如:宿主机是 Linux,只能通过虚拟机运⾏ Windows,
Docker 便⽆法做到。再例如,宿主机是 Windows,Windows 并不能直接运
⾏ Docker,Windows上的 Docker 其实是运⾏在 VirtualBox 虚拟机⾥的。

2.3.Docker 使⽤层级的⽂件系统

前⾯提到过,Docker 和现有容器技术 LXC 等
相⽐,优势之⼀就是 Docker 提供了镜像管理。对于 Docker ⽽⾔,镜像是⼀
个静态的、只读的容器⽂件系统的快照。然⽽不仅如此,Docker 中所有的磁
盘操作都是对特定的Copy-On-Write⽂件系统进⾏的。下⾯通过⼀个例⼦解
释⼀下这个问题。 例如我们要建⽴⼀个容器运⾏ JAVA Web 应⽤,那么我
们应该使⽤⼀个已经安装了 JAVA 的镜像。在 Dockerfile(⼀个⽤于⽣成镜
像的指令⽂件)中,应该指明“基于 JAVA 镜像”,这样 Docker 就会去
Docker Hub Registry 上下载提前构建好的 JAVA 镜像。然后再 Dockerfile 中
指明下载并解压 Apache Tomcat 软件到 /opt/tomcat ⽂件夹中。这条命令并
不会对原有的 JAVA 镜像产⽣任何影响,⽽仅仅是在原有镜像上⾯添加了⼀
个改动层。当⼀个容器启动时,容器内的所有改动层都会启动,容器会从第
⼀层中运⾏ /usr/bin/java 命令,并且调⽤另外⼀层中的 /opt/tomcat/bin 命
令。实际上,Dockerfile 中每⼀条指令都会产⽣⼀个新的改动层,即便只有
⼀个⽂件被改动。如果⽤过 Git 就能更清楚地认识这⼀点,每条指令就像是
每次 commit,都会留下记录。但是对于 Docker 来说,这种⽂件系统提供了
更⼤的灵活性,也可以更⽅便地管理应⽤程序。 我们Spantree的团队有⼀个
⾃⼰维护的含有 Tomcat 的镜像。发布新版本也⾮常简单:使⽤ Dockerfile
将新版本拷⻉进镜像从⽽创建⼀个新镜像,然后给新镜像贴上版本的标签。
不同版本的镜像的不同之处仅仅是⼀个 90 MB ⼤⼩的 WAR ⽂件,他们所基
于的主镜像都是相同的。如果使⽤虚拟机去维护这些不同的版本的话,还要
消耗掉很多不同的磁盘去存储相同的系统,⽽使⽤ Docker 就只需要很⼩的
磁盘空间。即便我们同时运⾏这个镜像的很多实例,我们也只需要⼀个基础
的 JAVA / TOMCAT 镜像。

2.4.Docker 可以节约时间

很多年前我在为⼀个连锁餐厅开发软件时,仅仅是为
了描述如何搭建环境都需要写⼀个 12 ⻚的 Word ⽂档。例如本地 Oracle 数
据库,特定版本的 JAVA,以及其他七七⼋⼋的系统⼯具和共享库、软件
包。整个搭建过程浪费掉了我们团队每个⼈⼏乎⼀天的时间,如果⽤⾦钱衡
量的话,花掉了我们上万美⾦的时间成本。虽然客户已经对这种事情习以为
常,甚⾄认为这是引⼊新成员、让成员适应环境、让⾃⼰的员⼯适应我们的
软件所必须的成本,但是相⽐较起来,我们宁愿把更多的时间花在为客户构
建可以增进业务的功能上⾯。 如果当时有 Docker,那么构建环境就会像使
⽤⾃动化搭建⼯具 Puppet / Chef / Salt / Ansible ⼀样简单,我们也可以把整
个搭建时间周期从⼀天缩短为⼏分钟。但是和这些⼯具不同的地⽅在于,
Docker 可以不仅仅可以搭建整个环境,还可以将整个环境保存成磁盘⽂件,
然后复制到别的地⽅。需要从源码编译 Node.js 吗?Docker 做得到。Docker
不仅仅可以构建⼀个 Node.js 环境,还可以将整个环境做成镜像,然后保存
到任何地⽅。当然,由于 Docker 是⼀个容器,所以不⽤担⼼容器内执⾏的
东⻄会对宿主机产⽣任何的影响。 现在新加⼊我们团队的⼈只需要运⾏
docker-compose up 命令,便可以喝杯咖啡,然后开始⼯作了。

2.5.Docker 可以节省开销

当然,时间就是⾦钱。除了时间外,Docker 还可以节 省在基础设施硬件上的开销。⾼德纳和⻨肯锡的研究表明,数据中⼼的利⽤ 率在 6% - 12% 左右。不仅如此,如果采⽤虚拟机的话,你还需要被动地监 控和设置每台虚拟机的 CPU 硬盘和内存的使⽤率,因为采⽤了静态分区 (static partitioning)所以资源并不能完全被利⽤。。⽽容器可以解决这个问 题:容器可以在实例之间进⾏内存和磁盘共享。你可以在同⼀台主机上运⾏ 多个服务、可以不⽤去限制容器所消耗的资源、可以去限制资源、可以在不 需要的时候停⽌容器,也不⽤担⼼启动已经停⽌的程序时会带来过多的资源 消耗。凌晨三点的时候只有很少的⼈会去访问你的⽹站,同时你需要⽐较多 的资源执⾏夜间的批处理任务,那么可以很简单的便实现资源的交换。 虚拟 机所消耗的内存、硬盘、CPU 都是固定的,⼀般动态调整都需要重启虚拟 机。⽽⽤ Docker 的话,你可以进⾏资源限制,得益于 CGroup,可以很⽅便 动态调整资源限制,让然也可以不进⾏资源限制。Docker 容器内的应⽤对宿 主机⽽⾔只是两个隔离的应⽤程序,并不是两个虚拟机,所以宿主机也可以 ⾃⾏去分配资源。