文章目录
- [1. 容器的生命周期](#1. 容器的生命周期)
-
- [1.1 状态](#1.1 状态)
- [1.2 容器 OOM(内存耗尽)](#1.2 容器 OOM(内存耗尽))
- [1.3 容器异常退出](#1.3 容器异常退出)
- [1.4 容器暂停](#1.4 容器暂停)
- [2. 容器命令清单](#2. 容器命令清单)
-
- [2.1 docker create](#2.1 docker create)
- [2.2 docker run](#2.2 docker run)
- [2.3 docker ps](#2.3 docker ps)
- [2.4 docker logs](#2.4 docker logs)
- [2.5 docker attach](#2.5 docker attach)
- [2.6 docker exec](#2.6 docker exec)
- [2.7 docker start](#2.7 docker start)
- [2.8 docker stop](#2.8 docker stop)
- [2.9 docker restart](#2.9 docker restart)
- [2.10 docker kill](#2.10 docker kill)
- [2.11 docker top](#2.11 docker top)
- [2.12 docker stats](#2.12 docker stats)
- [2.13 docker container inspect](#2.13 docker container inspect)
- [2.14 docker port](#2.14 docker port)
- [2.15 docker cp](#2.15 docker cp)
- [2.16 docker diff](#2.16 docker diff)
- [2.17 docker commit](#2.17 docker commit)
- [2.18 docker pause](#2.18 docker pause)
- [2.19 docker unpause](#2.19 docker unpause)
- [2.20 docker rm](#2.20 docker rm)
- [2.21 docker export](#2.21 docker export)
- [2.22 docker wait](#2.22 docker wait)
- [2.23 docker rename](#2.23 docker rename)
- [2.24 docker container prune](#2.24 docker container prune)
- [2.25 docker update](#2.25 docker update)
1. 容器的生命周期
1.1 状态
容器的生命周期是容器可能处于的状态。
created:初建状态running:运行状态stopped:停止状态paused: 暂停状态deleted:删除状态
各生命周期之间的转换关系如图所示:

docker create: 创建容器后,不立即启动运行,容器进入初建状态;
docker run: 创建容器,并立即启动运行,进入运行状态;
docker start: 容器转为运行状态;
docker stop: 容器将转入停止状态;
docker kill: 容器在故障(死机)时,执行 kill(断电),容器转入停止状态,这种操作容易丢失数据,除非必要,否则不建议使用;
docker restart: 重启容器,容器转入运行状态;
docker pause: 容器进入暂停状态;
docker unpause: 取消暂停状态,容器进入运行状态;
docker rm: 删除容器,容器转入删除状态。
killed by out-of-memory(因内存不足被终止) :宿主机内存被耗尽,也被称为OOM:非计划终止 这时需要杀死最吃内存的容器
container process exitde(异常终止):出现容器被终止后,将进入Should restart?选择操作:
yes需要重启,容器执行start命令,转为运行状态。
no不需要重启,容器转为停止状态。
1.2 容器 OOM(内存耗尽)
Docker在处理OOM事件时分为三种情况:
- 如果容器中的应用耗尽了主机系统分配给容器的内存限额,就会触发
OOM事件。例如,在容器当中,部署了一个
web服务。假设主机分配给此容器的内存上限为1G,当脚本申请的内存大于1G时,此容器就会触发OOM事件。而在这种情况下,此容器将会被强制关闭。但需要注意的是,此时关闭容器的并非是
Docker Daemon,而是宿主机操作系统。因为一个容器其实就是一组运行在宿主机操作系统当中的进程,宿主机操作系统通过cgroups对这组进程设定资源上限,当这些进程申请的资源到达上限时,触发的是宿主机操作系统的内核OOM事件,因此最终是由宿主机内核来关闭这些进程。
- 如果用户不想关闭这个容器,那么可以选择
--oom-kill-disable来禁用OOM-Killer。使用此参数时,仍需要注意,如果使用
-m设置了此容器内存上限,那么当容器到达内存资源上限时,主机不会关闭容器,但也不会继续向此容器继续分配资源,此时容器将处于hung状态。只需要将最坏的情况封闭在一定范围之内,而不至于蔓延出去。
- 如果用户使用了
--oom-kill-disable,但也没有使用-m来设定上限,因而此时此容器将会尽可能多地使用主机内存资源。换言之,主机内存有多大,它就将用多大。
1.3 容器异常退出
每个容器内部都存在一个
Init进程,容器中其他所有进程都是此进程的子进程。运行的容器是因为Init进程在运行,如果一个子进程因为某种原因造成了退出,那么其父进程也会同步退出,直至Init进程也退出。当Init进程退出时,也就代表着此容器被关闭。
docker目前没有办法知道此时的进程退出属于正常退出还是异常退出。当出现容器关闭情况时,Docker Daemon会尝试再次重新将此容器由Stopped状态转为Running状态。只有设置了--restart参数的容器,Docker Daemon才会去尝试启动,否则容器会保持停止状态。
1.4 容器暂停
Docker"剥夺"了此容器的CPU资源。而其他资源,如Memory资源、Network资源等还保留未动。如此一来,失去了
CPU资源的进程,是不会被主机内核系统所调度的,所以此容器就处于"冰封"状态。
2. 容器命令清单
| 命令 | 别名 | 功能 | 备注 |
|---|---|---|---|
docker create |
docker container create |
创建容器 | |
docker run |
docker container run |
运行容器 | 必须掌握 |
docker attach |
docker container attach |
连接到正在运行中的容器。 | |
docker commit |
docker container commit |
将镜像提交为容器 | 必须掌握 |
docker cp |
docker container cp |
在容器和宿主机之间拷贝 | 必须掌握 |
docker diff |
docker container diff |
检查容器里文件结构的更改。 | |
docker exec |
docker container exec |
在运行的容器中执行命令 | 必须掌握 |
docker export |
docker container export |
将容器导出为 tar | |
docker container inspect |
查看容器详细信息 | 必须掌握 | |
docker kill |
docker container kill |
杀死容器 | 必须掌握 |
docker logs |
docker container logs |
查看日志 | 必须掌握 |
docker ps |
docker container ls, docker container list, docker container ps |
查看正在运行的进程 | 必须掌握 |
docker pause |
docker container pause |
暂停进程 | |
docker port |
docker container port |
查看容器的端口映射 | |
docker container prune |
删除停止的容器 | ||
docker rename |
docker container rename |
重命名容器 | |
docker restart |
docker container restart |
重启容器 | 必须掌握 |
docker rm |
docker container rm, docker container remove |
删除容器 | 必须掌握 |
docker start |
docker container start |
启动容器 | 必须掌握 |
docker stats |
docker container stats |
查看资源占用信息 | 必须掌握 |
docker stop |
docker container stop |
停止容器 | 必须掌握 |
docker top |
docker container top |
查看某个容器的资源占用 | 必须掌握 |
docker unpause |
docker container unpause |
继续运行容器 | |
docker update |
docker container update |
更新容器配置 | |
docker wait |
docker container wait |
阻止一个或多个容器停止,然后打印退出代码 |
2.1 docker create
功能:创建一个新的容器但不启动它
语法:
shell
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
别名
shell
docker container create
关键参数
-i:以交互模式运行容器,通常与-t同时使用;-P:随机端口映射,容器内部端口随机映射到主机的端口-p:指定端口映射,格式为:主机(宿主)端口:容器端口-t:为容器重新分配一个伪输入终端,通常与-i同时使用;--name="nginx-lb":为容器指定一个名称;-h "mars":指定容器的hostname;-e username="ritchie":设置环境变量;--cpuset-cpus="0-2" or --cpuset-cpus="0,1,2":绑定容器到指定CPU运行;-m:设置容器使用内存最大值;--network="bridge":指定容器的网络连接类型;--link=[]:添加链接到另一个容器;--volume,-v:绑定一个卷--rm:shell退出的时候自动删除容器--restart:自动重启
例子:
shell
docker create --name mynginx nginx:latest
shell
root@yudukai:~# docker create --name mywebsite1 -p 80:80 nginx:1.21.1
2ae8f6d4ba1421eb61735945b3ffe7878d06b3e88a949c296f204ac52c3ca01c
root@yudukai:~# netstat -nltp |grep 80 # 这边看不到,是因为没启动
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 2658071/mysqld
tcp 0 0 127.0.0.1:2380 0.0.0.0:* LISTEN 651/etcd
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN 2658071/mysqld
root@yudukai:~# docker ps -a |grep mywebsite1 # 这边可以看到状态是Created,这里不加-a是看不到的,因为没有启动
2ae8f6d4ba14 nginx:1.21.1 "/docker-entrypoint...." About a minute ago Created mywebsite1
root@yudukai:~# docker start mywebsite1 # 然后我们开一下
mywebsite1
root@yudukai:~# netstat -nltp |grep 80 # 可以看到这里开启后占用了80端口
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 2658071/mysqld
tcp 0 0 127.0.0.1:2380 0.0.0.0:* LISTEN 651/etcd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4147370/docker-prox
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN 2658071/mysqld
tcp6 0 0 :::80 :::* LISTEN 4147377/docker-prox
root@yudukai:~# docker ps -a |grep mywebsite1 # 这边的状态人也不是Created了
2ae8f6d4ba14 nginx:1.21.1 "/docker-entrypoint...." 5 minutes ago Up 16 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp mywebsite1
root@yudukai:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ae8f6d4ba14 nginx:1.21.1 "/docker-entrypoint...." 7 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp mywebsite1
root@yudukai:~#
如果80端口被占用了,那么就可以更改一下端口。
也可以去浏览器查看:
shell
服务器ip:80

2.2 docker run
功能:创建一个新的容器并运行一个命令
语法:
shell
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
别名:
shell
docker container run
关键参数
-d: 后台运行容器,并返回容器ID;比create多了这个参数-i: 以交互模式运行容器,通常与-t同时使用;-P: 随机端口映射,容器内部端口随机映射到主机的端口-p: 指定端口映射,格式为:主机(宿主)端口:容器端口-t: 为容器重新分配一个伪输入终端,通常与-i同时使用;--name="nginx-lb": 为容器指定一个名称;-h "mars": 指定容器的hostname;-e username="ritchie": 设置环境变量;--cpuset-cpus="0-2" or --cpuset-cpus="0,1,2": 绑定容器到指定CPU运行;-m:设置容器使用内存最大值;--network="bridge": 指定容器的网络连接类型;--link=[]: 添加链接到另一个容器;--volume,-v: 绑定一个卷--rm:shell退出的时候自动删除容器--restart:自动重启
样例:
shell
#使用 docker 镜像 nginx:latest 以后台模式启动一个容器,并将容器命名为mynginx。
docker run --name mynginx -d nginx:latest
#使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。
docker run -p 80:80 -v /data:/data -d nginx:latest
# 创建并启动一个新容器,给容器命名为 mywebsite2
# -d后台运行容器,不占用当前终端,-p 81:80端口映射:宿主机 81 端口 → 容器 80 端口(左边宿主机,右边容器)
# 使用的镜像为 nginx,版本标签 1.21.1
docker run --name mywebsite2 -d -p 81:80 nginx:1.21.1
shell
root@yudukai:~# docker run --name mywebsite2 -d -p 81:80 nginx:1.21.1
ea63b99ba74d5b13b54e23b822de738f0e2022f83397da054db61afcacd3648a
root@yudukai:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea63b99ba74d nginx:1.21.1 "/docker-entrypoint...." 6 seconds ago Up 5 seconds 0.0.0.0:81->80/tcp, [::]:81->80/tcp mywebsite2
2ae8f6d4ba14 nginx:1.21.1 "/docker-entrypoint...." 17 minutes ago Up 12 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp mywebsite1
root@yudukai:~#
2.3 docker ps
功能:列出容器
语法:
shell
docker ps [OPTIONS]
别名:
shell
docker container ls, docker container list, docker container ps
关键参数
-a:显示所有的容器,包括未运行的。-f:根据条件过滤显示的内容。--format:指定返回值的模板文件。如json或者table-l:显示latest的容器。-n:列出最近创建的n个容器。--no-trunc:不截断输出。-q:静默模式,只显示容器编号。-s:显示总的文件大小。
样例:
shell
root@yudukai:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea63b99ba74d nginx:1.21.1 "/docker-entrypoint...." 6 seconds ago Up 5 seconds 0.0.0.0:81->80/tcp, [::]:81->80/tcp mywebsite2
2ae8f6d4ba14 nginx:1.21.1 "/docker-entrypoint...." 17 minutes ago Up 12 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp mywebsite1
shell
root@yudukai:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea63b99ba74d nginx:1.21.1 "/docker-entrypoint...." 3 minutes ago Up 2 minutes 0.0.0.0:81->80/tcp, [::]:81->80/tcp mywebsite2
2ae8f6d4ba14 nginx:1.21.1 "/docker-entrypoint...." 19 minutes ago Up 15 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp mywebsite1
01cfe5b5a691 busybox:latest "sleep 1000" 47 hours ago Exited (0) 47 hours ago test_container
9fcb41da2401 hello-world "/hello" 5 days ago Exited (0) 5 days ago dazzling_wozniak
f75a3fffabd3 hello-world "/hello" 5 days ago Exited (0) 5 days ago dreamy_bartik
dcc338752d8c hello-world "/hello" 5 days ago Exited (0) 5 days ago jolly_ritchie
d0f3c7af62dc c3cbe1cc1aa5 "/hello" 4 weeks ago Exited (0) 4 weeks ago wonderful_pasteur
shell
root@yudukai:~# docker ps -s
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
ea63b99ba74d nginx:1.21.1 "/docker-entrypoint...." 3 minutes ago Up 3 minutes 0.0.0.0:81->80/tcp, [::]:81->80/tcp mywebsite2 81.9kB (virtual 147MB)
2ae8f6d4ba14 nginx:1.21.1 "/docker-entrypoint...." 20 minutes ago Up 15 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp mywebsite1 81.9kB (virtual 147MB)
root@yudukai:~# docker ps -q
ea63b99ba74d
2ae8f6d4ba14
root@yudukai:~# docker ps -n 1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea63b99ba74d nginx:1.21.1 "/docker-entrypoint...." 14 minutes ago Up 14 minutes 0.0.0.0:81->80/tcp, [::]:81->80/tcp mywebsite2
root@yudukai:~# docker ps -n=1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea63b99ba74d nginx:1.21.1 "/docker-entrypoint...." 16 minutes ago Up 16 minutes 0.0.0.0:81->80/tcp, [::]:81->80/tcp mywebsite2
root@yudukai:~#
2.4 docker logs
功能:查看容器日志
语法:
shell
docker logs [OPTIONS] CONTAINER
别名:
shell
docker container logs
关键参数
-f,--follow: 跟踪日志输出--since:显示某个开始时间的所有日志-t,--timestamps: 显示时间戳-n,--tail:仅列出最新N条容器日志
样例:
shell
#跟踪查看容器 mynginx 的日志输出。
docker logs -f mynginx1
#查看容器 mynginx 从 2016 年 7 月 1 日后的最新 10 条日志。
docker logs --since="2016-07-01" --tail=10 mynginx

shell
root@yudukai:~# docker logs mywebsite2 -t
2026-08-28T05:54:52.155944172Z /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
2026-08-28T05:54:52.155971390Z /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
2026-08-28T05:54:52.157429043Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
2026-08-28T05:54:52.163230097Z 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
2026-08-28T05:54:52.170319993Z 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
2026-08-28T05:54:52.170524604Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
2026-08-28T05:54:52.173592393Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
2026-08-28T05:54:52.175186059Z /docker-entrypoint.sh: Configuration complete; ready for start up
2026-08-28T05:54:52.180449006Z 2026/08/28 05:54:52 [notice] 1#1: using the "epoll" event method
2026-08-28T05:54:52.180516551Z 2026/08/28 05:54:52 [notice] 1#1: nginx/1.21.1
2026-08-28T05:54:52.180522051Z 2026/08/28 05:54:52 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2026-08-28T05:54:52.180525486Z 2026/08/28 05:54:52 [notice] 1#1: OS: Linux 5.15.0-60-generic
2026-08-28T05:54:52.180530431Z 2026/08/28 05:54:52 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1024:524288
2026-08-28T05:54:52.180535528Z 2026/08/28 05:54:52 [notice] 1#1: start worker processes
2026-08-28T05:54:52.180690882Z 2026/08/28 05:54:52 [notice] 1#1: start worker process 31
2026-08-28T05:54:52.180970424Z 2026/08/28 05:54:52 [notice] 1#1: start worker process 32
2026-08-28T05:54:52.181232547Z 2026/08/28 05:54:52 [notice] 1#1: start worker process 33
2026-08-28T05:54:52.181503504Z 2026/08/28 05:54:52 [notice] 1#1: start worker process 34
root@yudukai:~#
shell
root@yudukai:~# docker logs --since="2026-08-28T14:20:25" mywebsite1
45.198.224.54 - - [28/Aug/2026:06:37:30 +0000] "GET / HTTP/1.1" 200 612 "-" "-" "-"
183.131.24.98 - - [28/Aug/2026:06:50:04 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Edg/151.0.0.0" "-"
183.131.24.98 - - [28/Aug/2026:06:50:05 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Edg/151.0.0.0" "-"
root@yudukai:~# docker logs --since="2026-08-28T14:20:25" mywebsite1 # 我刷新后就多了条
45.198.224.54 - - [28/Aug/2026:06:37:30 +0000] "GET / HTTP/1.1" 200 612 "-" "-" "-"
183.131.24.98 - - [28/Aug/2026:06:50:04 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Edg/151.0.0.0" "-"
183.131.24.98 - - [28/Aug/2026:06:50:05 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Edg/151.0.0.0" "-"
183.131.24.98 - - [28/Aug/2026:06:51:21 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Edg/151.0.0.0" "-"
root@yudukai:~#
2.5 docker attach
功能:连接到正在运行中的容器。
语法:
shell
docker attach [OPTIONS] CONTAINER
别名:
shell
docker container attach
关键参数
--sig-proxy:是否将所有信号代理,默认是true,如果设置为false,退出的话不会影响容器,否则退出会导致容器退出。
样例:
我们先看进入一下mywebsite1

进去后查看浏览器,刷新几次:

可以看到浏览器是可以进入的,刷新后也有对应的日志。
然后Ctrl+C。
可以看到浏览器进不去了,容器也关闭了。

可以看到mywebsite1已经退出了

然后我们再启动一下
shell
root@yudukai:~# docker start mywebsite1
mywebsite1
root@yudukai:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea63b99ba74d nginx:1.21.1 "/docker-entrypoint...." 13 days ago Up 13 days 0.0.0.0:81->80/tcp, [::]:81->80/tcp mywebsite2
2ae8f6d4ba14 nginx:1.21.1 "/docker-entrypoint...." 2 weeks ago Up 3 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp mywebsite1
root@yudukai:~#
再试一下这个参数
shell
docker attach --sig-proxy=false mywebsite1

可以看到,推出之后这个容器还是在跑的,不过这里要Ctrl+C三次,是一种保护机制。
不过我试了一下,Ctrl+Z,是一次就行的。

因为杀不死容器了,但总得有办法退出来吧?于是连续收到 3 次 SIGINT/SIGTERM 后才强制断开。这个"3 次"通常要求在短时间内连续按。
显示报文为:
CONTAINER ID: 容器ID。IMAGE: 使用的镜像。COMMAND: 启动容器时运行的命令。CREATED: 容器的创建时间。STATUS: 容器状态。PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。NAMES: 自动分配的容器名称。
2.6 docker exec
功能:在容器中执行命令
语法:
shell
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
别名:
shell
docker container exec
关键参数
-d:分离模式: 在后台运行-i:即使没有附加也保持STDIN打开-t:分配一个伪终端-e:设置环境变量-u,--user:指定用户 "<name|uid>[:<group|gid>]"-w,--workdir:指定工作目录
样例:
shell
#在容器 mynginx 中以交互模式执行 echo:
docker exec -it mywebsite1 echo "Hello bit"
#在容器 mynginx 中以交互模式打开 shell:
docker exec -it mywebsite1 bash
#通过 id 进去,docker ps 可以看到容器 id
docker exec -it 5706674cc67e bash
shell
#在容器 mynginx 中以交互模式打开 shell:
docker exec -it mywebsite1 bash

shell
# 查看版本
docker exec -it mywebsite1 nginx -v

shell
# 后台执行这个命令,没有打印
docker exec -d mywebsite1 nginx -v

shell
# -e环境变量
docker exec -it -e mynginx=maxyu mywebsite1 bash

shell
# -u,--user :指定用户 "<name|uid>[:<group|gid>]"
# 我们先看一下用户
docker exec -it mywebsite1 cat /etc/passwd
# 然后用里面的nginx用户运行一个命令,查看nginx的版本
docker exec -it -u nginx mywebsite1 nginx -v

如果我换一个不存在的用户,会提示用户找不到

shell
# -w指定工作目录
# 先看一下默认在什么路径
docker exec -it mywebsite1 bash
# 然后更改一下工作目录
docker exec -it -w /etc mywebsite1 bash

一般来说,我们会通过
exec命令的-it和bash进入容器,然后对容器进行各种各样的操作。
2.7 docker start
功能:启动停止的容器
语法:
shell
docker start [OPTIONS] CONTAINER [CONTAINER...]
别名:
shell
docker container start
样例:
shell
docker start mynginx
之前试过了,这里就简单介绍一下。
2.8 docker stop
功能:停止运行的容器
语法:
shell
docker stop [OPTIONS] CONTAINER [CONTAINER...]
别名:
shell
docker container stop
关键参数
-s:发送的信号
样例:
shell
docker stop mynginx

2.9 docker restart
功能:重启容器。
原来运行态:先关闭,然后进入运行态
原来关闭的:就让他进入运行态
语法:
shell
docker restart [OPTIONS] CONTAINER [CONTAINER...]
别名:
shell
docker container restart
关键参数
-s:发送信号
样例:
shell
docker restart mywebsite1
执行前,打开两个终端看一下日志

执行后:可以看到退出了日志,并且可以看到时间变了。

试一下-s
shell
docker restart -s 9 mywebsite1

对比之前退出的一大堆东西,可以看到这里是强制杀死。不过-s这个参数一般不怎么使用。
2.10 docker kill
功能:强制退出容器(暴力的)
语法:
shell
docker kill [OPTIONS] CONTAINER [CONTAINER...]
别名:
shell
docker container kill
关键参数
-s:发送的信号
注意事项:
Docker stop发送的是SIGTERM信号,docker kill发送的是SIGKILL信号。
样例:
shell
docker kill mywebsite1
docker stop:给时间等他关闭,给你保存数据的时间。


docker kill:直接杀掉,不给你保存数据的时间。
我们把容器再开一下


2.11 docker top
功能:查看容器中运行的进程信息,支持
ps命令参数。
语法:
shell
docker top CONTAINER [ps OPTIONS]
# [ps OPTIONS]指的是这个top命令后面可以跟ps命令的一些参数
别名:
shell
docker container top
注意事项:
容器运行时不一定有
/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,可以使用docker top来实现查看container中正在运行的进程。
样例:
shell
#查看容器进程信息
docker top mywebsite1

shell
# 加上ps参数aux可以更清晰的看到里面的资源占用
docker top mywebsite1 aux

2.12 docker stats
功能 :显示容器资源的使用情况,包括:
CPU、内存、网络I/O等。
语法:
shell
docker stats [OPTIONS] [CONTAINER...]
别名:
shell
docker container stats
关键参数
--all,-a:显示所有的容器,包括未运行的。
--format:指定返回值的模板文件。如table,json
--no-stream:展示当前状态就直接退出了,不再实时更新。
--no-trunc:不截断输出。
返回报文
CONTAINER ID与NAME:容器ID与名称。
CPU %与MEM %:容器使用的CPU和内存的百分比。
MEM USAGE/LIMIT:容器正在使用的总内存,以及允许使用的内存总量。
NET I/O:容器通过其网络接口发送和接收的数据量。
BLOCK I/O:容器从主机上的块设备读取和写入的数据量。
PIDs:容器创建的进程或线程数。
样例:
shell
#列出所有在运行的容器信息。 这个是实时刷新的,Ctrl+C可以退出
docker stats

疯狂点击刷新后,CPU占用也高了

shell
# 只监控一个容器mywebsite1
docker stats mywebsite1

shell
# -a打印所有容器包括停止的
docker stats -a

shell
#json 格式显示
docker stats --format json

shell
#定制化的表格显示
docker stats --format "table{{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"

shell
# --no-stream:展示当前状态就直接退出了,不再实时更新。
docker stats --no-stream

shell
# --no-trunc:不截断输出。
# 容器id实际上是非常长的,docker ps显示的只是前几位
docker stats --no-trunc

2.13 docker container inspect
功能:查看容器详细信息
语法:
shell
docker container inspect [OPTIONS] CONTAINER [CONTAINER...]
关键参数
-f:指定返回值的模板文件。如table、json-s:显示总的文件大小。
注意事项:
docker inspect会自动检查是镜像还是容器然后显示相信信息
样例:
shell
# 此命令展示的太长了,就不截图了
docker container inspect mywebsite1
shell
docker container inspect -f json mywebsite1

shell
# -s:显示总的文件大小。加上后可以看到里面多了个字段。
docker container inspect -s mywebsite1

2.14 docker port
功能:用于列出指定的容器的端口映射,或者查找将
PRIVATE_PORT NAT到面向公众的端口。
语法:
shell
docker port CONTAINER [PRIVATE_PORT[/PROTO]]
别名:
shell
docker container port
样例:
shell
docker port mywebsite1

这里一个是
IPV4,一个是IPV6。
2.15 docker cp
功能:在容器和宿主机之间拷贝文件
我们知道容器和宿主机之间有文件隔离,那么隔离产生后如何把文件拷贝呢?就靠这个命令了。这个命令主要是靠
:来区分的,:前面的就是容器id或者名字
语法:
shell
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
别名:
shell
docker container cp
样例:
shell
#将主机/www/目录拷贝到容器 mynginx 的/www 目录下。
docker cp /www/ mynginx:/www/
#将容器/www/目录拷贝到主机的/wwwbak 目录下。
docker cp mynginx:/www/ /wwwbak/
演示:
容器中的路径:

宿主机中的路径:

shell
# 把容器中的html拷贝到这个宿主机的当前目录下
docker cp mywebsite1:/usr/share/nginx/html/index.html .

我们看一下这个文件的内容

然后我改一下内容,欢迎语句我改成:

然后放回容器
shell
# 把宿主机中的html拷贝到容器原目录下
docker cp /data/maxhou/index.html mywebsite1:/usr/share/nginx/html/

2.16 docker diff
功能:检查容器里文件结构的更改。
C:改变过的文件,Change
A:增加的文件,ADD
语法:
shell
docker diff CONTAINER
样例:
shell
docker diff mywebsite1


docker diff的输出并不是严格按照使用者操作的先后顺序来的,也不完全是按字母顺序,它有一套内部的排序逻辑,所以新加的/test.html并没有出现在列表的最开头或最结尾,而是插在了中间。所以我们使用的时候可以添加过滤。
shell
docker diff mywebsite1 | grep test.html

2.17 docker commit
功能:从容器创建一个新的镜像。
语法:
shell
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
参数
-a:提交的镜像作者;-c:使用Dockerfile指令来创建镜像;可以修改启动指令 (这里的启动指令可以理解为CPP或者Java的mian函数一样的启动命令)-m:提交时的说明文字;-p:在commit时,将容器暂停。
样例:
shell
# 1. 查看本地已有的 nginx 镜像
root@yudukai:~# docker images nginx
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
nginx:1.21.1 a05b0cdd4fc1 200MB 53.8MB U
nginx:1.31.4 25ee11a13a12 241MB 66.2MB
nginx:trixie-perl a07ae7717013 311MB 79.6MB
nginx@sha256:f1aec5de9d214ab7dad6b67c6665ee9eaa55ac890c710700216804d8b4829802 f1aec5de9d21 151MB 38.4MB
# 2. 后台启动一个容器
# -d: 后台运行
# --name mywebsite1forcommit: 给容器起个名字,方便后面操作
# nginx:1.21.1: 指定使用哪个镜像
root@yudukai:~# docker run -d --name mywebsite1forcommit nginx:1.21.1
7e88092d3e2adb94a1b0727cb05043d48955a36d3713adfea5a7fad91394f944
# 3. 查看正在运行的容器,确认刚才的容器启动成功了
root@yudukai:~# docker ps |grep mywebsite1forcommit
7e88092d3e2a nginx:1.21.1 "/docker-entrypoint...." 22 seconds ago Up 21 seconds 80/tcp mywebsite1forcommit
# 4. 尝试查看名为 "mywebsite1" 的镜像
# 注意:此时这个名字还不存在,所以查不到(输出为空)
root@yudukai:~# docker images mywebsite1
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
# 5. 将容器保存为镜像
# mywebsite1forcommit: 源容器名
# mywebsite1:v1.0: 目标镜像名和标签
root@yudukai:~# docker commit mywebsite1forcommit mywebsite1:v1.0
sha256:84c0dafab6f799602cb225b417c80970d39e8e762f1a3c3cd77cfb3058555495
# 6. 再次查看名为 "mywebsite1" 的镜像
root@yudukai:~# docker images mywebsite1
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
mywebsite1:v1.0 84c0dafab6f7 200MB 53.8MB
root@yudukai:~#
然后进入创建一个txt文本文件
shell
root@yudukai:~# docker exec -it mywebsite1forcommit bash
root@7e88092d3e2a:/# echo "hello ydk lxbl" > /testforcommit.txt
root@7e88092d3e2a:/# ls -l
total 84
drwxr-xr-x 2 root root 4096 Sep 2 2021 bin
drwxr-xr-x 2 root root 4096 Jun 13 2021 boot
drwxr-xr-x 5 root root 340 Sep 16 05:48 dev
drwxr-xr-x 1 root root 4096 Sep 3 2021 docker-entrypoint.d
-rwxrwxr-x 1 root root 1202 Sep 3 2021 docker-entrypoint.sh
drwxr-xr-x 1 root root 4096 Sep 16 05:48 etc
drwxr-xr-x 2 root root 4096 Jun 13 2021 home
drwxr-xr-x 1 root root 4096 Sep 3 2021 lib
drwxr-xr-x 2 root root 4096 Sep 2 2021 lib64
drwxr-xr-x 2 root root 4096 Sep 2 2021 media
drwxr-xr-x 2 root root 4096 Sep 2 2021 mnt
drwxr-xr-x 2 root root 4096 Sep 2 2021 opt
dr-xr-xr-x 234 root root 0 Sep 16 05:48 proc
drwx------ 2 root root 4096 Sep 2 2021 root
drwxr-xr-x 1 root root 4096 Sep 16 05:48 run
drwxr-xr-x 2 root root 4096 Sep 2 2021 sbin
drwxr-xr-x 2 root root 4096 Sep 2 2021 srv
dr-xr-xr-x 13 root root 0 Sep 16 05:48 sys
-rw-r--r-- 1 root root 15 Sep 16 06:00 testforcommit.txt
drwxrwxrwt 1 root root 4096 Sep 3 2021 tmp
drwxr-xr-x 1 root root 4096 Sep 2 2021 usr
drwxr-xr-x 1 root root 4096 Sep 2 2021 var
root@7e88092d3e2a:/# cat testforcommit.txt
hello ydk lxbl
root@7e88092d3e2a:/# exit
exit
root@yudukai:~#
然后将容器当前的修改状态保存为一个新的镜像
shell
root@yudukai:~# docker commit mywebsite1forcommit mywebsite1:v2.0
sha256:ae473816ba2360ac8c20818d0df8574042e04e717fa0e1fead6950e25b1a20ea
# 查看名为 mywebsite1 的所有镜像
# 会看到现在有两个版本:v1.0 和 刚刚生成的 v2.0
# 注意它们的 ID 不同(ae473... vs 84c0...),说明 v2.0 是一个独立的新镜像
root@yudukai:~# docker images mywebsite1
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
mywebsite1:v1.0 84c0dafab6f7 200MB 53.8MB
mywebsite1:v2.0 ae473816ba23 200MB 53.8MB
# 使用刚刚制作的 v2.0 镜像启动一个新容器进行测试
# -it: 交互式运行
# --rm: 容器退出后自动删除(这是一个好习惯,测试完不留垃圾)
# bash: 启动后进入 bash 命令行
root@yudukai:~# docker run -it --rm mywebsite1:v2.0 bash
# 再次列出根目录文件
# 会发现:虽然这是一个全新的容器,但 testforcommit.txt 文件依然存在
# 这证明了 commit 成功,文件已经被"打包"进了镜像里。
root@289b7c01ad35:/# ls -l
total 80
drwxr-xr-x 2 root root 4096 Sep 2 2021 bin
drwxr-xr-x 2 root root 4096 Jun 13 2021 boot
drwxr-xr-x 5 root root 360 Sep 16 06:02 dev
drwxr-xr-x 1 root root 4096 Sep 3 2021 docker-entrypoint.d
-rwxrwxr-x 1 root root 1202 Sep 3 2021 docker-entrypoint.sh
drwxr-xr-x 1 root root 4096 Sep 16 06:02 etc
drwxr-xr-x 2 root root 4096 Jun 13 2021 home
drwxr-xr-x 1 root root 4096 Sep 3 2021 lib
drwxr-xr-x 2 root root 4096 Sep 2 2021 lib64
drwxr-xr-x 2 root root 4096 Sep 2 2021 media
drwxr-xr-x 2 root root 4096 Sep 2 2021 mnt
drwxr-xr-x 2 root root 4096 Sep 2 2021 opt
dr-xr-xr-x 242 root root 0 Sep 16 06:02 proc
drwx------ 1 root root 4096 Sep 16 06:00 root
drwxr-xr-x 1 root root 4096 Sep 16 05:48 run
drwxr-xr-x 2 root root 4096 Sep 2 2021 sbin
drwxr-xr-x 2 root root 4096 Sep 2 2021 srv
dr-xr-xr-x 13 root root 0 Sep 16 06:02 sys
-rw-r--r-- 1 root root 15 Sep 16 06:00 testforcommit.txt
drwxrwxrwt 1 root root 4096 Sep 3 2021 tmp
drwxr-xr-x 1 root root 4096 Sep 2 2021 usr
drwxr-xr-x 1 root root 4096 Sep 2 2021 var
root@289b7c01ad35:/# cat testforcommit.txt
hello ydk lxbl
root@289b7c01ad35:/#
接下来是对它参数的测试
shell
docker commit -a 'ydk' -m 'create' -p mywebsite1forcommit mywebsite1:v3.0

然后试一下更改他的启动命令
shell
docker image inspect nginx:1.21.1

shell
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
这个里面的就是启动命令,然后我们来更改一下
shell
docker commit -a 'ydk' -m 'create by ydk' -p -c 'CMD ["tail","-f","/etc/hosts"]' mywebsite1forcommit mywebsite1:v4.0

我们也可以继续验证

tail -f /etc/hosts:是跟踪查看容器尾部,系统里用来记录域名解析的文件的命令。当运行
docker logs ...查看容器日志时,实际上就是在看这个启动命令(tail -f /etc/hosts)的输出结果。启动瞬间:
tail命令读取了/etc/hosts文件的最后几行。找到内容:在这个文件的最后,
Docker刚刚写入了这一行配置:
IP地址:172.17.0.2(容器分配到的内网IP)- 主机名:
a35d25d0460c(容器ID的前12位)打印日志:
tail把这一行内容打印到了标准输出,也就是在docker logs里看到的东西。
2.18 docker pause
功能:暂停容器中所有的进程。(剥夺进程的时间片)
语法:
shell
docker pause CONTAINER [CONTAINER...]
别名:
shell
docker container pause
样例:
shell
docker pause mywebsite5
新开一个容器,记得开服务器对应端口


然后执行
shell
docker pause mywebsite5


2.19 docker unpause
功能:恢复容器中所有的进程。
语法:
shell
docker unpause CONTAINER [CONTAINER...]
别名:
shell
docker container unpause
样例:
shell
docker unpause mywebsite5

2.20 docker rm
功能:删除停止的容器
语法:
shell
docker rm [OPTIONS] CONTAINER [CONTAINER...]
别名:
shell
docker container rm
关键参数
-f:通过SIGKILL信号强制删除一个运行中的容器。
样例:
shell
#删除 mynginx 容器
docker stop mywebsite5
docker rm mywebsite5
#删除所有停止的容器
docker rm $(docker ps -a -q)
可以看到没关闭的容器直接删是删不掉的

先关闭再删

加上-f就可以强制删除,这个是危险操作。

2.21 docker export
功能:导出容器内容为
tar文件然后通过命令
docker import,把tar文件重新转换成镜像
语法:
shell
docker export [OPTIONS] CONTAINER
别名:
shell
docker container export
关键参数
-o:写入到文件。
样例:
shell
#导出 nginx 为 tar
docker export -o mynginx202203.tar mynginx

我们顺便再试一下之前的docker import命令。
shell
docker import mywebsite5.tar mywebsite5:v1.0

不过对比后可以发现这个镜像里面少了很多东西,这个就是我们docker export的一个问题,会丢失我们的元数据信息。
所以我们需要进行镜像的迁移的时候,往往还是使用save和load。

不过也可以自己指定更改

2.22 docker wait
功能:阻塞运行直到容器停止,然后打印出它的退出代码。
语法:
shell
docker wait CONTAINER [CONTAINER...]
别名:
shell
docker container wait
样例:
shell
docker wait mynginx

然后关闭一下

2.23 docker rename
功能:重命名容器
语法:
shell
docker rename CONTAINER NEW_NAME
别名:
shell
docker container rename
样例:
shell
docker rename mywebsite5 mywebsite2
注意不可以重命名为已有的。

2.24 docker container prune
功能:删除所有停止的容器(危险操作)
语法:
shell
docker container prune [OPTIONS]
关键参数
-f,--force:不提示是否进行确认
样例:
shell
docker container prune

2.25 docker update
功能:更新容器配置
语法:
shell
docker update [OPTIONS] CONTAINER [CONTAINER...]
别名:
shell
docker container update
关键参数
--cpus:cpu数量--cpuset-cpus:使用哪些cpu--memory:内存限制--memory-swap:交换内存--cpu-period:是用来指定容器对CPU的使用要在多长时间内做一次重新分配(类似于时间片)--cpu-quota:是用来指定在这个周期内,最多可以有多少时间用来跑这个容器(例如100个时间片有多少可以用来跑这个容器)
样例:
shell
#更新内存
docker update -m 500m mywebsite5

更新后

这个报错是因为:容器之前设置了 memoryswap 限制,且 swap 值小于当前要设置的内存限制,导致冲突。
不过指定容器内存一般是准备阶段就考虑好的,而不会后面一个一个改。所以这个命令用的也不多。