第四章 Docker容器
1. 容器基础
1.1 容器启动流程
通过docker run
命令可以启动运行一个容器。该命令在执行时首先会在本地查找指定的镜像,如果找到了,则直接启动,否则会到镜像中心查找。如果镜像中心存在该镜像,则会下载到本地并启动,如果镜像中心也没有,则直接报错。
如果再与多架构镜像原理相整合,则就形成了完整的容器启动流程。
1.2 容器运行本质
Docker
容器存在的意义就是为了运行容器中的应用,对外提供服务,所以启动容器的目的就是启动运行该容器中的应用。容器中的应用运行完毕后,容器就会自动终止。所以,如果不想让容器启动后立即终止运行,则就需要使容器应用不能立即结束。通常采用的方式有两种,使应用处于与用户交互的状态或等待状态。
2. 容器创建并启动命令
对于容器的运行,有两种运行模式:交互模式与分离模式。下面通过运行ubuntu
与tomcat
来演示这两种运行模式的不同。
2.1 以交互模式运行ubuntu
--name
指定当前容器名称为myubuntu
-it
指定以交互模式运行容器,且为容器分配一个伪终端。- 后面的
/bin/bash
用于指定容器启动后需要运行的命令为/bin下的bash命令,而该命令会启动一个bash终端。
我们在这里运行了一个ubuntu
系统的容器,并为其取名为myubuntu
。另外我们可以注意到,命令行前面提示部分内容发生了变化:原来显示的是[root@node1~]
,而现在变为了root@be0af689d045:/#
,这个就是docker
生成的伪客户端,而数字be0af689d045
表示的是docker
容器的ID。
此时就可以通过Linux
命令对该ubuntu
系统进行操作了。不过,由于容器中的该系统是一个精简的系统,有很多常用命令是没有安装的,所以如果要使用这些命令,就需要安装。
2.2 以交互模式运行tomcat
通过ls –l
命令可查看tomcat
根目录下的文件。注意,不支持ll
命令。
下面也是以交互模式运行tomcat
容器,不同的是,该命令后没有/bin/bash
,此时会真正启动tomcat
。
-p
用于指定端口映射,格式为:暴露给宿主机的端口:容器中应用的端口
;回车后会发现tomcat已启动,且tomcat
的日志输出占居了命令行。
此时在Window
的浏览器中通过8081
端口可以访问到tomcat
。
2.3 以分离模式运行tomcat
下面是以分离模式运行的tomcat
,返回的是容器ID
。
-d
选项表示以分离模式(detached mode
)运行容器,即命令在后台运行,命令的运行与宿主机的运行分离开来。
可以看到,已经启动了三个tomcat
容器。且无论是IPv4
还是IPv6
,端口映射关系都很明确。此时通过window
系统中的浏览器访问docker
主机中映射的三个tomcat
端口号就可以访问到tomcat。
通过该访问可以知道为什么要做端口映射的原因了:为了使相同的客户端主机可以访问同一宿主机上相同端口号的不同容器。
2.4 以分离模式运行ubuntu
该运行方式存在一个问题:容器使用命令启动了,但通过docker ps
命令查看不到。
再通过docker ps –a
命令可以发现该容器,只不过其已经退出。docker ps
查看的就是up
状态的容器,由于其已经退出,所以docker ps
查看不到。
3. 容器创建命令
docker create
命令仅创建容器但不启动,其用法与docker run
非常相似。注意,其没有-d
选项。
4. 容器退出命令
退出容器指的是退出以交互模式运行的容器。分为两种退出方式:
4.1 退出并停止容器exit
在容器命令行中再运行exit
命令后,通过docker ps –a
可以查看到该容器已经退出了。
4.2 退出不停止容器Ctrl + P + Q
注:先按下
Ctrl + P
,然后再按下Q
。
使用快捷键Ctrl + P + Q
能够返回到了宿主机命令行。
再通过docker ps
可以查看到其是UP
状态,说明容器退出了但并没有停止。
5. 容器状态查看命令
5.1 查看所有正在运行的容器
docker ps
命令本身查看的是所有处于运行状态的容器信息。
5.2 查看所有容器
docker ps –a
用于查看所有容器,无论是否处于运行状态。
5.3 查看所有容器的ID
docker ps –q
用于查看所有处于运行状态的容器的ID。
docker ps –qa
用于查看所有容器的ID
5.4 查看最后创建的容器
docker ps –l
用于查看最后创建的容器,无论该容器是否处于运行状态。
5.5 查看最后创建的n个容器
docker ps –n 3
用于查看最后创建的指定个数的容器,无论该容器是否处于运行状态。
6. 容器再进命令
当我们以分离模式运行了一个容器,或以交互模式运行了一个容器,但容器内部执行的命令占用了交互命令行,而此时我们又想进入到容器中对容器内部进行一些操作,此时就需要用到exec/attach
命令了。
注意,它们只能对正在运行的容器进行操作。
6.1 新建进程进入容器exec
该命令也用于进入到了运行状态的容器中。
对于该命令的测试,首先以分离模式运行tomcat8
容器。此时想进入该mytomcat
容器,就可以使用exec命令。
此时执行exit
命令退出容器。
此时查看正在运行的容器,发现mytomcat
容器并未退出。说明exec
命令会创建一个新的独立于容器的进程,而exit
命令仅用于结束该新建进程。同样,以交互模式运行tomcat
容器,仍是无法使用命令行的,因为tomcat
日志输出占用了命令行。
此时若要使用命令行,可另外再打开一个新的Session窗口,然后再执行exec
命令,便可进入容器,打开容器中的命令行。
6.2 外部操作容器exec
前两种都是在进入到容器后才对容器进行操作的,我们也可以不进入容器直接对容器内部进行操作。例如仅想查看tomcat
容器中工作目录中所包含的文件,直接在exec
命令后紧跟要执行的命令即可直接看到其结果。
6.3 容器附加标准输入
对于该命令的测试,首先以交互方式运行一个ubuntu
容器,然后使用Ctrl + P + Q
命令退出但不停止容器。
然后使用attach
命令进入容器命令行。此时,再使用exit
命令退出容器。然后会发现容器也停止了。由于exit
命令的作用是,结束当前进程,所以说明attach
命令并没有另外再创建新的进程,而是使用了容器进程,exit命令退出了当前进程,也就退出了容器。
6.4 容器附加标准输出
启动一个tomcat
容器与其中的tomcat
,指定容器名称为mytom
。然后通过docker attach
命令则可看到如下场景:占用了命令行,且没有任何输出,即使通过浏览器访问该tomcat
也没有任何输出。此时的mytom
容器已经附加了标准输出,只不过,其输出的是tomcat
的启停日志信息。
通过Ctrl + C
可结束tomcat
,此时可看到停止日志显示了出来。但由于此时的tomcat
已经停止,tomcat
容器已经退出,所以该docker attach
命令也就随之结束了。
7. 容器内进程查看命令
docker top
命令用于查看指定的正在运行的容器中正在运行的进程详情,这个详情包括当前这个进程正在运行的命令。
当然,如果容器中运行的进程较多,也可以通过grep
对结果进行过滤。
8. 容器日志查看命令
docker logs [容器]
可以查看指定容器中应用的运行日志,无论该容器是运行还是停止状态。
8.1 查看所有日志
docker logs
查看的是所有容器中应用的运行日志。这个日志对于不同的容器来说,其日志内容是不同的。由docker run
命令的[command]
决定(如果没有则由Dockerfile
中的CMD
指令决定)。
对启动了tomcat
的tomcat
容器来说,这个日志是tomcat
启停日志。
对于没有启动tomcat
的tomcat
容器来说,这个日志是/bin/bash
的运行历史记录。
对于ubuntu
容器来说,这个日志是/bin/bash
的运行历史记录。
8.2 查看最后的日志
通过添加选项-n
或--tail
可以指定要显示的最后几条日志。
8.3 查看指定时间内的日志
通过添加选项--since
可以指定要显示自从指定时间以来的日志。这个时间可以是一个绝对时间,也可以是一个相对时长。下面使用的是绝对时间:显示自从2022年8月1日后产生日志的最后3条。
下面使用的是相对时长:显示自从30分钟之前产生日志中的最后3条。其中m表示分,可以使用s表示秒,h表示小时。
8.4 查看指定时间外的日志
通过添加选项--until
可以指定要显示截止到指定时间之前的日志。这个时间可以是一个绝对时间,也可以是一个相对时长。
下面使用的是绝对时间:显示截止到2022年8月8日前产生日志的最后3条。
下面使用的是相对时长:显示截止到5分钟之前产生日志中的最后3条。
8.5 查看日志时间戳
如果要查看某日志的详细时间戳,可以使用-t
选项。下面的命令查看的是最后3条日志的时间戳,并与不添加-t
的输出进行了对比。
8.6 查看动态日志
通过添加选项-f
可以查看运行中容器的动态日志。
以上命令用于查看mytomcat
的最后三条动态日志。其会占用命令行,一直等待日志的输出。
9. 容器启停命令
9.1 启动start
通过docker start
命令可以启动已经停止的指定容器,这个容器可以通过容器名称指定,也可以通过容器ID指定。
docker start 容器名称/容器ID指定
9.2 重启restart
通过docker restart
命令可以重启处于运行状态的指定容器。
docker restart 容器名称/容器ID指定
9.3 优雅停止stop
通过docker stop
命令可以优雅停止指定容器。所谓优雅停止是指,若当前容器正在被其它进程访问,则在访问结束后再停止。
docker stop 容器名称/容器ID指定
9.4 强制停止kill
通过docker kill
命令可以强制停止指定容器。所谓强制停止是指,无论容器当前是否被其它进程访问都直接停止。
docker kill 容器名称/容器ID指定
9.5 停止所有容器
无论是docker kill
还是docker stop
,都可使用下面方式停止所有容器。因为这两个命令的参数都可以是容器ID。
docker kill/stop $(docker ps -qa)
9.6 暂停pause
通过docker pause
命令可以暂停容器对外提供服务。
docker pause 容器名称/容器ID指定
9.7 解除暂停unpause
通过docker unpause
命令可解除容器的暂停服务状态。
docker unpause 容器名称/容器ID指定
10. 容器删除命令
10.1 容器删除命令
docker rm
命令在默认情况下,要删除的容器必须是已经停止的容器。当然,这个容器可以使用容器名或容器ID指定。
docker rm 容器名称/容器ID指定
10.2 强制删除
在docker rm
命令中添加-f
可实现强制删除容器。即,无论容器是否停止都会删除。
docker rm -f 容器名称/容器ID指定
10.3 删除所有容器
docker rm $(docker ps -qa)
11. 容器与宿主机文件传递
docker cp
命令可以完成容器与宿主机中文件/目录的相互复制,无论该容器是否处于运行状态。
以上命令是将mytomcat
容器的tomcat
中的webapps
目录复制到宿主机的当前目录,查看宿主机当前目录。
11.1 将宿主机文件复制到容器
以上命令用于将宿主机中当前目录下的software
文件复制到mytomcat
容器的/usr/local/tomcat
目录中。若要查看容器中是否已经存在了software
文件,需要首先启动该容器。
11.2 不支持容器间的cp
docker cp
命令不支持容器间的文件传递。
12. 提交容器为镜像
通过docker commit
命令可以将一个容器文件系统的当前快照生成为一个新的镜像。
需求:这里要在一个Ubuntu
容器或Centos
容器中安装net-tools
工具包。为了方便演示,这里选择CentOS
容器,直接使用yum
安装。当然,如果使用Ubuntu
容器也可以,要么直接使用apt-get
安装net-tools
,要么先安装yum
后再安装net-tools
。
12.1 修改容器层
首先创建并启动一个容器,例如centos:7
镜像的容器。然后发现该容器中是没有安装ifconfig
命令的。
安装net-tools
网络工具命令包。
此时再使用ifconfig,
已经可以使用了。
12.2 生成镜像
下面要将已经安装了ifconfig
命令的容器生成为一个镜像,以方便后期自己或他人使用。
这里指定生成的镜像的<repository>
为centos7
,<tag>
为net-tools
。
12.3 使用新镜像
下面是使用新生成的镜像创建并启动一个容器,发现其中的ifconfig
命令是可以使用的。
12.4 生成悬虚镜像
悬虚镜像,即没有<repository>
与<tag>
的镜像。悬虚镜像一般都是由于某些失误操作或其它一些操作而生成的副产物,一般是要被清除掉的。如果非要使用悬虚镜像,那只能通过其ImageID
来使用了。
下面要将已经安装了ifconfig
命令的容器生成为一个悬虚镜像,即没有指定<repository>
与<tag>
。
13. 导入/导出容器
在上一章中学习了docker save
与docker load
命令,分别用于导出/导入镜像。这里要学习的docker export
与docker import
命令分别用于导出/导入容器。
13.1 导出容器export
docker export
命令用于将一个容器的文件系统导出为tar
文件。例如,下面的命令是将tomcat:8.5.32
镜像的容器tom
导出到当前/root
目录的tomcat8.tar
文件中。
13.2 导入容器import
docker import
命令用于根据指定的tar
文件构建新的镜像。下面的命令是将当前目录下的tomcat8.tar
导出为镜像mytomcat:1.0
。
13.3 与save/load命令的对比
export与save
export
作用于容器,save
作用于镜像,但它们导出的结果都为tar
文件export
一次只能对一个容器进行导出,save
一次可以对多个镜像进行导出export
只是对当前容器的文件系统快照进行导出,其会丢弃原镜像的所有历史记录与元数据信息,save
则是保存了原镜像的完整记录
import与load
import
导入的是容器包,load
加载的是镜像包,但最终都会恢复为镜像import
恢复为的镜像只包含当前镜像一层,load
恢复的镜像与原镜像的分层是完全相同的import
恢复的镜像就是新构建的镜像,与原镜像的ImageID
不同;load
恢复的镜像与原镜像是同一个镜像,即ImageID
相同import
可以为导入的镜像指定<repository>
与<tag>
,load
加载的镜像不能指定<repository>
与<tag>
,与原镜像的相同
13.4 与docker commit的对比
- 相同点:
docker export
+docker import
会将一个容器变为一个镜像,docker commit
也可以将一个容器变一个镜像。 - 不同点:
docker export
+docker import
恢复的镜像仅包含原容器生成的一层分层,docker commit
生成的镜像中包含容器的原镜像的所有分层信息。
14. docker system命令集
docker system
是一个命令集,其有四个子命令。
14.2 查看docker磁盘占用数据
docker system df
用于查看docker
各部分占用情况。
如果要获取更为详细的占用情况,可添加-v
选项。
14.3 查看docker发生过的事件
docker system events
命令造价于docker events
命令,可查看指定日间之内(--since
)或之外(--until
)在docker
上所发生的所有事件。这些事件包含运行过的命令有docker
内部执行的一些操作。
14.4 查看docker详情
docker system info
命令等价于docker info
,用于查看当前docker
的详情。包括dockerClient
与docker Server
详情。其中docker server
包含镜像、容器情况,docker
所在系统的软硬件情况等。
14.5 删除docker中的无用数据
docker system prune
命令用于删除docker
中的无用数据,这些无用数据包含已经停止的容器、没有任何连接容器的网络、悬空镜像,及悬空镜像的构建缓存。