Docker概览
Docker是一个用于开发、交付和运行应用的开放平台,Docker被设计用于更快地交付应用。Docker可以将应用程序和基础设施层隔离,并且可以将基础设施当作程序一样进行管理。使用Docker,可以更快地打包代码、测试以及部署,并且可以减少从编写到部署运行代码的周期。Docker将内核容器特性(LXC)、工作流和工具集成,以帮助管理和部署应用。
什么是Docker
核心是,Docker了一种在安全隔离的容器中运用近乎所有应用的方式,这种隔离性和安全性允许你在同一个主机上同时运行多个容器,而容器的这种轻量级特性,无需消耗运用hpervisor所需的额外负载,意味着你可以节省更多的硬件资源。
基于容器虚拟化的工具或平台可提供:
将应用(包括支撑组件)放入Docker容器中
分发和交付这些容器给团队,便于后续的开发和测试
将容器部署到生产环境中,生产环境可以是本地的数据中心,也可以在云端。
Docker 是容器管理工具 Docker 是一个轻量级、便携式、与外界隔离的容器,也是一个可以在容器中很方便地构建、传输、运行应用的引擎。和传统的虚拟化技术不同的是,Docker 引擎并不虚拟出一台虚拟机,而是直接使用宿主机的内核和硬件,直接在宿主机上运行容器内应用。也正是得益于此,Docker 容器内运行的应用和宿主机上运行的应用性能差距几乎可以忽略不计。 但是 Docker 本身并不是一个容器系统,而是一个基于原有的容器化工具 LXC 用来创建虚拟环境的工具。类似 LXC 的工具已经在生产环境中使用多年,Docker 则基于此提供了更加友好的镜像管理工具和部署工具。
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 虚拟机里的。
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 镜像。
Docker 可以节约时间 很多年前我在为一个连锁餐厅开发软件时,仅仅是为了描述如何搭建环境都需要写一个 12 页的 Word 文档。例如本地 Oracle 数据库,特定版本的 JAVA,以及其他七七八八的系统工具和共享库、软件包。整个搭建过程浪费掉了我们团队每个人几乎一天的时间,如果用金钱衡量的话,花掉了我们上万美元的时间成本。虽然客户已经对这种事情习以为常,甚至认为这是引入新成员、让成员适应环境、让自己的员工适应我们的软件所必须的成本,但是相比较起来,我们宁愿把更多的时间花在为客户构建可以增进业务的功能上面。 如果当时有 Docker,那么构建环境就会像使用自动化搭建工具 Puppet / Chef / Salt / Ansible 一样简单,我们也可以把整个搭建时间周期从一天缩短为几分钟。但是和这些工具不同的地方在于,Docker 可以不仅仅可以搭建整个环境,还可以将整个环境保存成磁盘文件,然后复制到别的地方。需要从源码编译 Node.js 吗?Docker 做得到。Docker不仅仅可以构建一个 Node.js 环境,还可以将整个环境做成镜像,然后保存到任何地方。当然,由于 Docker 是一个容器,所以不用担心容器内执行的东西会对宿主机产生任何的影响。 现在新加入我们团队的人只需要运行docker-compose up
命令,便可以喝杯咖啡,然后开始工作了。
Docker 可以节省开销 当然,时间就是金钱。除了时间外,Docker 还可以节省在基础设施硬件上的开销。高德纳和麦肯锡的研究表明,数据中心的利用率在 6% - 12% 左右。不仅如此,如果采用虚拟机的话,你还需要被动地监控和设置每台虚拟机的 CPU 硬盘和内存的使用率,因为采用了静态分区(static partitioning)所以资源并不能完全被利用。而容器可以解决这个问题:容器可以在实例之间进行内存和磁盘共享。你可以在同一台主机上运行多个服务、可以不用去限制容器所消耗的资源、可以去限制资源、可以在不需要的时候停止容器,也不用担心启动已经停用的程序时会带来过多的资源消耗。凌晨三点的时候只有很少的人会去访问你的网站,同时你需要比较多的资源执行夜间的批处理任务,那么可以很简单的便实现资源的交换。 虚拟机所消耗的内存、硬盘、CPU 都是固定的,一般动态调整都需要重启虚拟机。而用 Docker 的话,你可以进行资源限制,得益于 CGroup,可以很方便动态调整资源限制,让然也可以不进行资源限制。Docker 容器内的应用对宿主机而言只是两个隔离的应用程序,并不是两个虚拟机,所以宿主机也可以自行去分配资源。
Docker介绍:http://www.lupaworld.com/article-243555-1.html
Docker介绍:http://www.docker.org.cn/book/docker/what-is-docker-16.html
Docker官方文档:https://docs.docker.com/engine/understanding-docker/
Docker中文文档:http://git.oschina.net/widuu/chinese_docker
2 Docker的安装
Docker的安装是比较简单的。
对于Linux用户可以借助其发⾏版的Linux包管理工具安装,对于Windows和
MAC用户相对麻烦一些,文中下以Windows7系统为例,讲述安装过程。
笔者强烈建议大家使用Linux系统进入本章的学习,第一是比较符合目前
Docker的市场趋势,第一Docker本身就是基于Linux的LXC技术。
CentOS 7.0下Docker的安装
查看内核版本(Docker需要64位版本,同时内核版本在3.10以上,如果版
本低于3.10,需要升级内核):uname -r
更新yum包:
yum update
-
添加yum仓库:
sudo tee /etc/yum.repos.d/docker.repo <<-'EOF' [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/7/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg EOF
安装Docker:
yum install docker-engine
启动Docker:
service docker start
-
使用Docker国内镜像(为Docker镜像下载提速,非必须)
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://fe8a7d6e.m.daocloud.io
参考:
官方文档:https://docs.docker.com/engine/installation/linux/centos/
CentOS 6.5下Docker的安装
Docker容器最早受到RHEL完善的支持是从最近的CentOS 7.0开始的,官方说明是只能运行于64位架构平台,内核版本为2.6.32-431及以上(即 >=CentOS 6.5,运行docker时实际提示3.10.0及以上)。 需要注意的是CentOS 6.5与7.0的安装是有一点点不同的,CentOS 6.x上Docker的安装包叫docker-io,并且来源于Fedora epel库,这个仓库维护了大量的没有包含在发行版中的软件,所以先要安装EPEL,而CentOS 7.x的Docker直接包含在官方镜像源的Extras仓库(CentOS-Base.repo下的[extras]节enable=1启用)。
下面就CentOS 6.5讲解Docker的安装过程,以下是软件版本:
Linux版本 Docker版本 CentOS 6.5 X64(只能X64) 1.7.1 升级内核
查看内核版本:
uname -r
结果:
2.6.32-431.el6.x86_64
,不满足上文的需求,故此需要升级内
核。升级步骤:
导入公钥数字证书:
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
安装ELRepo:
rpm -ivh http://www.elrepo.org/elrepo-release-6-5.el6.elrepo.noarch.rpm
-
安装kernel长期版本:
yum --enablerepo=elrepo-kernel install kernel-lt -y
lt表示long-term的意思,长期维护版本,也可以将kernel-lt改为kernel
-ml,安装主线版本 -
编辑grub.conf文件,修改Grub引导顺序,确认刚安装好的内核在哪个位置,然后设置default值(从0开始),一般新安装的内核在第一个位置,所以设置default=0。
vim /etc/grub.conf # 以下是/etc/grub.conf的内容 default=0 # 修改该值即可 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS (3.10.103-1.el6.elrepo.x86_64)
重启并查看内核版本,将会发现内核已经更新。
安装Docker
-
禁用selinux,因为selinux和LXC有冲突,故而需要禁用
vim /etc/selinux/config的内容 # 以下是/etc/selinux/config的内容 # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enfo rcing. # disabled - No SELinux policy is loaded. SELINUX=disabled # 将SELINUX设为disabled,注意修改后最好重启 下机器。
-
安装 Fedora EPEL
yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_ 64/epel-release-6-8.noarch.rpm
-
安装Docker
yum install -y docker-io
-
以守护模式运行Docker
docker -d
-
如果不报错,那就是启动成功了,如果报以下异常:
docker: relocation error: docker: symbol dm_task_get_info_ with_deferred_remove, version Base not defined in file lib devmapper.so.1.02 with link time reference INFO[0000] Listening for HTTP on unix (/var/run/docker.soc k)
执行以下内容:
yum upgrade device-mapper-libs
-
将Docker开机启动
chkconfig docker on
重启机器
其他平台的安装
参考文档
Windows:https://docs.docker.com/engine/installation/windows/
MAC: https://docs.docker.com/engine/installation/mac/
CentOS:https://docs.docker.com/engine/installation/linux/centos/
3.Docker的常用命令
准备工作
对于Window用户,请点击Kitematic左下方的DOCKER CLI按钮,在弹
出的命令窗体内输入命令,不要在CMD中测试Docker命令。-
下载镜像,以kitematic/hello-world-nginx为例:
docker pull kitematic/hello-world-nginx
常用命令测试一览表
命令 解释 docker images 列表本地所有镜像 docker search 关键词 在Docker Hub中搜索镜像 docker pull 镜像名称 下载Docker镜像 docker rmi 镜像id 删除Docker镜像。加参数-f表示强制删除。 docker run 镜像名称 启动Docker镜像 docker ps 列表所有运行中的Docker容器。该命令参数比较多,-a:列表所有容器;-f:过滤;-q 只列表容器的id。 docker version 查看Docker版本信息 docker info 查看Docker系统信息,例如:CPU、内存、容器个数等等 docker kill 容器id 强行停止一个容器 docker start /stop / restart 容器id 启动、停止、重启指定容器 docker build -t 标签名称 目录 构建Docker镜像,-t 表示指定一个标签 docker tag 为镜像打标签 更多命令,请输入 --help 参数查询;如果想看docker命令可输入 docker
--help ;如果想查询 docker run 命令的用法,可输入 docker run --
help 。docker run
docker run 应该是我们最常用的命令了,这边讲解一下,便于大家入门。
参数 解释 -d 后台 -P 随机端口映射 -p 指定端口映射格式:
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort |
测试:
-
启动测试镜像
docker pull kitematic/hello-world-nginx
docker run -d -p 91:80 kitematic/hello-world-nginx
这边解释下docker run的两个参数:
-d # 后台运行 -p 宿主机端口:容器端口 # 开放容器端口到宿主机端口
访问:http://localhost:91 测试,这里的localhost指的是宿主机的主机名
TIPS
- 目前网上很多教程还是boot2docker(项目地
址:https://github.com/boot2docker/boot2docker),该项目已废
弃了,笔者不建议使用。- 如果安装不成功,请按照提示解决一下,譬如开启VT技术等等。
Docker的提示是做得非常好的。- 对于Winodws用户,建议点击Kitematic左下⻆的DOCKER CLI,在
弹出来的控制台输入Docker命令,而不要直接在CMD中输入命令。
参考文档:
http://my.oschina.net/denglz/blog/487332
https://segmentfault.com/a/1190000000733628
http://www.oschina.net/translate/nstalling-dockerio-on-centos-64-64-bit
https://segmentfault.com/a/1190000000735011
http://www.server110.com/docker/201411/11122.html
http://dockone.io/article/152http://www.open-open.com/lib/view/open1422492851548.html
Docker常用命令:http://www.infoq.com/cn/articles/docker-command-line-quest/