Docker简介
Docker是DotCloud开源的、可以将任何应用包装在Linuxcontainer中运行的工具。
Docker基于Go语言开发,代码托管在Github上,目前超过10000次commit。
基于Docker的沙箱环境可以实现重型隔离,多个容器间不会互相影响;Docker可以手动化打包和布署任何应用,便捷地创建一个轻量级私有PaaS云,也可以用于搭建开发测试环境以及布署可扩充的web应用等。
DockervsVM
从右图可以看出,VM是一个运行在宿主机之上的完整的操作系统,VM运行自身操作系统会占用较多的CPU、内存、硬盘资源。
Docker不同于VM,只包含应用程序以及依赖库,基于libcontainer运行在宿主机上,并处于一个隔离的环境中,这促使Docker愈发轻量高效,启动容器只需几秒钟之内完成。
因为Docker轻量、资源占用少,致使Docker可以轻易的应用到建立标准化的应用中。但Docker目前还不够健全,例如隔离疗效不如VM,共享宿主机操作系统的一些基础库等;网路配置功能相对简单,主要以桥接方法为主;查看日志也不够便捷灵活。
另外,IBM发表了一篇关于虚拟机和Linuxcontainer性能对比的论文,论文中实际测试了虚拟机和Linuxcontainer在CPU、内存、存储IO以及网路的负载情况,结果显示Docker容器本身几乎没有哪些开支,并且使用AUFS会一定的性能耗损,不如使用DockerVolume,Docker的NAT在较高网路数据传输中会引入较大的工作负载,带来额外的开支。不过container的性能与native相差不多,各方面的性能都通常等于或则优于虚拟机。Container和虚拟机在IO密集的应用中都须要调整优化以更好的支持IO操作,二者在IO密集型的应用中都应当慎重使用。
Docker构架设计
Docker是CS构架,主要由下边三部份组成:
Dockerdaemon:运行在宿主机上,Docker守护进程,用户通过Dockerclient(Docker命令)与Dockerdaemon交互
Dockerclient:Docker命令行工具,是用户使用Docker的主要形式,Dockerclient与Dockerdaemon通讯并将结果返回给用户,Dockerclient也可以通过socket或则RESTfulapi访问远程的Dockerdaemon
Dockerhub/registry:共享和管理Docker镜像,用户可以上传或则下载里面的镜像,官方地址为,也可以搭建自己私有的Dockerregistry。
了解了Docker的组成,再来了解一下Docker的两个主要概念:
Dockerimage:镜像是只读的,镜像中包含有须要运行的文件。镜像拿来创建container,一个镜像可以运行多个container;镜像可以通过Dockerfile创建,也可以从Dockerhub/registry上下载。
Dockercontainer:容器是Docker的运行组件,启动一个镜像就是一个容器,容器是一个隔离环境,多个容器之间不会互相影响,保证容器中的程序运行在一个相对安全的环境中。
Docker网路
Docker的网路功能相对简单,没有过多复杂的配置,Docker默认使用birdge桥接方法与容器通讯,启动Docker后,宿主机上会形成docker0这样一个虚拟网路插口,docker0不是一个普通的网路插口redhat有线网络 提示设备未托管,它是一个虚拟的以太集线器,可以为绑定到docker0里面的网路插口手动转发数据包,这样可以使容器与宿主机之间相互通信。
每次Docker创建一个容器,会形成一对虚拟插口,在宿主机上执行ifconfig,会发觉多了一个类似veth****这样的网路插口,它会绑定到docker0上redhat有线网络 提示设备未托管,因为所有容器都绑定到docker0上,容器之间也就可以通讯。
在宿主机上执行ifconfig,会听到docker0这个网路插口,启动一个container,再度执行ifconfig,会有一个类似veth****的interface,每位container的缺省路由是宿主机上docker0的ip,在container中执行netstat-r可以见到如右图所示内容:
容器中的默认网段跟docker0的地址是一样的:
当容器退出以后,veth*虚拟插口也会被销毁。
除bridge形式,Docker还支持host、container、none三种网路通讯方法,使用其它通讯方法,只要在Docker启动时,指定–net参数即可,例如:
dockerrun-i-t--net=hostubuntu/bin/bash
host方法可以让容器无需创建自己的网路合同栈,而直接访问宿主机的网路插口,在容器中执行ipaddr会发觉与宿主机的网路配置是一样的,host方法让容器直接使用宿主机的网路插口,传输数据的效率会愈加高效,防止bridge方法带来的额外开支,而且这些方法也可以让容器访问宿主机的D-bus等网路服务,可能会带来意想不到的安全问题,应慎重使用host形式;container方法可以让容器共享一个早已存在容易的网路配置;none方法不会对容器的网路做任务配置,须要用户自己去订制。
Docker使用
首先要在宿主机上安装Docker,Docker安装参考官方安装文档。
Docker命令也比较类似Git,支持push以及pull操作上传以及下载Docker镜像。
1.查看当前Docker的版本
dockerversion
2.查看当前系统Docker信息
dockerinfo
3.查看宿主机上的镜像,Docker镜像保存在/var/lib/docker目录下:
dockerimages
4.从Dockerhub上下载某个镜像:
dockerpullubuntu:latest
dockerpullubuntu:latest
执行dockerpullubuntu会将Ubuntu这个库房下边的所有镜像下载到本地repository。
5.启动一个容器使用dockerrun:
dockerrun-i-tubuntu/bin/bash启动一个容器
dockerrun-i-t--rmubuntu/bin/bash--rm表示容器退出后立刻删掉该容器
dockerrun-t-i--nametest_containerubuntu/bin/bash--name指定容器的名称,否则会随机分配一个名称
dockerrun-t-i--net=hostubuntu/bin/bash--net=host容器以Host形式进行网路通讯
dockerrun-t-i-v/host:/containerubuntu/bin/bash-v绑定挂在一个Volumelinux中文乱码,在宿主机和Docker容器中共享文件或目录
6.查看当前有什么容器正在运行,使用dockerps:
7.启动或停止某个container使用dockerstart/stopcontainer_id:
8.使用dockercommit可以将container的变化作为一个新的镜像,例如:
xzs@host:~(0)$dockercommit-m="testdockercommit"50a1261f7a8bdocker_test
55831c956ebf46a1f9036504abb1b29d7e12166f18f779cccce66f5dc85de38e
xzs@host:~(0)$dockerimages|grepdocker_test
docker_testlatest5583155831cc956956ebf10secondsago290.7MB
不仅从Dockerhub上下载镜像,也可以写Dockerfile创建一个镜像,以创建一个Django程序为例,Dockerfile如下所示:
xzs@host:/tmp/docker(0)$catDockerfile
FROMubuntu:12.04
MAINTAINERYourName
RUNapt-getupdate
RUNapt-getinstall-ypython-software-propertiespython-pip
ADDmyproject/opt/code
RUNpipinstall-r/opt/code/requirement.txt
9.写完Dockerfile,在Dockerfile所在目录执行dockerbuild创建镜像:
dockerbuild-tdocker_test.
dockerrun-i-tdocker_test/bin/bash-c"cd/opt/code;pythonmanage.pyrunserver0.0.0.0:8080"
10.将制做的镜像上传到privateregistry:
dockertagtest/test
dockerpush/test
11.删掉镜像:dockerrm
经过长时间使用,主机上储存了好多已无用的镜像,想将它们删掉则用dockerrm或则dockerrmi,例如:
dockerrmcontainer_id
dockerrmiimage_id
Docker生态
随着Docker迅速火遍全球,以Docker为基础的生态系统也迅速的发展上去,从以布署和运行container为基础的CoreOS到各类各样的管理工具和PaaS软件,Docker以及生态产品都在迅猛发展,以下介绍几个代表性的软件。
首先介绍CoreOS,它的出现极大地促进了Docker技术的推广和发展,CoreOS是专门为大规模服务布署而设计的一种新的Linux发行版,通过运行轻量级的容器便捷扩充和维护大规模的服务。它具有以下特性:
CoreOS使用container管理服务(容器即服务),即以容器的角度去管理服务,服务的代码和依赖都打包到容器里,打包后的容器直接在CoreOS上运行管理。通过容器用户不再须要关注虚拟机环境等,极大地增加了服务和系统环境的耦合性。另外布署在CoreOS的多个容器都运行在各自独立的环境中,不会互相影响。
CoreOS专门为cluster等大规模布署而设计,提供了Etcd进行服务发觉,以及Fleet管理容器保证服务可用。
CoreOS愈发精简,例如RAM使用比普通Linux低40%。
CoreOS采用双分区模式(Dual-Partition),主分区为主动模式,负责系统运行,被动模式分区负责系统更新,更新时将整个CoreOS系统下载出来。
CoreOS是为集群服务而设计的,提供了Etcd、Fleet等管理工具管理容器和服务。Etcd是一种类似Zookeeper的分布式key/value储存服务,用于服务发觉和配置管理。Fleet是容器管理工具,保证服务的可用性,当某个机器的服务不可用时,Fleet会将服务迁移到其它机器上运行。
Docker生态中还有一个特别重要的容器管理工具–Kubernetes,它是Google开源的用于在集群环境中管理、维护、自动扩充容器,通过Kubernetes可以很便捷地在多个机器上管理和布署容器服务。如今早已得到IBM、Microsoft、RedHat等多个大公司的支持。
在Kubernetes中pod是一个基本单元linux内核,一个pod可以是提供相同功能的多个container,这种容器会被布署在同一个minion上。Replicationcontroller定义了多个pod或则容器须要运行,假如当前集群中运行的pod或容器达不到配置的数目,replicationcontroller会调度容器在多个minion上运行,保证集群中的pod数目。service则定义真实对外提供的服务,一个service会对应前端运行的多个container。
Kubernetes的构架由一个master和多个minion组成,master通过api提供服务,接受kubectl的恳求来调度管理整个集群。minion是运行Kubelet的机器,它接受master的指令创建pod或则容器。
最后介绍一下基于Docker实现的PaaS软件,DockerPaaS软件中以Deis和Flynn最为著名。Deis是基于Docker和CoreOS实现的轻量级的PaaS,遭到Heroku的启发,遵照“十二要素”构建应用技巧。
Deis是以应用程序为中心设计的,分为build、release、run三个阶段,用户执行”gitpush”后,Deis使用Docker容器编译并将编译结果保存在Docker镜像;发布阶段,一次build和配置文件形成一个数字标示的发布镜像,将发布镜像保存到Dockerregistry中以供后续发布到线上运行;运行阶段应用镜像会被调度到主机上运行,并更新相应的路由。
Flynn与Deis类似,也是以应用为中心,Flynn组件分为两层,layer0是底层资源的具象,主要负责资源调度以及服务发觉等,为下层应用容器的运行提供底层资源调度支持;layer1处理具体应用,通过Docker容器编译、部署和维护下层应用程序。
Docker总结
Docker从2013年发布第一个版本以来,早已火遍全球,技术迭代也比较频繁,其周边产品和技术也越来越丰富,因为Docker更新频繁,会出现新版本有时不兼容旧版本的情况,Docker周边产品基本都处于开发阶段还不具备生产环境下使用。
Docker的轻量级容器除了实现了资源隔离,并且几乎可以运行在任何地方,致使布署和扩充显得十分容易,随着Docker的日趋健全,希望Docker被越来越多的公司应用到生产环境中。