容器技术的生态系统自下而上分别覆盖了 IaaS 层和 PaaS 层所涉及的各类问题,包括资源调度、编排、部署、监控、配置管理、存储网络管理、安全、容器化应用支撑平台等。除了基于容器技术解决构建分布式平台无法回避的经典问题,容器技术主要带来了以下几点好处。
持续部署与测试。容器消除了线上线下的环境差异,保证了应用生命周期的环境一致性和标准化。开发人员使用镜像实现标准开发环境的构建,开发完成后通过封装着完整环境和应用的镜像进行迁移,由此,测试和运维人员可以直接部署软件镜像来进行测试和发布,大大简化了持续集成、测试和发布的过程。
跨云平台支持。容器带来的最大好处之一就是其适配性,越来越多的云平台都支持容器,用户再也无需担心受到云平台的捆绑,同时也让应用多平台混合部署成为可能。目前支持容器的 IaaS 云平台包括但不限于亚马逊云平台(AWS
)、Google 云平台(GCP
)、微软云平台(Azure
)、OpenStack
等,还包括如 Chef
、Puppet
、Ansible
等配置管理工具。
环境标准化和版本控制。基于容器提供的环境一致性和标准化,你可以使用 Git 等工具对容器镜像进行版本控制,相比基于代码的版本控制来说,你还能够对整个应用运行环境实现版本控制,一旦出现故障可以快速回滚。相比以前的虚拟机镜像,容器压缩和备份速度更快,镜像启动也像启动一个普通进程一样快速。
高资源利用率与隔离。容器没有管理程序的额外开销,与底层共享操作系统,性能更加优良,系统负载更低,在同等条件下可以运行更多的应用实例,可以更充分地利用系统资源。同时,容器拥有不错的资源隔离与限制能力,可以精确地对应用分配 CPU、内存等资源,保证了应用间不会相互影响。
容器跨平台性与镜像。Linux 容器虽然早在 Linux 2.6 版本内核已经存在,但是缺少容器的跨平台性,难以推广。容器在原有 Linux 容器的基础上进行大胆革新,为容器设定了一整套标准化的配置方法,将应用及其依赖的运行环境打包成镜像,真正实现了 一次构建,到处运行 的理念,大大提高了容器的跨平台性。
易于理解且易用。Docker 的英文原意是处理集装箱的码头工人,标志是鲸鱼运送一大堆集装箱,集装箱就是容器,生动好记,易于理解。一个开发者可以在 15 分钟之内入门 Docker 并进行安装和部署,这是容器使用史上的一次飞跃。因为它的易用性,有更多的人开始关注容器技术,加速了容器标准化的步伐。
应用镜像仓库。Docker 官方构建了一个镜像仓库,组织和管理形式类似于 GitHub,其上已累积了成千上万的镜像。因为 Docker 的跨平台适配性,相当于为用户提供了一个非常有用的应用商店,所有人都可以自由地下载微服务组件,这为开发者提供了巨大便利。
用户在使用 Docker 时,需要使用 Docker 命令行工具 docker
与 Docker daemon
建立通信。Docker daemon
是 Docker 守护进程,负责接收并分发执行 Docker 命令。
值得一提的是,docker
命令的执行一般都需要获取 root
权限,因为 Docker 的命令行工具 docker
与 Docker daemon
是同一个二进制文件,而 Docker daemon
负责接收并执行来自 docker
的命令,它的运行需要 root
权限。
在进行命令的解读前,依据命令的用途对其进行分类,帮助大家尽快掌握 docker
命令。
子命令分类 | 子命令 |
---|---|
Docker 环境信息 | info 、version |
容器生命周期管理 | create 、exec 、kill 、pause 、 restart 、rm 、run 、start 、stop 、 unpause |
镜像仓库命令 | login 、logout 、pull 、push 、search |
镜像管理 | build 、images 、import 、load 、rmi 、save 、tag 、commit |
容器运维操作 | attach 、export 、inspect 、port 、ps 、rename 、stats 、top 、wait 、cp 、diff 、update |
容器资源管理 | volume 、network |
系统日志信息 | events 、history 、logs |
从 docker
命令使用出发,梳理出如下图所示的命令结构图。
docker info
命令用于检查 Docker 是否正确安装。如果 Docker 正确安装,该命令会输出 Docker 的配置信息。
docker info
命令一般结合 docker version
命令使用,两者结合使用能够提取到足够详细的 Docker 环境信息。
$ sudo docker info
$ sudo docker version
容器生命周期管理涉及容器启动、停止等功能,下面选取最常用的 docker run
命令和负责启动停止的 docker
start
/ stop
/ restart
命令举例。
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run
命令用来基于特定的镜像创建一个容器,并依据选项来控制该容器。
$ sudo docker run ubuntu echo "Hello World"
Hello World
这是 docker run
命令最基本的使用方法,该命令从 ubuntu
镜像启动一个容器,并执行 echo
命令打印出 “Hello World”。执行完 echo
命令后,容器将停止运行。docker run
命令启动的容器会随机分配一个容器 ID(CONTAINER ID
),用以标识该容器。
在选取启动容器的镜像时,可以在镜像名后添加 tag
来区分同名的镜像,如 ubuntu:latest
、ubuntu:13.04
、ubuntu:14.04
。如在选取镜像启动容器时,用户未指定具体 tag
,Docker 将默认选取 tag
为 latest
的镜像。
$ sudo docker run -i -t --name mytest ubuntu:latest /bin/bash
root@83b752d52f3f:/#
上例中,docker run
命令启动一个容器,并为它分配一个伪终端执行 /bin/bash
命令,用户可以在该伪终端与容器进行交互。其中:
-i
选项表示使用交互模式,始终保持输入流开放;-t
选项表示分配一个伪终端,一般两个参数结合时使用 -it
,即可在容器中利用打开的伪终端进行交互操作;--name
选项可以指定 docker run
命令启动的容器的名字,若无此选项,Docker 将为容器随机分配一个名字。关于 docker run
的其他选项的用法可以通过官方文档查知。
docker run
命令可以新建一个容器来运行,而对于已经存在的容器,可以通过 docker
start
/ stop
/ restart
命令来启动、停止和重启。
利用 docker run
命令新建一个容器时,Docker 将自动为每个新容器分配唯一的 ID 作为标识。docker
start
/ stop
/ restart
命令一般利用容器 ID 标识确定具体容器,在一些情况下,也使用容器名来确定容器。
Docker registry
是存储容器镜像的仓库,用户可以通过 Docker client
与 Docker registry
进行通信,以此来完成镜像的搜索、下载和上传等相关操作。DockerHub 是由 Docker 公司在互联网上提供的一个镜像仓库,提供镜像的公有与私有存储服务,它是用户最主要的镜像来源。除了 Docker Hub 外,用户还可以自行搭建私有服务器来实现镜像仓库的功能。下面选取最常用的 docker pull
和 push
命令举例。
docker pull
命令是 Docker 中的常用命令,主要用于从 Docker registry
中拉取 image
或 repository
。在 Docker 官方仓库 Docker Hub 中有许多即拿即用的镜像资源,通过 docker pull
命令可以有效地利用它们,这也体现了 Docker 一次编译,到处运行的特性。同时,当镜像被拉取到本地后,用户可以在其现有基础上做出自身的更改操作,这也大大加快了应用的开发进程。
docker pull [OPTIONS] NAME[:TAG @DIGEST]
在使用 docker pull
命令时,可以从官方的 Docker Hub 中的官方镜像库、其他公共库、私人库中获取镜像资源,同时,还可以从私有服务器中获取镜像资源。只需在具体的镜像名前添加用户名、特定库名或者服务器地址即可获取镜像。使用示例如下:
#从官方Hub拉取ubuntu:latest镜像
$ sudo docker pull ubuntu
#从官方Hub拉取指明“ubuntu 12.04”tag的镜像
$ sudo docker pull ubuntu:ubuntu12.04
#从特定的仓库拉取ubuntu镜像
$ sudo docker pull SEL/ubuntu
#从其他服务器拉取镜像
$ sudo docker pull 10.10.103.215:5000/sshd
与 docker pull
命令相对应的 docker push
命令,可以将本地的 image
或 repository
推送到 Docker Hub 的公共或私有镜像库,以及私有服务器。
docker push [OPTIONS] NAME[:TAG]
$ sudo docker images
通过 docker images
命令可以列出主机上的镜像,默认只列出最顶层的镜像,可以使用 -a
选项显示所有镜像。
docker images [OPTIONS] [REPOSITORY[:TAG]]
上例中,从 REPOSITORY 属性可以判断出镜像是来自于官方镜像、私人仓库还是私有服务器。
这两个子命令的功能都是删除,docker rmi
命令用于 删除镜像,docker rm
命令用于 删除容器。它们可同时删除多个镜像或容器,也可按条件来删除。
docker rm [OPTIONS] CONTAINER [CONTAINER...]
docker rmi [OPTIONS] IMAGE [IMAGE...]
需要注意的是,使用 rmi
命令删除镜像时,如果已有基于该镜像启动的容器存在,则无法直接删除,需要首先删除容器。当然,这两个子命令都提供 -f
选项,可强制删除存在容器的镜像或启动中的容器。
docker attach
命令对于开发者来说十分有用,它可以连接到正在运行的容器,观察该容器的运行情况,或与容器的主进程进行交互。
docker attach [OPTIONS] CONTAINER
docker inspect
命令可以查看镜像和容器的详细信息,默认会列出全部信息,可以通过 --format
参数来指定输出的模板格式,以便输出特定信息。
docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...]
例如:
#查看容器的内部IP
$ sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' ee36
172.17.0.8
docker ps
命令可以查看容器的相关信息,默认只显示 正在运行的容器的信息。可以查看到的信息包括 CONTAINER ID
、NAMES
、IMAGE
、STATUS
、容器启动后执行的 COMMAND
、创建时间 CREATED
和绑定开启的端口 PORTS
。docker ps
命令最常用的功能就是查看容器的 CONTAINER ID
,以便对特定容器进行操作。
除了上述的命令外,Docker 还有一系列非常有用的子命令,如固化容器为镜像的 commit
命令等。下面以一些较为常用的子命令举例。
commit
命令可以将一个容器固化为一个新的镜像。当需要制作特定的镜像时,会进行修改容器的配置,如在容器中安装特定工具等,通过 commit
命令可以将这些修改保存起来,使其不会因为容器的停止而丢失。
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
提交保存时,只能选用正在运行的容器(即可以通过 docker ps
查看到的容器)来制作新的镜像。在制作特定镜像时,直接使用 commit
命令只是一个临时性的辅助命令,不推荐使用。官方建议通过 docker build
命令结合 Dockerfile
创建和管理镜像。
events
、history
和 logs
这 3 个命令用于查看 Docker 的系统日志信息。
events
命令会打印出实时的系统事件。history
命令会打印出指定镜像的历史版本信息,即构建该镜像的每一层镜像的命令记录。logs
命令会打印出容器中进程的运行日志。docker events [OPTIONS]
docker history [OPTIONS] IMAGE
docker logs [OPTIONS] CONTAINER
对于 Docker 的操作,我们应更多地结合案例操作进行深入学习和理解,并多做练习,打下坚实的基础。同时,深入了解 Docker 的核心原理对于掌握 Docker 的使用操作颇有益处。