Docker 常用命令
# 30.Docker 常用命令
介绍下 Docker 常用命令
# 帮助启动类命令
启动 docker: systemctl start docker
停止 docker: systemctl stop docker
重启 docker: systemctl restart docker
查看 docker 状态:systemctl status docker
开机自启: systemctl enable docker
查看 docker 概要信息:docker info
查看 docker 总体帮助文档: docker --help
查看 docker 命令帮助文档: docker 具体命令 --help
docker --help
会列出全部的命令,(部分)输出如下:
# docker --help
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Common Commands:
run Create and run a new container from an image
exec Execute a command in a running container
ps List containers
build Build an image from a Dockerfile
pull Download an image from a registry
push Upload an image to a registry
images List images
login Log in to a registry
logout Log out from a registry
search Search Docker Hub for images
version Show the Docker version information
info Display system-wide information
.................
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
docker 具体命令 --help
则可以查看某个命令的帮助文档(类似 Linux 下的 man 命令),例如看 pull 命令:
$ docker pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Download an image from a registry
Aliases:
docker image pull, docker pull
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--platform string Set platform if server is multi-platform capable
-q, --quiet Suppress verbose output
2
3
4
5
6
7
8
9
10
11
12
13
14
# 镜像命令
# 查看本地镜像
docker images:可以列出本地主机上的镜像。运行结果:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 9c7a54a9a43c 3 months ago 13.3kB
2
3
各个字段的说明:
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的版本号(例如 MySQL 有版本 5,版本 7)
- IMAGE ID:镜像 ID(类似数据库主键,不会重复)
- CREATED:镜像创建时间
- SIZE:镜像大小
同一仓库源可以有多个版本,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG
来定义不同的镜像。如果不指定一个镜像的版本标签,例如只使用 Redis,默认最新版,例如 Redis:latest
docker images 可以带两个参数:
- -a:列出本地所有的镜像(含历史映像层,后续会说)
- -q:只显示镜像 ID
docker images 后面还可以带镜像的名字,表明要查看某个镜像的信息(支持正则表达式)
$ docker images hello-world
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 23 months ago 13.3kB
$ docker images hello*
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 23 months ago 13.3kB
2
3
4
5
6
7
# 搜索镜像
格式:docker search 镜像名字
例如搜索 Redis:
$ docker search redis
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
redis Redis is an open source key-value store.. 12309 [OK]
redislabs/redisearch Redis With the RedisSearch module pre.... 57
............
2
3
4
5
name:镜像名字
DESCRIPTION:镜像的一些说明
STARS:该镜像的点赞数(例如 GitHub 项目也有点赞数)
OFFICIAL:是否经过了官方认证
AUTOMATED:是否为自动构建的(暂时不表)
和在 hub.docker.com (opens new window) 搜索是一样的:
该命令可选参数:
--limit : 只列出 N 个镜像(默认 25 个),例如 docker search --limit 5 redis
# 下载镜像
该命令可以下载镜像到本地,格式:docker pull 镜像名字
注意,我们没用指定用什么版本(TAG),因此默认是最新版,该命令等价于 docker pull 镜像名字:latest
例如下载两个版本的 Redis:
$ docker pull redis
Using default tag: latest
......
$ docker pull redis:6.0.8
6.0.8: Pulling from library/redis
....
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 9c7a54a9a43c 3 months ago 13.3kB
redis latest 7614ae9453d1 20 months ago 113MB
redis 6.0.8 16ecd2772934 2 years ago 104MB
2
3
4
5
6
7
8
9
10
11
12
13
# 查看占用空间
docker system df
:查看镜像/容器/数据卷所占的空间。至于什么是数据卷,后续再说
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 3 1 216.9MB 216.9MB (99%)
Containers 1 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
2
3
4
5
6
ps:Linux 下也有 df 命令,也是看磁盘空间的
# 删除镜像
docker rmi
可以用来删除镜像。
删除某个镜像:docker rmi 镜像ID
,或者 docker rmi 镜像名
。例如 docker rmi hello-world
删除多个镜像:docker rmi -f 镜像名1:TAG 镜像名2:TAG
(也可以用镜像 ID)
删除全部(慎用):docker rmi -f $(docker images -qa)
注:先找出所有镜像 ID,然后作为参数传递给 docker rmi -f
,这是 Linux 的命令行知识
注意,如果某个镜像之前被使用过,删除是会报错的:
$ docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container e3d569c1f07a is using its referenced image 9c7a54a9a43c
2
此时可以强制删除:
$ docker rmi -f hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:dcba6daec718f547568c562956fa47e1b03673dd010fe6ee58ca806767031d1c
Deleted: sha256:9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 7614ae9453d1 20 months ago 113MB
redis 6.0.8 16ecd2772934 2 years ago 104MB
2
3
4
5
6
7
8
9
# 面试题:谈谈 docker 虚悬镜像是什么?
仓库名、标签都是 <none>
的镜像,俗称虚悬镜像(dangling image)
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> ba6acccedd29 22 months ago 72.8MB
2
3
一般没什么用,建议删除。后续 Dockerfile 章节再介绍
# 容器命令
有镜像才能创建容器, 这是根本前提(因为 Centos 比较大,这里下载 Ubuntu 镜像)
$ docker pull ubuntu
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest ba6acccedd29 22 months ago 72.8MB
2
3
4
5
6
# 新建 + 启动容器
命令格式
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
常用 OPTIONS 说明(注意有些是一个减号开头,有些是两个减号开头):
-
--name="容器新名字"
:为容器指定一个名称; -
-d
:后台运行容器并返回容器 ID,也即启动守护式容器(后台运行); -
-i
:以交互模式(interactive)运行容器,通常与 -t 同时使用; -
-t
:为容器重新分配一个伪输入终端(tty),通常与-i
同时使用。也即启动交互式容器(前台有伪终端,等待交互); -
-P
(大写 P):随机端口映射。可以在启动后通过 docker ps 查看分配的端口 -
-p
(小写 p):指定端口映射
这里说下端口映射的概念:比如现在是 Docker 内的容器,运行了 Redis;那么外界想要通信这个 Redis,首先得找到这个 Docker 监听的端口(假设是 6379),然后再由 Docker 转发给这个容器内的端口
参数 | 说明 |
---|---|
-p hostPort:containerPort | 端口映射 -p:8080:80 |
-p ip:hostPort:containerPort | 配置监听地址 -p 10.0.0.100:8080:80 |
-p ip::containerPort | 随机分配端口 -p 10.0.0.100::80 |
-p hostPort:containerPort:网络协议 | 指定协议 -p 8080:80:tcp |
-p 81:80 -p 443:443 | 指定多个端口映射 |
交互式容器的概念:比如用 Docker 启动了一个操作系统 Ubuntu,那么得用一个终端能连接上该 Ubuntu,这样才能操作;示例:
[root@10 peterjxl]# docker run -it ubuntu /bin/bash
root@6f47c5c0dee0:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 1 01:42 pts/0 00:00:00 /bin/bash
root 9 1 0 01:42 pts/0 00:00:00 ps -ef
root@6f47c5c0dee0:/# ls
bin boot dev etc home lib lib32 lib64 libx32 media
2
3
4
5
6
7
8
9
run 命令中,带上了 bash,说明我们要用 bash;
执行 run 命令后,就可以看到接下来就是容器内的终端了,并且可以执行 ps
和 ls
等命令
退出终端:用 exit
命令
# 查看运行中的容器
命令格式: docker ps [OPTIONS]
(常用)OPTIONS 说明:
- -a:列出当前所有正在运行的容器 + 历史上运行过的
- -l(小写的 L):显示最近创建的容器。
- -n:显示最近 n 个创建的容器。例如
docker ps -n 1
显示最近创建的 1 个容器 - -q:静默模式,只显示容器 ID。
- ..... 更多选项参考:
docker run --help
我们可以先启动一个 Ubuntu 容器,然后打开一个新的终端,查看:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b6f86519ec6 ubuntu "/bin/bash" 16 seconds ago Up 7 seconds happy_banach
2
3
字段说明:
- CONTAINER ID:容器 ID
- IMAGE:镜像
- CREATED:创建时间,这里是 16s 之前创建的
- STATUS:状态,这里是 up,7s,也就是启动了 7 秒
- PORTS:暴露的端口,这里是没有暴露,因此为空
- NAMES:容器名字,可以在
docker run
命令中通过--name='容器名字'
来指定,这里没有指定,因此是随机的
# 退出容器
两种退出方式:
- exit:通过 run 进去的容器,用 exit 退出后,容器会停止
- ctrl+p+q: 通过 run 进去的容器,用快捷键 ctrl+p+q 退出,容器不停止
# 启动已停止运行的容器
命令格式:docker start 容器ID或容器名
# 重启容器
命令格式:docker restart 容器ID或者容器
# 停止容器
命令格式:docker stop 容器ID或者容器名
# 强制停止容器
命令格式:docker kill 容器ID或容器名
# 删除已停止的容器
命令格式:docker rm 容器ID
注意,正在运行中的容器不能被删除,得先用 docker stop
停止容器。如果一定要删除运行中的,得使用 -f
选项强制删除
一次性删除多个容器实例:
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
2
# 启动守护式容器
之前我们都是启动交互式容器,一启动就直接进入其终端;
但在大部分的场景下,我们希望 docker 的服务是在后台运行的,可以用 docker run -d
选项指定容器的后台运行模式。
好比学 Redis 的时候,可以在配置文件写 daemon 来使其变成守护进程
我们来试试:
$ docker run -d ubuntu
b1cce118042c6773628e67284d610dc37124ee4509813f12afcd648d27694010
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2
3
4
5
可以看到确实创建容器成功了(返回了容器 ID),但是为什么没有运行呢?这就涉及到一个知识点:Docker 容器后台运行,就必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如运行 top,tail),就是会自动退出的。
这个是 Docker 的机制问题,以 web 容器 nginx 为例,正常情况下,我们配置启动服务只需要启动响应的 service 即可。例如 service nginx start;
但是这样做,nginx 为后台进程模式运行,就导致 docker 前台没有运行的应用,这样的容器后台启动后,会立即自动停止,因为他觉得他没事可做了。
所以,最佳的解决方案是,将要运行的程序以前台进程的形式运行,常见就是命令行模式(比如之前的 docker -it
),表示还有交互操作,不用自动停止
# 查看容器日志
命令格式:docker logs 容器ID
该命令会将容器中终端的内容打印出来。例如先启动一个 Redis,然后查看日志:
$ docker run -d redis
96dea7b6285ada51813d4b7cc1c5498ed44bfefc4018d36e868d4a435371b2ea
$ docker logs 96d
1:C 31 Aug 2023 10:39:11.909 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 31 Aug 2023 10:39:11.909 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 31 Aug 2023 10:39:11.909 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 31 Aug 2023 10:39:11.909 * monotonic clock: POSIX clock_gettime
1:M 31 Aug 2023 10:39:11.910 * Running mode=standalone, port=6379.
1:M 31 Aug 2023 10:39:11.910 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 31 Aug 2023 10:39:11.910 # Server initialized
1:M 31 Aug 2023 10:39:11.910 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 31 Aug 2023 10:39:11.910 * Ready to accept connections
2
3
4
5
6
7
8
9
10
11
12
13
# 查看容器内运行的进程
命令格式:docker top 容器ID
比如之前启动的 Redis:
$ docker top 96d
UID PID PPID C STIME TTY TIME CMD
polkitd 15627 15609 0 18:39 ? 00:00:00 redis-server *:6379
2
3
# 查看容器内部细节
命令格式:docker inspect 容器ID
该命令先显示容器的很多细节,例如镜像信息,网络信息,网桥信息等,后续 Docker 高级篇会经常用这个
$ docker inspect 96d
[
{
"Id": "96dea7b6285ada51813d4b7cc1c5498ed44bfefc4018d36e868d4a435371b2ea",
"Created": "2023-08-31T10:39:11.551125034Z",
"Path": "docker-entrypoint.sh",
"Args": [
"redis-server"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 15627,
...........................
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 进入容器
命令格式:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
命令详解
-
OPTIONS
:可选参数,用于设置执行选项。 -
CONTAINER
:容器名称或 ID,指定要执行命令的容器 -
COMMAND
:要在容器内执行的命令 -
ARG
:命令的参数,可以有多个
options 常用参数
- -d,在后台运行命令
- -i,即使没有附加也保持 STDIN 打开,和 -t 配合
- -t,进入容器的 CLI 模式
- -e,设置环境变量
- –env-file,读入环境变量文件
- -w,需要执行命令的目录
- -u,指定访问容器的用户名
- 更多参数及说明通过
docker exec --help
查看
一般来说,都是使用 docker exec -it 容器ID /bin/bash
来进入容器。
注意:对于已经暂停或停止了的容器,无法执行 docker exec 命令
另一个进入容器的命令:docker attach 容器ID
。区别:
- attach 直接进入容器启动命令的终端,不会启动新的进程。用 exit 退出,会导致容器的停止。
- exec 是在容器中打开新的终端,并且可以启动新的进程。用 exit 退出,不会导致容器的停止。
推荐使用 docker exec
。
# 从容器内拷贝文件
有时候我们需要从容器内拷贝文件出来(例如用来备份)。命令格式:
docker cp 容器ID:容器内路径 目的主机路径
# 导入和导出容器
有时候我们希望将整个容器备份,此时就可以用导入导出命令:
- export:导出容器的内容留作为一个 tar 归档文件。命令格式:
docker export 容器ID > 文件名.tar
。 - import:从 tar 包中的内容创建一个新的文件系统再导入为镜像,命令格式:
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
。其中镜像用户、镜像名和镜像版本号是可以自定义的。
(完)