上一章我们简单介绍了Docker的作用,简单介绍了Docker image/contianer/repository的概念(等学完基本的流程就会发现Docker用起来就像GitHub差不多)。这一章,我们主要介绍如何运用Docker的基本命令来查看Docker状态,运行容器等等内容。
从Hello-world镜像开始
上一章的Docker中,我们介绍了如何使用run
命令将image
创建生成一个容器并运行。在此期间,Docker都做了这些工作:
浅谈Docker的运行原理
Docker是一个C/S架构的系统,Docker-daemon守护进程运行在主机上,然后通过Socket和客户端进行进行TCP通讯。
容器,是一个运行时环境,正是我们之前所比喻的集装箱。可以发现,当我们执行下面的命令时,Docker的启动几乎是秒级别的:
$ systemctl start docker
但我们如果要在VM ware中启动一个CentOS 7虚拟机,可能就需要等待1~2分钟了。造成这种现象的原因是:
1、 Docker有比虚拟机更少的抽象层,Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的实际物理机的硬件资源,因此在CPU,内存利用率上Docker有明显的优势。
2、 Docker利用的是宿主机的内核,而不需要另行启动一个OS。因此新建一个Docker容器只需要几秒钟。
下面列出一个表单来直观感受虚拟容器和虚拟机的区别:
Docker容器 | 虚拟机(VM) | |
---|---|---|
操作系统 | 与宿主机共享OS | 独立的虚拟OS |
存储大小 | 镜像小,便于存储 | 镜像庞大 |
运行性能 | 无额外性能损失 | 额外的CPU,内存开支 |
移植性 | 轻便,灵活,适用于Linux | 笨重,与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发 | 面向硬件运维 |
部署速度 | 快速,秒级别 | 较慢,10s以上 |
Docker常用命令
帮助命令
打印Docker版本
$ docker version
打印Docker内部详细信息
$ docker info
输出Docker的常用命令
$ docker --help
# Docker命令的格式= >Usage: docker [OPTIONS] COMMAND
镜像命令
images命令
$ docker images [Options]
给出各个列的说明:
列名 | 含义 |
---|---|
REPOSITORY | 表示镜像的仓库源 |
TAG | 镜像的标签(版本号) |
IMAGE ID | 镜像的ID号 |
CREATED | 镜像的创建时间 |
SIZE | 镜像的大小 |
同一个image允许有多个TAG,代表不同的版本。我们使用REPOSITORY:TAG
来定义不同的镜像。
如果不指定一个镜像的版本标签,默认使用latest镜像(即使用最新的镜像)。
[Options]
可选参数中包含了:
参数 | 含义 |
---|---|
-a | 列出本地所有的镜像 |
-q | 只显示镜像ID |
–digests | 只显示镜像的摘要信息 |
–no-trunc | 显示完整的镜像信息 |
每个镜像实际上是由层层的镜像叠加而成,我们所看到的镜像是暴露在最外层的那个镜像。具体内容可以参照下一章对UnionFS的简要介绍。
search命令
该命令从https://hub.docker.com中查询镜像。再次强调,仓库是存放镜像的地方。
$ docker search [Options] ${image}
该命令返回的结果与在官网中的search查询是一致的:
[Options]
可选参数中包含了:
参数 | 作用 |
---|---|
–filter=stars=n |
仅显示star数量大于等于n 的镜像 |
–no-trunc | 打印镜像完整的摘要信息 |
–automated | 只列出automated build类型的镜像 |
pull命令
从远端仓库(配置的阿里云镜像)中下载镜像。
$ docker pull ${image}
当镜像名没有标签备注时,默认下载该镜像的最新版。比如说我们从阿里云镜像中下载一个tomcat镜像:
$ docker pull tomcat
注意两个细节:
1、 Docker引擎下载的并不是一个镜像,而是多个镜像。
2、 仅一个tomcat镜像的大小竟然达到了600MB!
既然Docker有pull命令,那一定还有push,commit命令(就像Git那样),我们在之后的案例中会讲解它们。
rmi命令
rmi
命令用于删除本地中的指定镜像,注意和后续的rm
命令区分。
$ docker rmi [-f] ${image1} ${images2} ...
当镜像名没有标签备注时,默认删除该镜像的最新版。
注意,不能删掉本地容器(无论是开启还是关闭状态)所依赖的镜像。此时,要带上-f
参数,表示强制删除。
如果要删除多个镜像,直接在rmi
后面罗列即可。
如果要一键删除本地内所有的镜像,则需要使用以下组合命令:
$ docker rmi -f $(docker images -qa)
原理就是首先使用images
命令打印出所有本地的镜像ID,然后将这些ID全部作为参数放入到rmi
命令当中。
容器命令[基础]
在调用容器之前,我们先从镜像中获取一个centos镜像。
$ docker pull centos
$ docker run centos
run命令
我们之前已经使用run命令根据镜像新生成一个容器实例了。下面给出完整的run命令格式:
$ docker run [Options] ${image} [Command] [Args..]
[Options]
可选参数中包含了:
参数 | 作用 |
---|---|
–name | 为容器指定一个别称。 |
-d | 后台运行容器,并返回容器ID。 |
-i | 交互模式运行容器,通常和-t一同使用。 |
-t | 为容器分配一个伪输入终端,通常与-i一同使用。 |
-P | 随机端口映射。 |
-p | 指定端口映射。 |
其中,-p
参数的指定端口映射包含了以下格式:
ip::hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
接下来,我们在Docker引擎上,启动交互式centOS容器:
$ docker run -it centos
而通常,我们启动时还会加上一个别名(推荐该做法):
$ docker run -it centos --name vcentos
如果不指定通过--name
指定名称,Docker仍然会默认分配一个名字。
ps命令
Docker引擎也使用ps来查看目前正在运行中的容器。
$ docker ps
[Options]
可选参数中包含了:
参数 | 作用 |
---|---|
-a | 显示正在运行和历史运行过的容器。 |
-l | 显示上一次运行的容器。 |
-n m |
显示上m 次运行的容器。 |
-q | 只显示容器的ID。 |
–no-trunc | 不截断输出,显示完整信息。 |
注意,容器的ID和其依赖镜像的ID是相互独立的。
容器内部退出命令
若要在正在运行的容器内部,停止并退出,则:
$ docker exit
若不停止容器并退出,则按键:Ctrl + P + Q。
注意,一个容器一旦创建,它就会一直存在于这个Docker中。容器在被创建之后可以随时开启关闭。
当一个容器被废弃时,可以执行命令将其删掉。
在外部停止容器
停止容器有两种方法,第一种方式为:
$ docker stop ${containerID | containerName}
该方式会缓慢关闭容器内正在运行的进程,然后再关闭容器。
第二种方式为:
$ docker kill ${containerId | containerName}
该方式会以强制方式直接关闭容器。
重启被关闭的容器
若要重启被关闭且没有被删除的容器,则:
$ docker start ${containerID | containerName}
注意,前提是该容器仍然处于运行状态,可以通过容器ID,也可以通过容器的containerName。
启动成功之后,会返回启动的containerID,但不会进入到该容器之内。
另外,想要在容器中在运行时重新启动(通常是某些配置发生改变的情况),则使用restart
命令。
$ docker restart ${containerID | containerName}
重新进入仍然运行中的容器
$ docker attach ${containerID | containerName}
在外部直接操作容器
$ docker exec ${containerID | containerName} ${shell}
比如说,在宿主机(指虚拟机)中直接查看vcentos
容器内/root
目录内容。
$ docker exec vcentos ls -l /root
它会直接将vcentos
虚拟容器内的/root
目录内容打印出来,而不用先attach
进虚拟容器内再去执行命令。
下面的命令和attach
命令等效:
$ docker exec ${containerID | containerName} /bin/bash
rm命令
注意,rmi
命令用于删除镜像,rm
用于删除容器。
$ docker rm [-f] ${containerID | containerName}
同样,我们也可以通过命令组合的方式来实现删除所有的容器:
$ docker rm -f $(docker -aq)
#或者通过xrags管道符方式:
$ docker ps -a -q | xrags docker rm
容器命令的补充
关于run -d
当我们尝试以守护模式启动一个新的centos容器时,命令返回它的containerID,但是无法通过docker ps
命令查看到该容器,这是由于Docker内部的机制决定的:
Docker容器想要在后台运行,它内部一定需要有一个前台进程。或者说,如果容器内部没有执行会一直保持阻塞(挂起)的命令,则这个容器会被自动关闭。
为了观察现象,如果我们在这个容器启动时执行一个阻塞命令:
$ docker -d --name v_centos centos \
/bin/bash -c "while true;do echo hello;sleep 2;done"
此时再执行docker ps
,就会发现这个容器由于一直在阻塞式地执行echo
命令,因此没有被Docker引擎关闭。
注意,不要通过attach到以守护模式启动且被阻塞的容器中去,否则会无法返回。
查看容器日志
$ docker logs -f -t -tail ${count} ${containerID | containerName}
参数解释:
参数 | 作用 |
---|---|
-t | 加入时间戳 |
-f | 阻塞状态不断打印产生的日志 |
–tail count |
显示最新的count 条日志 |
查看容器内运行的进程
$ docker top ${containerID | containerName}
以json形式查看容器内部的细节
$ docker inspect ${containerID | containerName}
我们在之后介绍这个命令的用法。
容器与宿主机的文件互传
注:这里的“宿主机”指代运行Docker引擎的虚拟机。
#将容器内的文件传输到宿主机
$ docker cp ${container}:${Path} ${localPath}
#将宿主机内的文件传输给容器
$ docker cp ${localPath} ${container}:${Path}
其中,${Path}
为容器内的文件路径,而${localPath}
代表宿主机内的路径。即使容器目前处于关闭状态,只要路径正确,这条命令同样能够正常执行。