Linux:Docker 容器初体验
June 9, 2015
在本文中,我们将迈出使用Docker的第一步,学习第一个Docker容器。本章还会介绍如何与Docker进行交互的基本知识。
Table of Contents
1 确保Docker已经就绪
首先,我们会查看Docker是否能正常工作,然后学习基本的Docker的工作流:创建并管理容器。我们将浏览容器的典型生命周期:从创建、管理到停止,直到最终删除。
第一步,查看docker程序是否存在,功能是否正常,如代码清单3-1所示。
代码清单3-1 查看docker程序是否正常工作
$ sudo docker info Containers: 0 Images: 0 Storage Driver: aufs Root Dir: /var/lib/docker/aufs Dirs: 144 Execution Driver: native-0.1 Kernel Version: 3.8.0-29-generic Registry: [https://index.docker.io/v1/]
在这里我们调用了docker可执行程序的info命令,该命令会返回所有容器和镜像(镜像即是Docker用来构建容器的“构建块”)的数量、Docker使用的执行驱动和存储驱动(execution and storage driver),以及Docker的基本配置。
在前面几章我们已经介绍过,Docker是基于客户端-服务器构架的。它有一个docker程序,既能作为客户端,也可以作为服务器端。作为客户端时,docker程序向Docker守护进程发送请求(如请求返回守护进程自身的信息),然后再对返回来的请求结果进行处理。
2 运行我们的第一个容器
现在,让我们尝试启动第一个Docker容器。我们可以使用docker run命令创建容器,如代码清单3-2所示。docker run命令提供了Docker容器的创建到启动的功能,在本书中我们也会使用该命令来创建新容器。
代码清单3-2 创建第一个容器
$ sudo docker run -i -t ubuntu /bin/bash Pulling repository ubuntu from https://index.docker.io/v1 Pulling image 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c (precise) from ubuntu Pulling 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c metadata Pulling 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c fs layer Downloading 58337280/? (n/a) Pulling image b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc (quantal) from ubuntu Pulling image 27cf784147099545 () from ubuntu root@fcd78e1a3569:/#
{提示}官方文档列出了完整的Docker命令列表,你也可以使用docker help获取这些命令。此外,你还可以使用Docker的man页(即执行man docker-run)。
代码清单3-3所示命令的输出结果非常丰富,下面我们来逐条解析。
代码清单3-3 docker run命令
$ sudo docker run -i -t ubuntu /bin/bash
首先,我们告诉Docker执行docker run命令,并指定了-i和-t两个命令行参数。-i标志保证容器中STDIN是开启的,尽管我们并没有附着到容器中。持久的标准输入是交互式shell的“半边天”,-t标志则是另外“半边天”,它告诉Docker为要创建的容器分配一个伪tty终端。这样,新创建的容器才能提供一个交互式shell。若要在命令行下创建一个我们能与之进行交互的容器,而不是一个运行后台服务的容器,则这两个参数已经是最基本的参数了。
{提示}官方文档上列出了docker run命令的所有标志,此外还可以用命令docker help run查看这些标志。或者,也可以用Docker的man页(也就是执行man docker-run命令)。
接下来,我们告诉Docker基于什么镜像来创建容器,示例中使用的是ubuntu镜像。ubuntu镜像是一个常备镜像,也可以称为“基础”(base)镜像,它由Docker公司提供,保存在Docker HubRegistry上。
你可以用 ubuntu 基础镜像(以及类似的 fedora、debian、centos等镜像)为基础,在你选择的操作系统上构建自己的镜像。这里,我们基于此基础镜像启动了一个容器,并且没有对容器进行任何改动。
那么,在这一切的背后又都发生了什么呢?首先Docker会检查本地是否存在ubuntu镜像,如果本地还没有该镜像的话,那么Docker就会连接官方维护的Docker Hub Registry,查看Docker Hub中是否有该镜像。Docker一旦找到该镜像,就会下载该镜像并将其保存到本地宿主机中。
随后,Docker在文件系统内部用这个镜像创建了一个新容器。该容器拥有自己的网络、IP地址,以及一个用来和宿主机进行通信的桥接网络接口。最后,我们告诉Docker在新容器中要运行什么命令,在本例中我们在容器中运行/bin/bash命令启动了一个Bash shell。
当容器创建完毕之后,Docker就会执行容器中的/bin/bash命令,这时我们就可以看到容器内的shell了,就像代码清单3-4所示。
代码清单3-4 第一个容器的shell
root@f7cbdac22a02:/#
{注意}在第4章中,我们将会看到如何构建自己的镜像并基于该镜像创建容器的基础知识。
3 使用第一个容器
现在,我们已经以root用户登录到了新容器中,容器的IDf7cbdac22a02“,乍“看起来有些令人迷惑的字符串。这是一个完整的Ubuntu系统,你可以用它来做任何事情。下面我们就来研究一下这个容器。首先,我们可以获取该容器的主机名,如代码清单3-5所示。
代码清单3-5 检查容器的主机名
root@f7cbdac22a02:/# hostname f7cbdac22a02
可以看到,容器的主机名就是该容器的ID。我们再来看看/etc/hosts文件,如代码清单3-6所示。
代码清单3-6 检查容器的/etc/hosts文件
root@f7cbdac22a02:/# cat /etc/hosts 172.17.0.4 f7cbdac22a02 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters
Docker以在hosts文件中为该容器的IP地址添加了一条主机配置项。我们再来看看容器的网络配置情况,如代码清单3-7所示。
代码清单3-7 检查容器的接口
root@f7cbdac22a02:/# ip a 1: lo:mtu 1500 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 899: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 16:50:3a:b6:f2:cc brd ff:ff:ff:ff:ff:ff inet 172.17.0.4/16 scope global eth0 inet6 fe80::1450:3aff:feb6:f2cc/64 scope link valid_lft forever preferred_lft forever
我们可以看到,这里有lo的环回接口,还有IP为172.17.0.4的标准eth0网络接口,和普通宿主机是完全一样的。我们还可以查看容器中运行的进程,如代码清单3-8所示。
代码清单3-8 检查容器的进程
root@f7cbdac22a02:/# ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 18156 1936 ? Ss May30 0:00 /bin/bash root 21 0.0 0.0 15568 1100 ? R+ 02:38 0:00 ps -aux
接下来我们要干些什么呢?安装一个软件包怎么样?如代码清单3-9所示。
代码清单3-9 在第一个容器中安装软件包
root@f7cbdac22a02:/# apt-get update && apt-get install vim
通过上述命令,我们就在容器中安装了Vim软件。
你可以继续在容器中做任何自己想做的事情。当所有工作都结束时,输入exit,就可以返回到Ubuntu宿主机的命令行提示符了。
这个容器现在怎样了?容器现在已经停止运行了!只有在指定的/bin/bash命令处于运行状态的时候,我们容器也才会相应地处于运行状态。一旦退出容器,/bin/bash命令也就结束了,这时容器也随之停止了运行。
但容器仍然是存在的,我们可以用docker ps -a命令查看当前系统中容器的列表
默认情况下,当执行docker ps命令时,只能看到正在运行的容器。如果指定-a标志,选项的话,那么docker ps命令会列出所有容器,包括正在运行的和已经停止的。
{提示}你也可以为docker ps命令指定-l标志,该选项会列出最后一次运行的容器,包括正在运行和已经停止的。
从该命令的输出结果中我们可以看到关于这个容器的很多有用信息:ID、用于创建该容器的镜像、容器最后执行的命令、创建时间以及容器的退出状态(在上面的例子中,退出状态是0,因为容器是通过正常的exit命令退出的)。我们还可以看到,每个容器都有一个名称。
{注意}有三种方式可以指代唯一容器:短UUID(如f7cbdac22a02)、长UUID(如f7cbdac22a02e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778)或者名称(如gray_cat)。
0 Comments