使用 Docker 镜像
在之前的介绍中,我们知道镜像是 Docker 的三大组件之一。
Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker 会从镜像仓库下
载(默认是 Docker Hub )。
下面介绍更多关于镜像的内容,包括:
从仓库获取镜像;
管理本地主机上的镜像;
介绍镜像实现的基本原理。
Docker 在 1.13 版本引进了新的管理命令(management commands),在 Docker 1.13+ 推荐使用 docker image 子命令来管理 Docker 镜像。
获取镜像
从 Docker Registry 获取镜像的命令是 docker pull 。其命令格式为:
docker pull [选项] [Docker Registry地址]<仓库名>:<标签>
具体的选项可以通过 docker pull --help 命令看到,镜像名称的格式:
Docker Registry 地址:地址的格式一般是 <域名/IP>[:端口号] 。默认地址是 Docker Hub。
仓库名:仓库名是两段式名称,即 <用户名>/<软件名> 。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。
例如:
$ docker pull centos:latest
14.04: Pulling from library/centos
bf5d46315322: Pull complete
9f13e0ac480c: Pull complete
e8988b5b3097: Pull complete
40af181810e7: Pull complete
e6f7c7e5c03e: Pull complete
Digest: sha256:147913621d9cdea08853f6ba9116c2e27a3ceffecf3b492983ae97c3d643fbbe
Status: Downloaded newer image for centos:latest
上面的命令中没有给出 Docker Registry 地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 centos:latest ,因此将会获取官方镜像 library/centos 仓库中标签为 latest 的镜像。
如果从 Docker Hub 下载镜像非常缓慢,可以参照 镜像加速器 一节配置加速器。
运行
有镜像后,我们就可以以这个镜像为基础启动一个容器来运行。以上面的 centos:latest 为例,如果我们打算启动里面的 bash 并且进行交互式操作的话,可以执行下面的命令。
$ docker run -it --rm \
centos:latest \
bash
[root@ce0453a231bb /]$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
[root@ce0453a231bb /]$ exit
exit
$
docker run 就是运行容器的命令,具体格式参数如下。
-it:这是两个参数,-i:交互式操作,-t:终端。我们这里打算进入bash执行一些命令并查看返回结果,因此我们需要交互式终端。
--rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm 。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm 可以避免浪费空间。
centos:latest:这是指用 centos:latest 镜像为基础来启动容器。
bash:放在镜像名后的命令,这里我们希望有个交互式 Shell,因此用的是 bash 。
最后我们通过 exit 退出了这个容器。
Docker 1.13+
在 Docker 1.13+ 版本中推荐使用 docker image 来管理镜像。
$ docker image pull centos:latest
$ docker container run -it --rm \
centos:latest \
bash
列出镜像
要想列出已经下载下来的镜像,可以使用 docker images 命令。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 5f515359c7f8 5 days ago 183 MB
nginx latest 05a60462f8ba 5 days ago 181 MB
列表包含了仓库名、标签、镜像 ID、创建时间以及所占用的空间。其中仓库名、标签在之前的基础概念章节已经介绍过了。镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签。
列出部分镜像
不加任何参数的情况下, docker images 会列出所有顶级镜像,但是有时候我们只希望列出部分镜像。
根据仓库名列出镜像
$ docker images centos
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 16.04 f753707788c5 4 weeks ago 127 MB
centos latest f753707788c5 4 weeks ago 127 MB
centos 14.04 1e0c3dd64ccd 4 weeks ago 188 MB
列出特定的某个镜像,也就是说指定仓库名和标签
$ docker images centos:16.04
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 16.04 f753707788c5 4 weeks ago 127 MB
除此以外, docker images 还支持强大的过滤器参数 --filter ,或者简写 -f 。之前我们已
经看到了使用过滤器来列出虚悬镜像的用法,它还有更多的用法。比如,我们希望看到在
mongo:3.2 之后建立的镜像,可以用下面的命令:
$ docker images -f since=mongo:3.2
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 5f515359c7f8 5 days ago 183 MB
nginx latest 05a60462f8ba 5 days ago 181 MB
想查看某个位置之前的镜像也可以,只需要把 since 换成 before 即可。
此外,如果镜像构建时,定义了 LABEL ,还可以通过 LABEL 来过滤。
$ docker images -f label=com.example.version=0.1
...
以特定格式显示
默认情况下, docker images 会输出一个完整的表格,但是我们并非所有时候都会需要这些内容。比如,刚才删除虚悬镜像的时候,我们需要利用 docker images 把所有的虚悬镜像的ID 列出来,然后才可以交给 docker rmi 命令作为参数来删除指定的这些镜像,这个时候就用到了 -q 参数。
另外一些时候,我们可能只是对表格的结构不满意,希望自己组织列;或者不希望有标题,这样方便其它程序解析结果等,这就用到了 Go 的模板语法。
比如,下面的命令会直接列出镜像结果,并且只包含镜像ID和仓库名:
$ docker images --format "{{.ID}}: {{.Repository}}"
5f515359c7f8: redis
05a60462f8ba: nginx
fe9198c04d62: mongo
00285df0df87: <none>
f753707788c5: centos
f753707788c5: centos
1e0c3dd64ccd: centos
或者打算以表格等距显示,并且有标题行,和默认一样,不过自己定义列:
$ docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID REPOSITORY TAG
5f515359c7f8 redis latest
05a60462f8ba nginx latest
fe9198c04d62 mongo 3.2
00285df0df87 <none> <none>
f753707788c5 centos latest
f753707788c5 centos latest
1e0c3dd64ccd centos latest
Docker 1.13+
在 Docker 1.13+ 版本中推荐使用 docker image 来管理镜像。
$ docker image ls
操作 Docker 容器
是 Docker 又一核心概念。
简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
本章将具体介绍如何来管理一个容器,包括创建、启动和停止等。
Docker 在 1.13 版本中引进了新的管理命令(management commands),在 Docker 1.13+推荐使用docker container子命令来管理 Docker 容器。
启动容器
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。
所需要的命令主要为docker run。
例如,下面的命令输出一个 “Hello World”,之后终止容器。
$ docker run centos:latest /bin/echo 'Hello world'
Hello world
这跟在本地直接执行/bin/echo 'hello world'几乎感觉不出任何区别。
下面的命令则启动一个 bash 终端,允许用户进行交互。
$ docker run -it --name=test-centos docker.io/centos:latest /bin/bash
root@af8bae53bdd3:/#
说明option:
-t 让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,
-i 则让容器的标准输入保持打开。
-it 表示交互模式, 启动成功后进入命令行,同-i -t写法一样。
-d 表示守护模式, 容器在后台运行
--name 为容器命名
docker.io/centos:latest 格式为镜像名:版本
/bin/bash 进入bash命令行
在交互模式下,用户可以通过所创建的终端来输入命令,例如
root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
当利用docker run来创建容器时,Docker 在后台运行的标准操作包括:
检查本地是否存在指定的镜像,不存在就从公有仓库下载
利用镜像创建并启动一个容器
分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
从地址池配置一个 ip 地址给容器
执行用户指定的应用程序
执行完毕后容器被终止
注意:从终端拆除:crtl+p,ctrl+q 即可返回到宿主机,容器依然运行。
启动已终止容器
可以利用docker start命令,直接将一个已经终止的容器启动运行。
容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用ps或top来查看进程信息。
root@ba267838cc1b:/# ps
PID TTY TIME CMD
1 ? 00:00:00 bash
11 ? 00:00:00 ps
可见,容器中仅运行了指定的 bash 应用。这种特点使得 Docker 对资源的利用率极高。
Docker 1.13+
在 Docker 1.13+ 版本中推荐使用docker container来管理容器。
$ docker container run centos:latest /bin/echo 'Hello world'
$ docker container start
后台运行容器
更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d 参数来实现。
下面举两个例子来说明一下。
如果不使用 -d 参数运行容器。
$ docker run centos:latest /bin/sh -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
hello world
容器会把输出的结果 (STDOUT) 打印到宿主机上面
如果使用了 -d 参数运行容器。
$ docker run -d centos:latest /bin/sh -c "while true; do echo hello world; sleep 1; done"
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a
此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面(输出结果可以用docker logs 查看)。
注: 容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关。
使用 -d 参数启动后会返回一个唯一的 id,也可以通过 docker ps 命令来查看容器信息。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77b2dc01fe0f centos:latest /bin/sh -c 'while tr 2 minutes ago Up 1 minute agitated_wright
要获容器内部运行的命令从终端输出的信息,可以通过 docker logs 命令。
$ docker logs [container ID or NAMES]
hello world
hello world
hello world
. . .
Docker 1.13+
在 Docker 1.13+ 版本中推荐使用 docker container 来管理镜像。
$ docker container run -d
$ docker container ls
$ docker container logs
终止容器
可以使用 docker stop 来终止一个运行中的容器。
此外,当Docker容器中指定的应用终结时,容器也自动终止。
例如对于只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。
终止状态的容器可以用 docker ps -a 命令看到。例如
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba267838cc1b centos:latest "/bin/bash" 30 minutes ago Exited (0) About a minute ago trusting_newton
98e5efa7d997 training/webapp:latest "python app.py" About an hour ago Exited (0) 34 minutes ago backstabbing_pike
处于终止状态的容器,可以通过 docker start 命令来重新启动。此外, docker restart 命令会将一个运行态的容器终止,然后再重新启动它。
Docker 1.13+
在 Docker 1.13+ 版本中推荐使用 docker container 来管理容器。
$ docker container ls
$ docker container start
$ docker container restart
进入容器
在使用 -d 参数时,容器启动后会进入后台。
某些时候需要进入容器进行操作,包括使用docker attach命令或docker exec命令,推荐大家使用docker exec命令,原因会在下面说明。
attach 命令
docker attach 是 Docker 自带的命令。下面示例如何使用该命令。
$ docker run -dit centos
243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
243c32535da7 centos:latest "/bin/bash" 18 seconds ago Up 17 seconds nostalgic_hypatia
$ docker attach 243c32535da7
root@243c32535da7:/#
注意: 如果从这个 stdin 中 exit或crtl+d会导致容器的停止。为了保证容器依然运行,从终端拆除:crtl+p,ctrl+q 即可返回到宿主机。
exec命令
docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。
只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。
当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符
$ docker run -dit centos
69d137adef7a8a689cbcb059e94da5489d3cddd240ff675c640c8d96e84fe1f6
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
243c32535da7 centos:latest "/bin/bash" 18 seconds ago Up 17 seconds nostalgic_hypatia
$ docker exec -i 69d1 bash
ls
bin
boot
dev
...
$ docker exec -it 69d1 bash
root@69d137adef7a:/#
如果从这个 stdin 中 exit,不会导致容器的停止。这就是为什么推荐大家使用 docker exec 的原因。
更多参数说明请使用 docker exec --help 查看。
Docker 1.13+
在 Docker 1.13+ 版本中推荐使用 docker container 来管理容器。
$ docker container attach
$ docker container exec
导出和导入容器
导出容器
如果要导出本地某个容器,可以使用 docker export 命令。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7691a814370e centos:latest "/bin/bash" 36 hours ago Exited(0) 21 hours ago test
$ docker export 7691a814370e > centos.tar
这样将导出容器快照到本地文件。
导入容器快照
可以使用 docker import 从容器快照文件中再导入为镜像,例如
$ cat centos.tar | docker import - test/centos:v1.0
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test/centos v1.0 9d37a6082e97 About a minute ago 171.3MB
此外,也可以通过指定 URL 或者某个目录来导入,例如
$ docker import http://example.com/exampleimage.tgz example/imagere
注:用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 dockerimport 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
Docker 1.13+
在 Docker 1.13+ 版本中推荐使用 docker container 来管理容器
$ docker container export
$ docker image import
删除容器
可以使用 docker rm 来删除一个处于终止状态的容器。例如
$ docker rm trusting_newton
trusting_newton
如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器。
清理所有处于终止状态的容器
用 docker ps -a 命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。
$ docker container prune
Docker 1.13+
在 Docker 1.13+ 版本中推荐使用 docker container 来管理容器。
$ docker container rm trusting_newton
访问仓库
仓库(Repository)是集中存放镜像的地方。
一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址dl.dockerpool.com/centos 来说, dl.dockerpool.com 是注册服务器地址, centos 是仓库名。大部分时候,并不需要严格区分这两者的概念。
Docker Hub
目前 Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 15,000 的镜
像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
注册
你可以在 https://cloud.docker.com 免费注册一个 Docker 账号。
登录
可以通过执行 docker login 命令交互式的输入用户名及密码来完成在命令行界面登录Docker Hub。
docker login [OPTION] [SERVER]
option:
-u username
-p password
$ docker login -u wangjinhuai
Password:
Login Succeeded
$
通过 docker logout 退出登录。
拉取镜像
通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。
例如以 centos 为关键词进行搜索:
$ docker search centos
NAME DESCRIPTION
STARS OFFICIAL AUTOMATED
centos The official build of CentOS.
465 [OK]
tianon/centos CentOS 5 and 6, created using rinse in
stea... 28
blalor/centos Bare-bones base CentOS 6.5 image
6 [OK]
saltstack/centos-6-minimal
6 [OK]
tutum/centos-6.4 DEPRECATED. Use tutum/centos:6.4 inste
ad. ... 5 [OK]
下载官方 centos 镜像到本地。
$ docker pull centos
Pulling repository centos
0b443ba03958: Download complete
539c0211cd76: Download complete
511136ea3c5a: Download complete
7064731afe90: Download complete
推送镜像
用户也可以在登录后通过 docker push 命令来将自己的镜像推送到 Docker Hub。
以下命令中的 username 请替换为你的 Docker 账号用户名。
$ docker tag centos:latest username/centos:latest
$ docker images
REPOSITORY TAG IMAGE
ID CREATED SIZE
centos latest 275d79
972a86 6 days ago 94.6MB
username/centos latest 275d79
972a86 6 days ago 94.6MB
$ docker push wangjinhuai/centos:latest
$ docker search username
NAME DESCRIPTION STARS
OFFICIAL AUTOMATED
username/centos