Docker:容器
- 容器
- 容器命令
- docker ps
- docker create
- docker start
- docker run
- docker logs
- docker exec
- docker stop
- docker restart
- docekr rm
- docker kill
- docker pause
- docker unpause
- docker commit
- docker cp
- docker diff
- docker export
- docker import
- docker rename
- docker stats
- docker top
- docker port
- docker update
- docker container inspect
- docker container prune
- 容器模式
- attach
- deatached
- interactive
容器
Docker
的核心功能,是基于容器化技术提供的环境隔离以及资源控制,容器就是一个个具体的隔离环境。当用户把镜像拉取到本地后,就可以使用镜像实例化出一个具体的容器,随后在容器内部进行操作。
如图,当容器实例化完成时,会在镜像上面添加一个容器层,容器在容器层内部进行操作,不会影响镜像层。当一个镜像实例化出多个容器,所有容器共用镜像层。
容器命令
docker ps
- 功能:查看已经实例化的容器
语法:
docker ps [option]
选项 :
-a
:显示所有容器,包括未运行的-n
:显示最近创建的n个容器
docker create
- 功能:创建一个容器,但是不启动
语法:
docker create [option] image [command]
选项:
-i
:以交互模式运行-t
:为容器重新分配一个伪终端-P
:随机端口映射-p
:指定端口映射,格式:-p 宿主机端口:容器端口
--name
:为容器指定一个名称-e
:设置环境变量--cpuset-cpus
:指定容器可以使用的CPU核-m
:指定容器允许使用的内存最大值--network
:指定容器网络类型--volume -v
:绑定一个存储卷--rm
:在shell
退出时,自动删除容器--restart
:容器崩溃时,自动重启
创建一个nginx
容器:
可以通过docker ps -a
查看容器,由于容器还没有启动,要加上-a
。
这里参数比较多,在docker run
部分讲解。
docker start
- 功能:启动一个暂停的容器
语法:
docker start [option] container [container ...]
其可以一次启动多个容器,只需要把容器名或者容器ID追加到指令末尾即可。
启动刚才创建的容器:
此时不再需要-a
选项,就可以查看到容器,并且容器获得了一个端口号80
。
docker run
- 功能:创建一个新的容器并运行
语法:
docker run [option] image [command]
选项:
-i
:以交互模式运行-t
:为容器重新分配一个伪终端-P
:随机端口映射-p
:指定端口映射,格式:-p 宿主机端口:容器端口
--name
:为容器指定一个名称-e
:设置环境变量--cpuset-cpus
:指定容器可以使用的CPU核-m
:指定容器允许使用的内存最大值--network
:指定容器网络类型--volume -v
:绑定一个存储卷--rm
:在shell
退出时,自动删除容器--restart
:容器崩溃时,自动重启-d
:后台运行容器
docker run
是docker create
和docker start
的结合体,同时完成创建容器和启动容器的过程。并且docker run
的选项和docker create
高度重合,功能也是一致的,只多出一个-d
选项。
首先是交互界面,常常使用-it
配合完成,使用-i
选项后,容器会读取输入流,解析用户从键盘输入的指令,但是不会返回结果。而-t
选项会创建一个伪终端,这个终端会返回容器内指令的输出结果。
创建一个centos
容器:
一开始,宿主机的版本是Ubuntu 24.04
,随后通过docker run
创建并运行容器,并且使用-it
选项进入容器终端。进入容器终端后,发现当前操作系统的版本已经变成了CentOS
。
最后通过exit
命令退出容器终端。可以看出,容器确实可以在一个操作系统上运行另一个操作系统,实现隔离。
直接运行一个nginx
容器:
运行后,发现进入了一个奇怪的终端,这些内容其实是nginx
的日志文件,因为没有指定-it
选项,所以没有进入一个可操作的终端,此时可以通过ctrl+ c
终止容器并退出。
对于这种情况,也可以使用-d
直接让其在后台运行:
这样就不会出现刚才的日志终端了。另外的,此处还指定了一个-P
选项,这代表随机端口映射。nginx
使用80
端口进行服务,但是最后还是要宿主机的端口与外界通信,此时就要存在一个宿主机与容器端口的映射关系,宿主机接收到来自32769
端口的所有数据,都交给容器内部的80
端口处理。
从容器往外看,就好像是自己收到了来自80
端口的数据。此处的-P
,是随机指定端口,也就是说32769->80
是操作系统随机指派的,如果想要自己指定,需要用-p
选项。
此处test5
容器指定了端口映射6666:80
,此后宿主机就会把来自6666
端口的消息,转发到容器内的80
端口处理。
通过curl
测试本机6666
端口:
此时返回了一个nginx
的html
页面,说明nginx
服务启动成功了,也说明6666
端口的消息,确实会被转发到容器内进行处理。
docker
还可以对容器进行资源的限制,其中--cpuset-cpus
控制容器可以使用的CPU核:
比如此处--cpuset-cpus "0,1"
表示这个容器,只能使用两个CPU核,分别是0 1
。也可以指定范围--cpuset-cpus "0-5"
,表示可以使用0 1 2 3 4 5
这六个核。
再往后的一些参数,比如network
,volumn
这些内容,会在其他博客专门讲解。
docker logs
- 功能:查看容器日志
语法:
docker logs [option] container
选项:
-f
:跟踪输出日志-n
:仅列出最近n
条日志
查看nginx
容器的日志:
如果往回看,会发现这和docker run
时没有加-it -d
选项时,输出的内容一样,其实这就是nginx
日志,其包含了nginx
从创建开始的所有信息。
docker exec
- 功能:在容器中执行命令
语法:
docker exec [option] container command [arg...]
command
:要执行的命令arg
:执行命令的参数
参数:
-d
:在后台运行-i
:以交互模式运行-t
:为容器分配一个伪终端-e
:设置环境变量-u --user
:指定用户-w --workdir
:指定工作目录
如果需要在容器内部执行命令,就需要使用exec
选项来执行命令。
查看容器内部nginx
版本:
通过exec
在容器test9
内执行nginx -version
得到nginx
的版本号。在这之前在宿主机执行同样的命令,发现宿主机没有安装nginx
,说明这个命令确实是进入容器内部执行了。
在docker run
的时候,可以通过-it
选项进入容器自由操作。exec
也可以做到,在容器启动后进入容器。
进入nginx
容器:
此处-it
要配合bash
一起使用,表示进入容器并执行bash
进程,这样才会分配终端,否则无法进入容器。
默认进入容器,是处于根目录的,如果想要在进入容器时处于指定目录,或者说执行指令时处于某条路径,就需要-w
选项。
这样一进入容器,就是指定的目录。
如果在容器内部,有多个用户的话,还可以通过-u
指定操作的用户。
docker stop
- 功能:停止运行的容器
语法:
docker stop [option] container [container...]
参数:
-s
:发送的信号
docker stop
可以停止正在运行的容器。
停止的容器,可以通过docker ps -a
查看:
查看test9
的日志:
可以看到,这个容器收到了信号3 SIGQUIT
导致退出,可以使用-s
选项。
对于docker stop
,其默认使用SIGTERM
信号进行关闭容器,如果超出一定时间还没有关闭容器,那么发送SIGQIT
强制退出。
docker stop
的关闭方式比较柔和,会给容器一定时间进行资源的保存,日志中也可以看到gracefully shutting down
,表示优雅地退出。
docker restart
- 功能:重启容器
语法:
docker restart [option] container [container...]
只需要指定容器名或者容器ID,就可以把暂停的容器重新启动。
docekr rm
- 功能:删除停止的容器
语法:
docker rm[option] container [container...]
选项:
-f
:强制删除一个运行中的容器
默认情况下,docker rm
只能删除已经停止的容器,如果容器正在运行,那么不允许删除。
test8
是暂停的容器,成功删除了,但是test9
正在运行,删除失败。
此时可以通过-f
选项强制删除正在运行的容器。
docker kill
- 功能:强制停止运行的容器
语法:
docker kill [option] container [container...]
参数:
-s
:发送的信号
docker kill
可以停止正在运行的容器,其和docker stop
的功能是一样的,但是docker kill
是更加激进的做法。
这里重启了一个test6
容器,并用docker kill
杀掉,再查看日志。奇怪的事情是,输出日志中没有退出信息,反而是一些重启的信息,难道没有杀掉吗?
其实不是的,docker kill
直接给容器发送SIGQUIT
信号,导致容器直接退出,根本来不及写日志。相反的docker stop
退出时,容器不仅有时间回收资源,保存信息,还可以顺手写一个日志。
docker pause
- 功能:暂停容器内部的所有进程
语法:
docker pause container [container...]
此处的pause
与stop
和kill
不同,后两者是直接关掉容器,而这个pause
只暂停容器内部的进程,容易不会被关闭。
创建一个redis
容器:
进行5555:6379
的端口映射,此时就可以通过5555
端口访问到容器中的reids
。
暂停容器:
此时再访问redis
客户端,陷入了阻塞,因为虽然容器依然启动着,但是容器内部的redis
进程已经停止了。
docker unpause
- 功能:恢复容器内部暂停的所有进程
语法:
docker unpause container [container...]
docker commit
- 功能:将容器提交为一个镜像
语法:
docker commit [option] container [image[:tag]]
选项:
-a
:备注提交镜像的作者-c
:使用Dockerfile
创建镜像-m
:备注
创建一个centos
为基础的镜像:
首先创建了一个cantos
容器,随后在容器内部写一个log.txt
文件,退出后把这个容器提交为镜像。
镜像的备注为centos with log
,作者是myself
,镜像名称是test
并且标签为v1.0
。
此时查看镜像,就多出了一个test
镜像,并且test
和centos
两个镜像的大小都是231m
,因为创建的那个log.txt
太小了,所以看上去两者一样大。
查看镜像信息:
此时Comment
内部就是备注,Author
是作者。
docker cp
- 功能:在容器和宿主机之间拷贝文件
语法:
docker cp [option] [container:]src_path [container:]dest_path
此处container:
表示这个路径在容器中,如果不带这个说明是宿主机的路径。
首先创建一个nginx
容器,在容器内部创建一个nginx.txt
文件,退出容器回到宿主机。先通过docker cp test12:/nginx.txt ./
,把容器内部的文件拷贝到宿主机。这样宿主机中就得到了从容器内部的文件。
再在宿主机创建一个ubuntu.txt
,通过docker cp ./ubuntu.txt test12:/
拷贝到容器内部,让容器执行ls /
时,就多出了拷贝过去的新文件。
docker diff
- 功能:检查容器文件结构的更改
语法:
docker diff container
尝试检查刚才的test12
文件:
每一行的前缀,A
表示add
添加文件,C
表示cancel
删除文件。其中就包含A /ubuntu.txt
和A nginx.txt
,表示添加了这两个文件,其它的都是nginx
容器启动时的一些相关文件。
docker export
- 功能:导出容器为一个压缩包
语法:
docker export [option] container
选项:
-o
:将导出到指定文件
把test12
容器打包:
docker import
- 功能:从压缩包中创建镜像
语法:
docker import [option] file [image[:tag]]
选项:
-m
:备注
导入刚才的test.tar
:
这样就可以拿到镜像了。
这里的导入导出流程是:容器 -> 压缩包 -> 镜像
,一般用于直接把容器内容打包传递给其它主机时使用,其他主机拿到镜像后,就可以实例化出一样的容器。
docker rename
- 功能:重命名容器
语法:
docker rename container newname
docker stats
- 功能:显示容器资源的使用情况
语法:
docker stats [option] [container...]
选项:
-a
:显示所有容器,包括未运行的容器--no-stream
:显示当前情况后直接退出--no-trunc
:不截断输出
直接执行docker stats
:
此时显示所有正在运行的容器的情况,并且每秒钟都会刷新一次,如果只希望输出一次,加上--no-stream
选项。
docker top
- 功能:查看容器内部的进程信息
语法:
docker top container [option]
选项:
相当于Linux
的ps
命令,只要是ps
可以使用的参数,都可以作为docker top
的参数。
查看test12
容器内部的进程:
在test12
内部运行了三个进程,此处的参数-aux
,就是ps -aux
的参数。
docker port
- 功能:查看容器的端口映射
语法:
docker port container [option]
查看test9
的端口映射:
docker update
- 功能:更新容器配置
语法:
docker update [option] container
选项:
--cpus
:CPU的数量--cpuset-cpus
:允许使用哪些CPU的核-m
:内存限制
docker container inspect
- 功能:查看容器的详细信息
语法:
docker container inspect
查看test9
的详细信息:
此时可以看到test9
容器的一些内容,比如当前运行状态,创建时间,是否重启等等。
此处使用的命令是docker inspect
,而不是docker container inspect
。
还有一个命令docker image inspect
,它和docker container inspect
都可以简写为docker inspect
,此时docker
会自动识别目标是一个容器还是镜像。
docker container prune
- 功能:删除所有已经停止的容器
语法:
docker container prune [option]
选项:
-f
:不再进行确认
删除当前已经停止的容器:
首先通过ps -a
查询,此时可以看到很多已经停止的容器,执行docker container prune
后,进行了一次确认[y/N]
,如果不想询问可以加上-f
选项,随后已经停止的容器就被删除了。
容器模式
attach
当运行容器时,docker run
不加-it
或者-d
选项,会进入attach
模式。
创建一个nginx
容器:
这个情况之前已经讲解过,此时终端会一直阻塞,并且会输出容器的日志信息,这种模式称为attach
模式。这种模式下,可以通过ctrl + c
终止,但是容器也会一起退出,开发环境是不会使用这个模式的,就算要看日志,也可以通过docker log
。
deatached
当使用-d
或者--detach
选项,让容器在后台运行,称为detached
模式。
创建一个后台nginx
容器:
这种模式下,容器会一直运行,不会因为一个ctrl + c
就退出。如果想要进入容器执行命令,可以通过docker exec
命令。
interactive
当创建好一个容器后,可能需要进入容器内部进行复杂的操作,此时docker exec
用起来就很麻烦。
为此,可以使用docker exec -it ... bash
的组合,此时就可以进入容器内部,通过bash
终端操作容器,此时称为interactive
模式。
如果想要退出这个终端,输入exit
即可,但是不能输入ctrl + c
,否则容器也会退出。