2017-05-19@erixhao技术极客TechBooster
很早就想写一篇关于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的Nexus和Artifactory。
高效虚拟化
这个可以算做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