Docker

很早就想写一篇关于Docker的文章了,但却久久未动笔,直到最近社区再无Docker了,在2017年4月17日的DockerCon17上,开源项目Docker变更为Moby,好吗,膜拜单车了,开始动笔....


提到容器大家会很快想到Docker, 然而容器技术并非新鲜事物,虚拟机, VM已诞生多年,而真正大面积使用,普及则是近几年借着云计算及PaaS趋势而火。

本文将主要简单入门介绍Docker为主, 适合入门级别,请Docker高手直接【点赞转发】即可。


目录

  • Docker介绍

  • Docker之父

  • 应用场景

  • 系统架构

  • 基本概念

  • 核心技术

  • DevOps流程革新

  • Kubernetes

  • 总结

1

Docker 介绍

比较喜欢Docker老版本官网的经典又直白的介绍及其Slogan: 

"Docker - Build, Ship, and Run Any App, Anywhere"


Docker是一个开源的引擎,可以为任何应用创建一个轻量级的,可以移植的,自给自足的容器。


Docker宣称,开发人员可以在笔记本上编译,测试,打包其应用及依赖到可移植容器中,然后批量发布到任意服务器,并在生产环境中部署,包括VMs, OpenStack集群等其他基础应用平台。


而容器是完全的沙箱机制,相互之间不会有任何接口,有点类似iOS中的独立Apps


2

Docker创办简史

老传统,简单介绍一下Docker的由来及主要创始人。

大概7年前,2010年,上图的年轻人28岁的Solomon Hykes加入当年炙手可热的PaaS服务队伍,在旧金山成立主攻PaaS的公司,起名dotCloud。PaaS主要定位为为软件开发提供相关的配套设施,包括语言环境,运行环境,存储等基础服务,其中涉及多种框架,语言,如PHP, MySQL, Node.js, MongoDB等等,PaaS通常提供构建服务SDK,并实现云端自动部署与测试。


当dotCloud把基于Linux Container(LXC),用Go开发的的PaaS平台做到极致的时候,理论上dotCloud已经摆脱环境限制,善于洞察的Solomon发现其基于LXC的技术具有快速,高效协作开发与部署的捷径,在当时PaaS激烈竞争环境下,dotCloud为了苟且偷生,不得已决定开源核心引擎(Apache2.0协议),不料柳暗花明,激起千层浪, 而其公开的核心引擎,名字叫Docker


dotCloud看到社区及众多PaaS大佬(Amazon, Google, IBM, MS, RedHat, VMware)对Docker的追捧及认可,顺势而为,直接于2013年公司更名为Docker发布Docker 0.1版本,并于2014年把docCloud的PaaS服务平台出售,至此拉开了基于云计算平台的发布产品变革序幕。

Docker除了本身技术的创新之处,其实在推广运营上也做了很多文章,依托于GitHub, 大力推广社区文化,Meetup,

看一张早期2014年的GitHub的统计数据吧:

在2014年发布1.0版本时,通过其用心经营社区,其15个多月期间已经超过460位贡献者参与,可见开源社区,GitHub的威力,以及幕后的广告运营能力。

再来看一下至今的Pull Chart数据吧:

数据在说话,Docker的成功起源于开源,发展于社区。

3

Docker的应用场景

云计算时代的配置管理

云计算时代的到来,极大程度上整合了硬件网络资源,开发于云端,如成功模版AWS,然而其相应大规模,分布式软件配置及管理则带来相当的复杂度,Docer则借鉴传统的虚拟及镜像机制,提供artifact集装箱能力,从而助力云计算,尤其是类似于提供了Web, Hadoop集群,消息队列等,顺应潮流。


镜像装箱机制

Docker的镜像也并非新物,类似一个只读模版的文件结构,可以自定义及扩展,用来创建Docker容器。

Docker提供的镜像机制从另一个从层面,抽象统一了软件系统部署包标准,如本来各操作系统如Ubutu的deb,  RedHat的RPM, 语言类的Java的JAR, WAR, 依赖管理,打包部署皆不同, Docker则敏锐嗅到其痛点及商业价值,推出Docker镜像及仓库,标准化从应用源码打包,分发,制品库,部署等通用流程与机制,其实类似Java的NexusArtifactory

高效虚拟化

这个可以算做Docker的杀手锏。Docker借助LXC并进行革新提供了高效运行环境,而非类似VM的虚拟OS,GuestOS的弊端在于看起来够虚拟,隔离,然而使用起来又浪费资源,又难于管理。


Docker则基于LXC的核心Linux Namespace,对cgroups/namespace机制及网络过封装,把隔离性,灵活性(资源分配),便携,安全性,最重要是其性能做到了极致。

一个普通PC启动一两个VM已经很吃力,而可以启动上千个Docker容器,做到在本地模拟多节点分布式环境,并且在秒级,毫秒级别,确实是秒杀VM。


当然,任何事物发展都不会尽善尽美,Docker的Daemo进程作为其运行服务,维护其生命周期,然而却饱受容器厂商的诟病,为其之后的容器调度管理大战,埋下伏笔,也为后来的K8(Kubernetes)横空出世留下足够空间。


价格优势

是的,开支绝对是云计算时代重要决策因素,比起VMWare之的价格昂贵则又是另一助力之源了。

Docer甚至做到了按需按时分配,如临晨客户访问量极奖,然而却是跑批之高峰,Docker可以做到合理巧妙资源配置。



总体而言,目前目前Docker已经逐步创立CaaS并作为标杆,当前最广应用领域为Test/QA, Web, 大数据,企业应用等基于云计算的应用。


4

系统架构

总体架构图



搞软件开发的人喜欢研究系统架构,下图为Docker的总体架构图:

总体架构为c/s架构,模块之间松耦合,包含了Client, Daemon, Registry, Graph, Driver, Libcontainer以及Docker Container。


VM



我们从与VM对比开始吧:

可以明显看出区别,Docker是在操作系统层面进行虚拟化,而传统VM则直接在硬件层面虚拟化。

VM之Hypervisor虚拟化

作为Linux的最重要创新之一,引入Hypervisor,运行其他操作系统的操作系统,它们为执行提供独立的虚拟硬件平台,同时硬件虚拟平台可以提供对底层机器的虚拟的完整访问,如下图的详细架构。


其实,在解决软件架构设计问题时,通常做法是引入一个抽象层来解决,其实这种做法是有点普世原理,同样适用于硬件封装,Hypervisor正是这样一种虚拟抽象层。

平台虚拟化的好处不言而喻,大大提升了服务器的效率,统计数据表明服务器通常只有5%的时间在全负荷工作,其他时间则处于休眠或者空闲状态,虚拟化技术可以大大提升服务器的利用率,从而间接减少服务器数量,即成本!

下图为简化的基于Linux的Hypervisor

可以看出,Hypervisor作为虚拟技术的核心,它支持给每一个虚拟机分配内存,CPU, 网络和磁盘,并加载虚拟机的客户操作系统。


当然,在获取到这么优秀功能(对硬件的虚拟化,并搭载操作系统)的代价,自然牺牲了启动速度及在资源利用率,性能的开销等。

Docker之架构

Docker则绕过虚拟化,直接复用Host主机的OS, 抽象出Docker Engine层面实现调度与隔离,大大降低其负重级别。

其实,其底层实现则借助了LXC, 管理利用了namespace做全县控制和隔离,cgroup来进行资源配置,aufs(类似git的思想,把文件系统的修改当作一次代码commit进行叠加从而节省存储)提高文件系统资源利用率。


LXC

LXC (Linux Container)容器是一种内核虚拟化技术,相比上述的Hypervisor技术则提供更轻量级的虚拟化,以隔离进程和资源,且无需提供指令解析机制及全虚拟化的复杂性,LXC或者容器将操作系统层面的资源分到孤立/隔离的组中,用来管理使用资源。


LXC为Sourceforge上的开源项目,其实现是借助Linux的内核特性,(cgroups子系统+namespace, 在OS层次上做整合为进程提供虚拟执行环境,即称之为容器,除了分配绑定cpu,内存,提供独立的namespace(网络,pid,ipc,mnt,uts)



Hypervisor v.s. VMWare v.s LXC


  • Hypervisor抽象虚拟化硬件平台

  • VMWare, XEN抽象虚拟化操作系统

  • LXC进程级别虚拟化

Docker Engine优势

可以看出借助/或者基于LXC的Docker Engine即容器的优势不言而喻:


  • 启动速度快,通常小于1秒

  • 资源利用率高,一个PC可以跑上千个容器

  • 性能开销小

  • 面向软件开发者而非硬件运维

  • 轻便,移植性高

Docker基于LXC的改进

  • 提供了简洁易用的命令行和API 

  • 使用Go语言开发,吸引开源社区关注

  • 基于联合文件系统的镜像分层技术,加上在线Docker Hub服务,容器迁移方便快捷

  • 一个容器只包含一个进程的微服务架构




5

Dockerk基本概念

镜像(Image)

Docker的镜像即一个只读的模版,用来创建真正Docker容器。有点类似Java的类定义。


镜像是一种文件结构,Dockerfile中的命令都会在文件系统中创建一个新的层次结构,镜像则构建与这些文件系统之上。

容器(Container)

容器则是镜像创建的实例,同样用Java类比的话类似Java的运行时对象Object。它可以被启动,开始,停止,删除等操作。

容器之间是相互隔离的,保证安全的平台,如上文分析的进程间隔离的,甚至可以把每个容器当作一个精简版的Linux。

仓库(Repository)

镜像的仓库,用来保存images,当我们创建了自己的image后可以用push把它上传到公有或者私有仓库,类似我们git或者svn代码仓库,这样其他开发人员或者Ops可以pull用来开发或者部署。同样,类似代码仓库,每个镜像支持tag标签。

Docker官网提供的镜像已经有超过近10万+的免费镜像,有点类似AppStore。

https://hub.docker.com

https://store.docker.com/

还有写不错的App可以直接桌面搜索, 如Kitmatic:



常用命令



6

Docker核心技术

Docker的核心技术包括了隔离性,可配额/可度量,便携性及安全性

隔离性:Linux Namespace(ns)

Docker采用上文提到的LXC即利用Kernel Namespace, 包括pid, net, ipc, mnt, uts, user等namespace将容器的进程,网络,消息,文件系统,UTS和用户空间隔离。

1)pid namespace

不同用户的进程就是通过pid隔离开的,且不同的namespace中可以有相同pid。


所有LXC进程在Docker中的父进程为Docker进程,同时允许嵌套,实现Docker in Docker。

2) net namespace

网络的隔离则通过net namespace实现,每个net namspace有独立的network device, IP, IP routing table, /proc/net目录等。


3) ipc namespace

Container中进程交互采用linux的进程间交互方法, Interprocess Communicaiton - IPC, 包括信号量,消息队列,共享内存等。

4)mnt namespace

mnt namespace允许不同namespace的进程看到的文件结构不同,即隔离文件系统。

5)uts namesapce

UTS - Unix Time-Sharing System namespace允许每个Container拥有独立的hostname和domain name,使其在网络上可以独立的节点。

6) user namespace

每个Container拥有不同user和group id,即隔离用户。

可配额度 Control Groups(cgroups)

可以对资源的配额和度量是虚拟化进程中又一核心所在。

Linux的cgroups实现了对资源配额和度量。cgroups类似文件的接口,在/cgroups目录下新建一个group,在此文件夹新建task,并将pid写入即可实现对改进程的资源控制。

groups可以限制blkio,cpu,devices,memory,net_cls, ns等9大子系统。

便携性:AUFX

AUFX(Another UnionFS),做到了支持将不同目录挂在到同一个虚拟文件系统下,AUFX支持为每一个成员目录设定权限readonly,readwrite等,同时引入分层概念,对于readonly的权限branch可以逻辑进行增量修改。

如上图,linux启动,首先将rootfs设置成readonly,之后将其切换至readwrite模式供用户使用。

Docker的初始化也是将rootfs以readonly加载,之后利用union mount将一个readwrite文件系统挂载在readonly的rootfs之上,并向上叠加,这一系列的结构构成了container运行时。

所有的修改都写入最上层的writeable层,image不保存用户状态,只是模版。

多层次之间的image具有父子依赖关系,docker会解析依赖并加载。

安全性

  • 借助linux的kernel namspace和cgroups实现

  • deamon的安全接口

  • linux本身提供的安全方案,apparmor,selinux

7

Docker的DevOps流程

在传统开发流程中引入Docker后,其整个开发的DevOps流程必然受到影响与更新。

  • Dev可能运行于Mac上的Docker,从Public或者Private Registory下载或者开发完成后提交

  • QA可能运行于基于Centos和Docker,从Registory下载image运行更新测试

  • Ops在把通过QA测试的image部署到云端,如AWS

Dev

Dev在使用docker后,通常如在mac(docker mac版本已经发布)上安装构建一个有如mysql和tomcat,java的镜像,并把你的业务app部署到其中,最后启动docker镜像进行开发。或者把数据库与tomcat,java分开为两个容器也可以。


  • 保证了线下线上环境一致

  • 开发好后直接把镜像发布到生产

  • 简化了开发环境的搭建

  • 简化了部署流程

构建容器

可以采用dockerfile来定义生成容器以及使用Fig来定义整个容器的运行框架。


Fig则可以通过fig.yml文件来定义所有的环境。

Ops -> CI/CD

Docker同样可以集成到持续部署流程,如下图采用Spring Boot, GitLab, Jenkins, Docker and Slack。

PaaS云端发布K8s

对于PaaS的云端分布式发布部署,是一个难点也是一个真正企业级的扩展。


这几年随着Cloud的发展以及PaaS的气候,已经形成比较成熟的方案,其中Google的Kubernetes和Apache的Mesos是其中的佼佼者。


8

Kubernetes

Google于10年前开始使用容器技术,并于2013年创建Kubernetes项目,创始人 Brendan Burns


K8s很多的抽象概念非常契合分布式调度系统,可以做到描述集群架构,定义服务状态,并维持,其实现了分布式集群的配置管理和维护包括动态伸缩及故障迁移。K8s可以单独开文来论述了。

  • 自动化容器的部署与复制

  • 服务与命名发现

  • 集群调度

  • 自动扩展及收缩服务器规模

  • 容器编排,负载均衡

  • 应用升级部署

  • 弹性容器及故障迁移

  • 集群监控

总结

互联网技术近几年在虚拟化技术,云计算,大数据,AI的发展下,进入高速发展时代,Docker也正是借助并助力PaaS分布式计算,Docker作为容器技术及集成设施的引领者顺应潮流也是PaaS是的极大革新!


当然Docker本身还在高速发展中,企业也许根据自身的环境考量,不要为了Docker而Docker!



公众号:技术极客TechBooster


孪生公众号:技术 + 金融 = 程序量化投资Venus


本站公众号
   欢迎关注本站公众号,获取更多程序园信息
开发小院