本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接。内容可任意使用,但对因使用该内容引起的后果不做任何保证。
作者:haoqiang1531@outlook.com
博客:fireaxe.blog.chinaunix.net
1. 什么是docker
从原理上看,docker是基于lxc与AUFS衍生出的一种技术。
Q:什么是lxc?
A:lxc是linux kernel container,相当于linux轻量级虚拟机。与virtual box、vmware等指令集虚拟化的虚拟机相比,其优势是利用了host系统的kernel。因此,lxc可以看成是共享kernel的虚拟机。福祸相依,lxc的缺点也是因为利用了host的kernel,导致container中运行的也必须是linux系统。如果需要使用非linux系统,则只能使用vmware等虚拟机。
Q:什么场景需要用docker?
这个问题最好看完下面的内容后再来讨论,不过基于该问题的重要性,还是决定挪到前面来讲说吧。(一般来讲,大部分只看前三段的。。。)
1) 云部署(这部分没玩过,只能是道听途说了)
以前都是用虚拟机,有了docker后,一部分对用什么操作系统没要求的应用,立刻移了过来。当然lxc也行,但是,但凡用到云平台的,都是大规模应用了。而lxc并不具备大规模应用所需的易部署性与易迁移性。
2) 公司内部的CI平台
一是CI平台的搭建,可以利用docker技术实现CI平台各工具的分离,提高升级的灵活性。同时通过用image的方式进行工具备份。(数据备份另有方法)
二是测试环境的打包,利用dockerfile,自动利用最新版本来合成可测试环境,可以排除环境的干扰。同时,一旦测试完成,可以对外发布image,避免客户重新安装软件带来的各种配置问题。(以前要适配各种环境,现在好了,连着环境一起发布,都不用测试多环境了)
3) 开发环境快速搭建
用docker实现开发环境,一旦谁有了新电脑想搭一个开发环境,直接pull一个image过来,分分钟搞定啊!!
Q:为什么lxc能实现隔离?
A:实际上linux启动的原理也是先启动kernel,kernel在启动user space。那么kernel启动多个user space也不是不可以了。所需的只是kernel内部要做好隔离。这也是lxc需要在kernel中实现的原因,user space是不一定需要知道除自己外还有其他user space的)
Q:为什么不同发行版可以同时在一个系统上的container内运行?
A:linux各发行版的不同主要在于user space,kernel都是一样的,这也为不同发行版同时运行提供了便利。lxc只是为container内提供了kernel,然后根据不同发行版的需要,构造不同的user space。
Q:既然lxc已经提供了container,那么为什么不直接用lxc呢?
A:其实也不是哪里都用docker,要看应用场景。
lxc本质上是一种虚拟机技术,如果我平时工作就是需要不同发行版或者统一发行版的不同 版本,那么使用lxc完全够了。
docker则更像是对服务的分割。现在的系统越来越复杂,在同一个机器上运行会有各种相互的干扰。同时不利于迁移,假如要把某个服务迁移到另一个机器上,会遇到各种环境配置与依赖的问题。这个用lxc也可以,但是由于lxc的每个container只提供了kernel的支持,用户态环境需要重新配置。假如有三个container都需要apache server,则我需要在每个container内都安装一次,这显然是一种浪费。或者是不同的开发环境都需要gcc编译器,则还要安装多份。于是又有人打起了复用部分user space的注意。
Q:如何实现user space级别的复用?
A:开头说了docker是基于lxc与AUFS的一种技术。AUFS就是让用户能够复用一部分userspace。
user space在本质上来说就是一个文件系统。因此user space 的复用就可以看做事对文件系统的复用。AUFS可以实现多个目录的堆叠,而且能单独设置每一个目录的读写属性。简单说,lxc为每一个container生成了一个与外界完全隔离的文件系统,这样从user space的角度看来,自己就是唯一的操作系统;AUFS在此基础上实现了堆叠,能让多个container共享一部分文件系统。
Q:AUFS实现的文件系统共享的意义何在?
A:举个例子,我要用两个container,分别放mysql server与redmine server。操作系统要求是ubuntu。
在lxc上,我需要分别构造两个含有ubuntu的container,再分别安装两个软件。
在docker上,则可以先构造一个ubuntu的container,然后再基于这个container分别构造两个container用来放mysql server与server。ubuntu的部分对于其派生的container来说是只读的。然后如果某一天用户发现需要在mysql基础上添加几个应用,可以方便的从mysql server这个container再派生。这样通过派生的方式,实现了复用。
更详细的可以参考:10张图带你深入理解Docker容器和镜像()
Q:image与container的区别?
A:其实image就是container,image相当于container的一个只读拷贝。如果子container直接复用父container,那么当子container修改了父container的内容时,该父container的其他子container也就收影响了。因此把父container做成一个只读的image,这样它的子container就不能修改它了。
另一方面,container是动态的,类似于git中被管理的一套代码,image则相当于一个commit(docker中从container生成image的命令恰好也是commit)。container只能用于开发者自己,只有把它用commit生成image后,其他人才能在此基础上去拉出branch,进行并行开发。
当然commit后,image只存在于本地,如果想多人协同开发,还需要通过“docker push”命令,把image推送到服务器上。docker的服务器被称之为docker registry。
Q:什么是dockerfile?
A:dockerfile是生成image的脚本,常用生产环境的部署。
例子1:我开发了一套软件,每周需要发布一个docker image。正常流程是pull一个基础image,然后下载安装我的软件,最后commit成一个新的image进行发布。有了dockerfile后,我就可以把这一过程做成自动化的,每次只需要运行一个docker build命令,利用写好的dockerfile来生成新的image。
例子2:某生产环境依赖于多中组件,但这些组件也在不停更新。如果使用image,则每次都需要更新完后进行打包与重新发送image的工作。有了dockerfile就好多了,每次需要更新环境时,只需要重新运行一次dockerfile,它自动会根据命令去下载与安装最新组件。
综上,我们在强调一次dockerfile的作用:一种脚本语言,让环境的打包过程自动化。开发过程中的作用不是很大。
2. 常用命令
命令
|
解释
|
create [--name container-id]
|
根据指定image创建container
|
start [-ti/-d/-v]
|
启动指定的container
-ti 建立虚拟终端病连接
-d 后台运行,且命令完成后不退出
-v 映射host的目录到container
|
run [--name container-id]
|
'docker create' + 'docker start'
|
ps [-a]
|
在运行的container
-a 所有container
|
iamges [-a]
|
所有image
-a 所有image及构成image的各层
|
history
|
某个image及构成该image的层
|
stop
|
container关机
|
pause
|
container暂停
|
rm
|
删除container
|
commit
|
根据container建立新的image
|
rmi
|
删除image
|
pull
|
合同步指定image到本地
|
push
|
合入image到docker hub
|
login
|
登陆docker hub
|
3. docker例程
这个直接参考下面的链接吧:
4. 数据卷与数据卷容器(data volume & data volume container)
1) 数据卷与数据卷容器的意义
数据卷:
实现数据与应用的分离。实际应用备份时不会包含数据。数据进行单独备份。因为数据与应用的备份通常需要采取不同的策略。
数据卷容器
通过数据卷容器,对实际应用于host进行隔离。这样数据在host上位置改变时,只需要修改数据卷容器,其他应用类容器不用修改。
2)使用数据卷
创建包含一个数据卷的容器:$ docker run -v /data/path:/mount/path:ro --name dbdata ubuntu /bin/bash
创建包含两个数据卷的容器:$ docker run -d -v /data/path1:/mount/path1:ro -v /data/path2:/mount/path2:ro --name dbdata ubuntu /bin/bash
$ docker run -ti --volumes-from dbdata --name app ubuntu
通过-v把host的目录“/data/path”给mount到container dbdata的“/mount/path”目录下。dbdata就成为数据卷容器。
实际应用的容器app基于dbdata来生成。通过“--volumes-from dbdata”获得数据卷容器dbdata具有的读写权限。
本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接。内容可任意使用,但对因使用该内容引起的后果不做任何保证。
作者:haoqiang1531@outlook.com
博客:fireaxe.blog.chinaunix.net
阅读(6474) | 评论(0) | 转发(0) |