一、什么是Docker?
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公 司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub (http s://github.com/docker/docker) 上进行维护。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。
在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操 作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用 本地主机的操作系统,而传统方式则是在硬件层面实现。
传统虚拟化
Docker
二、为什么要使用Docker?
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
首先,Docker 容器的启动可以在**秒级**实现,这相比传统的虚拟机方式要快得多。 其次,Docker 对系统资源的**利用率很高**,一台主机上可以同时运行数千个 Docker 容器。
容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚 拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
具体说来,Docker 在如下几个方面具有较大的优势。
2.1 更快速的交付和部署
对开发和运维(devop)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代 码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解 应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部 署的时间。
2.2 更高效的虚拟化
Docker 容器的运行不需要额外的 hypervisor 支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。
2.3 更轻松的迁移和扩展
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这 种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
2.4 更简单的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更 新,从而实现自动化并且高效的管理。
2.5 对比传统虚拟机总结
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
磁盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于原生 |
系统支持量 | 单机支持几千个容器 | 一般几十个 |
三、Docker基本概念
Docker包括三个基本概念:
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
3.1 镜像
Docker 镜像就是一个只读的模板。
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。
镜像可以用来创建 Docker 容器。
Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已 经做好的镜像来直接使用。
3.1.1 获取镜像
Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker 会从镜像仓库下载(默认是 Dock er Hub 公共注册服务器中的仓库)。
可以使用 ```docker pull```命令来从仓库获取所需要的镜像。
3.2 容器
Docker 利用容器来运行应用。
容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。
3.3 仓库
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最大的公开仓库是 Docker Hub (https://hub.docker.com) ,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool (http://www.dockerpool.com) 等,可以提供大陆用户更稳定快速的访问。 当然,用户也可以在本地网络内创建一个私有仓库。
当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上 使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
注:Docker 仓库的概念跟 Git (http://git-scm.com) 类似,注册服务器可以理解为 GitHub 这样的托管服务。
四、Docker常用命令
docker命令 | 常用参数(OPTIONS) | 解释 |
---|---|---|
| 从Docker Hub 拉取镜像。 | |
| 列出当前pull的所有镜像 | |
|
| 在一个新的容器中运行一个命令 |
|
| 从已有的镜像创建一个新的镜像。
|
|
| 保存一个或多个镜像到tar包。默认保存到stdout。 |
|
| 从一个tar包或者stdin加载镜像 |
|
| 移除一个或多个镜像 |
| 启动一个或多个停止的容器 | |
|
| 停止一个或多个运行的容器。 |
| 挂载本地标准输入输出、错误流到一个运行的容器。 | |
|
| 导出容器快照到本地。tar包 |
| 从本地tar包或者url导入一个镜像快照 | |
|
| 移除一个或多个容器 |
| 在Docker Hub搜索image | |
|
| 构建一个镜像,从Dockerfile |
五、Dockerfile
5.1 基本结构
Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。
一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
例如:
# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# Base image to use, this must be set as the first line
FROM ubuntu
# Maintainer: docker_user <docker_user at email.com> (@docker_user)
MAINTAINER docker_user docker_user@email.com
# Commands to update the image
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# Commands when creating a new container
CMD /usr/sbin/nginx
5.2 dockerfile 指令
指令 | 格式 | 解释 |
---|---|---|
FORM | FROM <image>or FROM<image>:<tag> | 第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM指令(每个镜像一次)。 |
MAINTAINER | MAINTAINER <name> | 指定维护者的信息 |
RUN | RUN <command> or RUN ["executable", "param1", "param2"] | 前者将在 shell 终端中运行命令,即 /bin/sh -c ; 后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"] 。
|
CMD | 支持三种格式
| 指定启动容器时执行的命令,每个Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会 被执行。 如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。 |
EXPOSE | EXPOSE <port> [<port>...] | 告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。 |
ENV | ENV <key> <value> | 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。 |
ADD | ADD <src> <dest> | 该命令将复制指定的 <src> 到容器中的<dest> 。 其中 <src> 可以是Dockerfile所在目录的一个相对路 径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。 |
COPY | COPY <src> <dest> | 复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest> 。 当使用本地目录为源目录时,推荐使用 COPY 。 |
ENTRYPOINT | 两种格式:
| 配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。 每个 Dockerfile 中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。 |
VOLUME | VOLUME ["/data"] | 创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。 |
USER | USER daemon | 指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。 当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如: roupadd -r postgres && useradd -r -g postgres postgres 。要临时获取管理员权限可以使用 gosu ,而不推 荐 sudo 。 |
WORKDIR | WORKDIR /path/to/workdir | 为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。 可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。 |
ONBUILD | ONBUILD [INSTRUCTION] | 配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。 |
六、Docker Compose
6.1 简介
Compose 项目目前在 Github (https://github.com/docker/compose) 上进行维护,目前最新版本是 1.2.0。
Compose 定位是“defining and running complex applications with Docker”,前身是 Fig,兼容 Fig 的模板文件。
Dockerfile 可以让用户管理一个单独的应用容器;而 Compose 则允许用户在一个模板(YAML 格式)中定义 一组相关联的应用容器(被称为一个 project ,即项目),例如一个 Web 服务容器再加上后端的数据库服务容 器等。
6.2 Compose命令说明
大部分命令都可以运行在一个或多个服务上。如果没有特别的说明,命令则应用在项目所有的服务上。
执行 docker-compose [COMMAND] --help 查看具体某个命令的使用说明。
基本的使用格式是:
docker-compose [options] [COMMAND] [ARGS...]
6.2.1 选项
选项 | 说明 |
---|---|
| 输出更多调试信息 |
| 打印版本并退出 |
| 使用特定的 compose 模板文件,默认为 docker-compose.yml |
| 指定项目名称,默认使用目录名称 |
6.2.2 命令
命令 | 选项 | 说明 |
---|---|---|
build | 构建或者重新构建一个服务 服务一旦构建后,将会带上一个标记名,例如 web_db。 可以随时在项目目录下运行 docker-compose build 来重新构建服务。 | |
help | 获得一个命令的帮助 | |
kill | -s,指定发送的信号。默认为SIGKILL | 通过发送 SIGKILL 信号来强制停止服务容器 |
logs | 查询服务的日志输出 | |
port | 打印绑定的公共端口 | |
ps | 列出所有的容器 | |
pull | 拉取服务镜像 | |
rm | 删除停止的服务容器 | |
run | 在服务上执行一个命令 | |
scale | 设置同一个服务运行的容器的个数 | |
start | 启动一个已经存在的服务容器 | |
stop | 停止一个已经启动的容器,但不删除它 | |
up | 构建,(重新)创建,启动,链接一个服务相关的容器。 |
6.2.3 yaml模板文件
默认的模板文件是 docker-compose.yml ,其中定义的每个服务都必须通过 image 指令指定镜像或 build 指 令(需要 Dockerfile)来自动构建。
其它大部分指令都跟 docker run 中的类似。
如果使用 build 指令,在 Dockerfile 中设置的选项(例如: CMD , EXPOSE , VOLUME , ENV 等) 将会自动被获取,无需在 docker-compose.yml 中再次设置。
配置 | 解释 |
---|---|
image | 指定为镜像名称或镜像 ID。如果镜像在本地不存在, Compose 将会尝试拉去这个镜像。 |
build | 指定 Dockerfile 所在文件夹的路径。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。 |
command | 覆盖容器启动后默认执行的命令。 |
links | 链接到其它服务中的容器。使用服务名称(同时作为别名)或服务名称:服务别名 (SERVICE:ALIAS) 格式 都可以。 |
external_links | 链接到 docker-compose.yml 外部的容器,甚至 并非 Compose 管理的容器。参数格式跟 links 类似。 |
ports | 暴露端口信息。 注:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 你可能会得到错误得结 果,因为 YAML 将会解析 xx:yy 这种数字格式为 60 进制。所以建议采用字符串格式。 |
expose | 暴露端口,但不映射到宿主机,只被链接的服务访问。 仅可以指定内部端口为参数 |
volumes | 卷挂载路径设置。可以设置宿主机路径(HOST:CONTAINER ) 或加上访问模式 ( HOST:CONTAINER:ro )。 |
volumes_from | 从另一个服务或容器挂载它的所有卷。 |
environment | 设置环境变量。你可以使用数组或字典两种格式。 |
env_file | 从文件中获取环境变量,可以为单独的文件路径或列表。 |
extends | 基于已有的服务进行扩展。 |
net | 设置网络模式。使用和 docker client 的 --net 参数一样的值。 |
pid | 跟主机系统共享进程命名空间。打开该选项的容器可以相互通过进程 ID 来访问和操作。 |
dns | 配置 DNS 服务器。可以是一个值,也可以是一个列表。 |
cap_add, cap_drop | 添加或放弃容器的 Linux 能力(Capabiliity)。 |
dns_search | 配置 DNS 搜索域。可以是一个值,也可以是一个列表。 |
restart | 服务是否一直重启。restart: always |