1、容器概念

1.1、什么是容器

容器(Container):在docker中指的是从镜像创建的应用程序运行实例。

可以将容器看作将一个 应用程序及其依赖环境打包 而成的集装箱。

容器的实质是进程,与直接在主机执行不同,容器进程在属于自己的独立的命名空间内运行。这种特性使得容器封装的应用程序比直接在主机上运行的应用程序更加安全。

1.2、容器的基本信息

# docker ps -a 显示本地所有的容器
[root@hqs imglayers]# docker ps -a
容器ID             容器使用的镜像         启动容器时执行的命令       容器创建时间         容器运行状态               容器对外发布端口    容器名称
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS            NAMES
0d5df0735154        imglayers-test      "/bin/sh -c 'python …"   32 minutes ago      Exited (0) 32 minutes ago                    wizardly_lehmann
cd866d55dc6a        imglayers-test      "/bin/sh -c 'python …"   41 minutes ago      Exited (0) 41 minutes ago                    charming_zhukovsky

# --no-trunc显示完整ID
[root@hqs imglayers]# docker ps -a --no-trunc
CONTAINER ID                                                       IMAGE               COMMAND                             CREATED             STATUS                          PORTS               NAMES
0d5df073515409bd606139f4c0dd8d5bf91360fa15700a7e64935e8da35bb8cd   imglayers-test      "/bin/sh -c 'python /app/app.py'"   40 minutes ago      Exited (0) About a minute ago                       wizardly_lehmann
cd866d55dc6a8b626b3c8f2695bc43cc2bcf91adc58c549413dad3855cfd6947   imglayers-test      "/bin/sh -c 'python /app/app.py'"   48 minutes ago      Exited (0) 48 minutes ago                           charming_zhukovsky

容器的唯一标识容器ID与镜像ID一样采用UUID形式,由64个十六进制字符组成。通常采用前12个字符,也可以使用更短格式(前几个字符)。

# 完整ID标识
[root@hqs imglayers]# docker start 0d5df073515409bd606139f4c0dd8d5bf91360fa15700a7e64935e8da35bb8cd
0d5df073515409bd606139f4c0dd8d5bf91360fa15700a7e64935e8da35bb8cd
# 前12字符ID标识
[root@hqs imglayers]# docker start 0d5df0735154
0d5df0735154
# 更短字符ID标识
[root@hqs imglayers]# docker start 0d5
0d5

容器ID能保证唯一性,但是不方便记忆,可以使用容器名称来引用容器。
容器名称默认是Docker自动生成的,也可以在执行 docker run 的时候用 --name 选项自行指定。
还可以使用 docker rename 命令重命名容器。

# 创建容器docker自动生成名字
[root@hqs imglayers]# docker run -tid ubuntu:16.04 /bin/bash
C6e384fa3274d59bf7820cb3a23911fcf7e17dd8a2d6316a917422bfea93a2898
[root@hqs imglayers]# docker ps -a          
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6e384fa3274d        ubuntu:16.04        "/bin/bash"         2 minutes ago       Up 2 minutes                            quirky_liskov

# 容器名称引用容器
[root@hqs imglayers]# docker stop quirky_liskov
quirky_liskov

# 创建时用--name指定容器名
[root@hqs imglayers]# docker run --name hqs_test  imglayers-test
Hello,  World!@!!!!!!
[root@hqs imglayers]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
89076ab59bd1        imglayers-test      "/bin/sh -c 'python …"   47 seconds ago      Exited (0) 46 seconds ago                       hqs_test

1.3、可写的容器层

每个容器都有自己的可写容器层,所有的改变都存储在这个容器层。

容器被删除时,可写层也被删除,底层镜像没有影响。——》容器操作不会影响到镜像。

Docker使用存储驱动来管理镜像层和容器层的内容。

1.4、磁盘的容器大小

可以使用 docker ps -s可以输出SIZE列,显示容器所用的空间。

[root@hqs ~]# docker ps -s
CONTAINER ID        IMAGE            COMMAND          CREATED          STATUS          PORTS        NAMES           SIZE
6e384fa3274d        ubuntu:16.04     "/bin/bash"      7 hours ago      Up 4 minutes                 newbee         164B (virtual 135MB)

SIZE列第一个值:容器可写层当前所用的数据大小。
SIZE列第二个值:虚拟大小,在括号中用virtual标注,容器所用只读镜像的数据量和容器可写层大小的和。

磁盘上正在运行的容器所用的磁盘空间是每个容器大小和只读镜像值的总和。

# 再启动一个ubuntu容器
[root@hqs ~]# docker run -tid ubuntu:16.04 /bin/bash
ed278a030f5a9ae3f6cfe87a765c94b34975cc14cd4d90fa1bf11fb51ee345ba
# 复制一个文件到容器中
[root@hqs hqs]# docker cp ./asdadw.pdf ed278a030f5a:/home
# 查看容器大小
[root@hqs hqs]# docker ps -s
CONTAINER ID        IMAGE             COMMAND         CREATED           STATUS          PORTS     NAMES            SIZE
ed278a030f5a        ubuntu:16.04      "/bin/bash"     7 minutes ago     Up 7 minutes              kind_bartik      6.58MB (virtual 141MB)
6e384fa3274d        ubuntu:16.04      "/bin/bash"     7 hours ago       Up 15 minutes             newbee           164B (virtual 135MB)
# 两个容器所用的磁盘空间:164B+6.58M+135M由三值的和得到。

1.5、写时复制策略

写时复制策略:高效的文件共享和复制策略。特性如下:

  1. 容器任意层要读取某一层文件时,可以直接使用。
  2. 容器任意层要修改某一层文件时,文件将复制到该层并修改,隐藏原文件。
  3. 一层层拉取镜像时,可以不拉取已经下载好的共享镜像层。
  4. 复制提升容器效率,仅需修改的文件会复制到可写层,让可写层尽量少占用空间。

修改容器已有文件,存储驱动执行写时复制策略,aufs、overlay、overlay2驱动执行步骤:

  1. 从镜像各层中搜索要修改的文件。从最新的层开始直到最底层,一次一层。被找到的文件将被添加到缓存中以加速后续操作。
  2. 对找到的文件的第1个副本执行copy_up操作,将其复制到容器的可写层中。
  3. 任何修改只针对该文件的这个副本,容器不能看见该文件位于低层的只读副本
# 登录容器后删除文件和命令
[root@hqs hqs]# docker exec -ti 6e384fa3274d /bin/bash
root@6e384fa3274d:/usr/bin# rm find && rm wc && rm du && rm tr

# 查看容器空间变化——》可写层数据变多
[root@hqs hqs]# docker ps -s
CONTAINER ID      IMAGE            COMMAND         CREATED           STATUS          PORTS    NAMES            SIZE
ed278a030f5a      ubuntu:16.04     "/bin/bash"     14 minutes ago    Up 14 minutes            kind_bartik      6.58MB (virtual 141MB)
6e384fa3274d      ubuntu:16.04     "/bin/bash"     7 hours ago       Up 23 minutes            newbee           244B (virtual 135MB)

2、容器操作命令

容器操作命令:容器生命周期管理操作(创建、启动、停止、删除等)、容器运维操作(查看、连接、日志、事件等)。
操作容器可以使用容器的ID或容器的名称进行标识。
Docker新提供了一个统一的容器管理命令 docker container,功能和语法基本和 docker 子命令相同。

2.1、容器操作大全

# docker container 语法
Usage:  docker container COMMAND
Manage containers
Commands:
  attach      Attach local standard input, output, and error streams to a running container    # 连接正在运行的容器
  commit      Create a new image from a containers changes                                 # 从当前容器创建新镜像
  cp          Copy files/folders between a container and the local filesystem              # 在容器和文件系统间复制文件和目录
  create      Create a new container                                                       # 创建新容器
  diff        Inspect changes to files or directories on a containers filesystem           # 检查容器创建以来文件系统上文件或目录的更改
  exec        Run a command in a running container                                         # 从正在运行的容器中执行命令
  export      Export a containers filesystem as a tar archive                              # 将容器文件系统导出为归档文件
  inspect     Display detailed information on one or more containers                       # 显示容器详细信息
  kill        Kill one or more running containers                                          # 杀死一个正在运行的容器(强关)
  logs        Fetch the logs of a container                                                # 获取容器的日志信息
  ls          List containers                                                         # 输出容器列表(docker ps)
  pause       Pause all processes within one or more containers                            # 暂停一个或多个容器的所有进程
  port        List port mappings or a specific mapping for the container                   # 列出容器的端口映射或特定的映射
  prune       Remove all stopped containers                                           # 删除所有停止的容器(docker子命令没有的)
  rename      Rename a container                                                           # 对容器改名
  restart     Restart one or more containers                                               # 重启容器
  rm          Remove one or more containers                                                # 删除容器
  run         Run a command in a new container                                             # 创建新容器并执行命令
  start       Start one or more stopped containers                                         # 启动容器
  stats       Display a live stream of container(s) resource usage statistics              # 显示容器资源使用统计信息
  stop        Stop one or more running containers                                          # 停止容器
  top         Display the running processes of a container                                 # 显示容器正在运行的进程
  unpause     Unpause all processes within one or more containers                          # 恢复容器中被暂停的所有进程
  update      Update configuration of one or more containers                               # 更新容器配置
  wait        Block until one or more containers stop, then print their exit codes         # 阻塞容器运行,直到容器停止运行,输出退出码

2.2、run创建并启动容器

使用 docker run 创建一个新的容器并启动,docker在后台运行的操作如下:

1.检查本地是否存在指定的镜像,如没有就从仓库自动下载
2.基于镜像创建容器并启动
3.为容器分配文件系统,并在镜像层顶部增加一个可读写的容器层
4.从主机配置的网桥接口将一个虚拟接口桥接到容器
5.从网桥的地址池给容器分配一个IP地址
6.运行用户指定的应用程序
7.根据设置决定是否终止容器运行

# 语法
docker container run [OPTIONS选项] IMAGE镜像 [COMMAND命令] [ARG参数...]
# 常用选项
-d(--detach):后台运行容器,并返回容器ID。
-i(--interactive):容器的标准输入保持打开。
-t(--tty):为容器重新分配一个伪输入终端(Pseudo TTY)。
-p(--publish):设置端口映射,格式:'主机端口:容器端口'。
-P:发布容器中所有暴露的端口。
--dns:指定容器使用的dns服务器(默认是和主机的dns设置一致)。
--name:为容器指定名称。
--rm:容器退出时自动删除。
-v:将主机本地的目录和容器目录绑定,实现数据的持久化,将数据存储在本地文件系统中
--restart:设置重启策略,如设置always,表示容器即使异常退出也会自动重启

(1)启动容器执行命令后自动终止容器

[root@hqs hqs]# docker run ubuntu:16.04 /bin/echo '这是一个自动终止的容器'
这是一个自动终止的容器
[root@hqs hqs]# docker ps -a
CONTAINER ID      IMAGE             COMMAND             CREATED           STATUS                     PORTS        NAMES
d16fabb6b96e      ubuntu:16.04     "/bin/echo 这是一个…"  7 seconds ago    Exited (0) 6 seconds ago               blissful_mccarthy

(2)启动容器执行命令后退出自动删除

# --rm 容器退出自动删除
[root@hqs hqs]# docker run --name test-kobe  --rm  centos  /bin/bash 
[root@hqs hqs]# docker run --rm ubuntu:16.04  /bin/echo '这是一个自动终止的容器'
这是一个自动终止的容器
[root@hqs hqs]# docker ps -a

(3)启动容器并允许用户交互

# -t:分配一个伪终端并绑定到容器的标准输入;-i:让容器的标准输入保持打卡,自动进入容器交互模式
# 不加-d的话,只要退出容器(exit或者Ctrl+D均可退出容器),容器自动终止
[root@hqs hqs]# docker run -ti ubuntu:16.04 /bin/bash
root@5565c81f49bb:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@5565c81f49bb:/# exit
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS          NAMES
5565c81f49bb        ubuntu:16.04        "/bin/bash"         34 seconds ago      Exited (1) 3 seconds ago               cranky_kapitsa

(4)启动容器并让其以守护进程的形式在后台运行

很多情况下容器都会采用守护进程方式运行。需要使用 -d 选项。

[root@hqs hqs]# docker pull httpd
[root@hqs hqs]# docker run -d -p 80:80 --name testweb httpd
dbad1b30d9e76523be5b13967edefe5585f4a333d1dfb4637d32c38b97986c59
[root@hqs hqs]# docker ps 
CONTAINER ID        IMAGE        COMMAND              CREATED             STATUS              PORTS                NAMES
dbad1b30d9e7        httpd        "httpd-foreground"   8 seconds ago       Up 7 seconds        0.0.0.0:80->80/tcp   testweb
# 使用docker logs查看容器的输出信息
[root@hqs hqs]# docker logs testweb
AH00558: httpd: Could not reliably determine the servers fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the servers fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Wed Mar 16 01:42:27.920912 2022] [mpm_event:notice] [pid 1:tid 140667220098368] AH00489: Apache/2.4.52 (Unix) configured -- resuming normal operations
[Wed Mar 16 01:42:27.920990 2022] [core:notice] [pid 1:tid 140667220098368] AH00094: Command line: 'httpd -D FOREGROUND'

# 直接-d启动ubuntu容器:命令/bin/bash默认情况下,容器立即退出,如同bash没有连接到终端且无法运行
[root@hqs ~]# docker run -d ubuntu:16.04 /bin/bash  

[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
dd1120bff856        ubuntu:16.04        "/bin/bash"         6 seconds ago       Exited (0) 5 seconds ago                       gallant_bel
# -t选项分配“伪tty”,可以让bash继续无限期地运行(它认为连接到了交互式TTY)
[root@hqs ~]# docker run -td ubuntu:16.04 /bin/bash
849eeb5ea98bedd1120bff856114be2afa110c874c9cec2f73f22ad736f6f244b246e7f1f4ed404bd6d019f8b480d72170be6f2d4fab576f2362327dcb42bf28
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                PORTS             NAMES
849eeb5ea98b        ubuntu:16.04        "/bin/bash"         2 seconds ago       Up 1 second                             crazy_gates

(5)-P发布容器所有暴露的端口

通过docker run命令创建容器时使用-P选项将容器中所有暴露的端口发布到Docker主机上随机的高端地址端口中。
要求容器中要发布的端口必须提前暴露出来。
有两种方式可以暴露端口:一种是在Dockerfile中使用EXPOSE指令定义,另一种是执行docker run命令创建容器时使用--expose选项指定。

# 1.创建容器使用-P选项发布httpd服务
[root@hqs ~]# docker pull httpd
[root@hqs ~]# docker run --rm -d --name websrv -P httpd
adc5a789b20c170b229d6aafa879fd2cad54eb363259be994e6d21841ecf08f5

# 2.使用docker port 查看容器的端口映射设置
[root@hqs ~]# docker port websrv
80/tcp -> 0.0.0.0:49153               《————左边是容器发布的端口80,右边是映射到主机上的IP地址和端口49153
80/tcp -> :::49153

# 3.使用curl命令访问服务测试
[root@hqs ~]# curl http://192.168.100.111:49153
<html><body><h1>It works!</h1></body></html>

(6)-p发布容器特定端口

通过 docker run 命令启动容器,可以使用 -p 选项将容器的一个或多个端口映射到主机上。

可以多次使用 -p 设置任意数量的端口映射。

选项格式

说明

示例

-p 主机端口:容器端口

映射主机上所有网络接口的地址

-p 8080:80

-p 主机IP地址:主机端口:容器端口

映射指定地址的指定端口

-p 192.168.10.10:80:5000

-p 主机IP地址::容器端口

映射指定地址的任一端口

-p 127.0.0.1::5010

-p 容器端口

自动分配主机端口

-p 5200

-p 以上各种格式/udp

发布UDP端口(默认为TCP端口)

-p 8080:80/udp

-p 以上各种格式/tcp -p 以上各种格式/udp

同时发布TCP和UDP端口

-p 8080:80/tcp -p 8080:80/udp

# 案例1:映射主机上所有网络接口的地址
[root@hqs ~]# docker run -dti --name websrv -p 8000:80 httpd
edc35a9e8b6dded9abb82906e02258cba32c608bf7e3face09e9d3d4308a60fc
[root@hqs ~]# docker port websrv
80/tcp -> 0.0.0.0:8000
80/tcp -> :::8000
[root@hqs ~]# curl http://192.168.100.111:8000
<html><body><h1>It works!</h1></body></html>

# 案例2:映射指定地址的指定端口
[root@hqs ~]# docker run -dti --name websrv2 -p 192.168.100.111:8001:80 httpd
1d19b8a06483811bab9b5b5767cf8c38aabe911f3ed2df5250a1e155a7276e7e
[root@hqs ~]# docker port websrv2
80/tcp -> 192.168.100.111:8001
[root@hqs ~]# curl http://192.168.100.111:8001
<html><body><h1>It works!</h1></body></html>

# 案例3:映射指定地址的任一端口
[root@hqs ~]# docker stop websrv websrv2
websrv
websrv2
[root@hqs ~]# docker run -dti --name websrv3 -p 127.0.0.1::80 httpd
19057827c1c7477e860a2f6ebd6c1dd4c1f2fd4386c61a3c6aafcf39a317ea65
[root@hqs ~]# docker port websrv3
80/tcp -> 127.0.0.1:49153
[root@hqs ~]# curl http://127.0.0.1:49153
<html><body><h1>It works!</h1></body></html>

# 案例4:自动分配主机端口
[root@hqs ~]# docker run -dti --name websrv4 -p 80 httpd
3ccb4a496636eb774452c900acdd8f3ca0f4d5bf99c58618e266e6f83ae6c55b
[root@hqs ~]# docker stop websrv3
websrv3
[root@hqs ~]# docker port websrv4
80/tcp -> 0.0.0.0:49154
80/tcp -> :::49154
[root@hqs ~]# curl http://192.168.100.111:49154
<html><body><h1>It works!</h1></body></html>

# 案例5:发布UDP端口
[root@hqs ~]# docker run -dti --name websrv5 -p 8080:80/udp httpd
9ae61cbd4e67b606ee38ace205036c458edf6eecb67b908a87e9363ae63a8f55
[root@hqs ~]# docker port websrv5
80/udp -> 0.0.0.0:8080
80/udp -> :::8080

# 案例6:同时发布TCP和UDP端口
[root@hqs ~]# docker run -dti --name websrv6 -p 8080:80/tcp -p 8080:80/udp httpd
d13977a616392d890c6335ba4446d88eeb033e65c8fafb9379c0593e50dde861
[root@hqs ~]# docker port websrv6
80/tcp -> 0.0.0.0:8080
80/tcp -> :::8080
80/udp -> 0.0.0.0:8080
80/udp -> :::8080

2.3、create创建容器

使用 docker create 命令创建一个新的容器,但不启动。
语法和参数和docker run 基本相同。

# 语法
docker container create [OPTIONS选项] IMAGE镜像 [COMMAND命令] [ARG参数...]

# 案例:基于busybox镜像创建一个容器
[root@hqs ~]# docker create -t -i busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
5cc84ad355aa: Pull complete 
Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Status: Downloaded newer image for busybox:latest
95127ca1f247c7d94e9e838432e5f137adef78efe3ea3ae10bc59e58eaffb451
[root@hqs ~]# docker ps -a
CONTAINER ID     IMAGE      COMMAND     CREATED          STATUS         PORTS       NAMES
95127ca1f247     busybox    "sh"        3 minutes ago    Created                   keen_visvesvaraya

容器处于Created(已创建)状态,后面可以使用 docker start 启动容器。

2.4、start启动容器

使用 docker start 启动一个或多个停止的容器。

# 语法
[root@hqs ~]# docker start --help
Usage:  docker start [OPTIONS] CONTAINER [CONTAINER...]
Start one or more stopped containers
Options:
  -a, --attach               Attach STDOUT/STDERR and forward signals                # 连接标准输出/标准错误并转发信号
      --detach-keys string   Override the key sequence for detaching a container     # 覆盖分离容器的键顺序
  -i, --interactive          Attach containers STDIN            # 附加容器的标准输入

# 启动前面创建的busybox容器
[root@hqs ~]# docker start 95127ca1f247
95127ca1f247
[root@hqs ~]# docker ps 
CONTAINER ID        IMAGE        COMMAND     CREATED             STATUS            PORTS        NAMES
95127ca1f247        busybox      "sh"        10 minutes ago      Up 8 seconds                   keen_visvesvaraya

2.5、停止\强停\暂停容器

(1)stop停止容器

停止一个或多个处于运行状态的容器。

# 语法:
[root@hqs ~]# docker container stop --help
Usage:  docker container stop [OPTIONS] CONTAINER [CONTAINER...]
Stop one or more running containers
Options:
  -t, --time int   Seconds to wait for stop before killing it       # 等多少秒之后停止容器(默认是10秒)
                   (default 10)

# 案例
[root@hqs ~]# docker stop 95127ca1f247
95127ca1f247
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                         PORTS          NAMES
95127ca1f247        busybox             "sh"                 About an hour ago   Exited (137) 5 seconds ago                    keen_visvesvaraya
[root@hqs ~]# docker container stop f8cf60a42d01
f8cf60a42d01
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                         PORTS               NAMES
95127ca1f247        busybox             "sh"                 About an hour ago   Exited (137) 2 minutes ago                         keen_visvesvaraya
f8cf60a42d01        httpd               "httpd-foreground"   About an hour ago   Exited (0) 14 seconds ago                          testweb

# -t等一段时间后停止容器
[root@hqs ~]# docker stop -t 3 6b15972463bc 994f78b1a1bd
执行后等待了三秒继续输出id
6b15972463bc
994f78b1a1bd

(2)kill杀死(强停)容器

使用 docker kill 命令可以杀死(强行停止)一个或多个容器。

# 语法
[root@hqs ~]# docker container kill --help
Usage:  docker container kill [OPTIONS选项] CONTAINER容器 [CONTAINER...]
Kill one or more running containers
Options:
  -s, --signal string   Signal to send to the container       # 传给容器的信号,默认是传递kill
                        (default "KILL")

# 案例
[root@hqs ~]# docker kill bf1128a4d870
bf1128a4d870
[root@hqs ~]# docker container kill 5565c81f49bb
5565c81f49bb
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                         PORTS          NAMES
bf1128a4d870        centos              "/bin/bash"          2 hours ago         Exited (137) 26 seconds ago                   reverent_shamir
5565c81f49bb        ubuntu:16.04        "/bin/bash"          9 hours ago         Exited (137) 17 seconds ago                   quizzical_buck

(3)pause暂停(挂起)容器

使用 docker pause 命令可以暂停容器中所有的进程。
使用 docker unpause 命令可以恢复容器中被暂停的所有进程。

# 语法
[root@hqs ~]# docker pause --help
Usage:  docker pause CONTAINER [CONTAINER...]
Pause all processes within one or more containers
[root@hqs ~]# docker unpause --help
Usage:  docker unpause CONTAINER [CONTAINER...]
Unpause all processes within one or more containers

# 案例
[root@hqs ~]# docker start 379effe4cc2a bf1128a4d870
379effe4cc2a
bf1128a4d870
[root@hqs ~]# docker pause 379effe4cc2a
379effe4cc2a
[root@hqs ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS        NAMES
379effe4cc2a        centos              "/bin/bash"         2 hours ago         Up About a minute (Paused)                dreamy_hertz
bf1128a4d870        centos              "/bin/bash"         2 hours ago         Up About a minute                         reverent_shamir
[root@hqs ~]# docker unpause 379effe4cc2a
379effe4cc2a
[root@hqs ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
379effe4cc2a        centos              "/bin/bash"         2 hours ago         Up About a minute                       dreamy_hertz
bf1128a4d870        centos              "/bin/bash"         2 hours ago         Up About a minute                       reverent_shamir

2.6、删除容器相关

(1)rm删除容器

可以使用 docker rm 命令删除一个或多个容器。

# 语法
[root@hqs ~]# docker rm --help
Usage:  docker rm [OPTIONS选项] CONTAINER [CONTAINER...]
Remove one or more containers
Options:
  -f, --force     Force the removal of a running container (uses SIGKILL)     # 使用SIGKILL信号强制删除运行中的容器
  -l, --link      Remove the specified link                                   # 删除容器的网络连接
  -v, --volumes   Remove the volumes associated with the container            # 删除容器关联的卷

# 正常删除运行中容器:先停止后删除
[root@hqs ~]# docker rm 379effe4cc2a
Error response from daemon: You cannot remove a running container 379effe4cc2a25175892e3720c30293bf0d21f0f60513052aeb29e0b7f0bd7df. Stop the container before attempting removal or force remove
[root@hqs ~]# docker stop 379effe4cc2a
379effe4cc2a
[root@hqs ~]# docker rm 379effe4cc2a  
379effe4cc2a

# -f强制删除运行中容器
[root@hqs ~]# docker rm -f bf1128a4d870
bf1128a4d870

# 正则表达式筛选批量删除容器
[root@hqs hqs]# docker ps -a | grep imglayers-test | awk '{print $1}'
1d54e625e6db
0d5df0735154
cd866d55dc6a
[root@hqs hqs]# docker rm $(docker ps -a | grep imglayers-test | awk '{print $1}') 
1d54e625e6db
0d5df0735154
cd866d55dc6a

# -q选项获取id批量删除
[root@hqs ~]# docker ps -aq
95127ca1f247
f8cf60a42d01
482f41cde0d4
f06b3e532208
3700446ead6f
5565c81f49bb
[root@hqs ~]# docker rm -f $(docker ps -qa)
95127ca1f247
f8cf60a42d01
482f41cde0d4
f06b3e532208
3700446ead6f
5565c81f49bb
[root@hqs ~]# docker ps -a

(2)prune删除容器

使用 docker container prune 命令删除所有停止执行的容器。docker子命令没有对应的命令。

# 语法:
[root@hqs ~]# docker container prune --help
Usage:  docker container prune [OPTIONS]
Remove all stopped containers
Options:
      --filter filter   Provide filter values (e.g. 'until=<timestamp>')     # 提供过滤值
  -f, --force           Do not prompt for confirmation                    # 不要提示确认

# 示例:prune命令将created和exited状态的容器均删除
# 经测试处于pause状态的容器不会被删除
[root@hqs ~]# docker create busybox
525ca333e512130c41f2a2695e13598b4ef5f48cdfe8aa2a7105b89b2b89995f
[root@hqs ~]# docker run ubuntu:16.04 /bin/bash
[root@hqs ~]# docker run ubuntu:16.04 /bin/bash
[root@hqs ~]# docker run ubuntu:16.04 /bin/bash
[root@hqs ~]# docker run -dti ubuntu:16.04 /bin/bash
^[[Aad712d8eb9812209a768ebc3a9da74546473a9ca45202c829cac08b5e5a01b99
[root@hqs ~]# docker run -dti ubuntu:16.04 /bin/bash
9de5fc3131423c539fef73f7d558128eda4a491a85e27a99fddc34182ec91082
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                      PORTS               NAMES
9de5fc313142        ubuntu:16.04        "/bin/bash"         2 seconds ago        Up 2 seconds                                    charming_shirley
ad712d8eb981        ubuntu:16.04        "/bin/bash"         4 seconds ago        Up 3 seconds                                    flamboyant_jepsen
9fe062f491d8        ubuntu:16.04        "/bin/bash"         52 seconds ago       Exited (0) 51 seconds ago                       elated_bohr
1aefffa4672a        ubuntu:16.04        "/bin/bash"         53 seconds ago       Exited (0) 52 seconds ago                       nostalgic_northcutt
a6367c7367bd        ubuntu:16.04        "/bin/bash"         56 seconds ago       Exited (0) 55 seconds ago                       sad_kilby
525ca333e512        busybox             "sh"                About a minute ago   Created                                         kind_bohr
[root@hqs ~]# docker container prune 
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
9fe062f491d8bba4346bfb92d21f2057e12ac1901021c74b325526ee2e00a3e5
1aefffa4672addabc068b43bc74a217cb73c71eade5ad9fe4fdb418ab2507a70
a6367c7367bd311af5e7532e187e2d858045f2c19768c52c5f112e86190d0055
525ca333e512130c41f2a2695e13598b4ef5f48cdfe8aa2a7105b89b2b89995f
Total reclaimed space: 0B
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
9de5fc313142        ubuntu:16.04        "/bin/bash"         58 seconds ago       Up 57 seconds                           charming_shirley
ad712d8eb981        ubuntu:16.04        "/bin/bash"         About a minute ago   Up 59 seconds                           flamboyant_jepsen

2.7、rename重命名容器

使用 docker rename 命令为容器重新命名。

# 语法
[root@hqs ~]# docker rename --help
Usage:  docker rename CONTAINER容器 NEW_NAME新名字
Rename a container

# 案例
# ID标识改
[root@hqs ~]# docker rename d16fabb6b96e  newbee02
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE             COMMAND             CREATED            STATUS                   PORTS       NAMES
d16fabb6b96e        ubuntu:16.04      "/bin/echo 这是一个…"    7 hours ago    Exited (0) 7 hours ago              newbee02
# 容器名标识改
[root@hqs imglayers]# docker rename quirky_liskov newbee
[root@hqs imglayers]# docker ps -a
CONTAINER ID        IMAGE               COMMAND            CREATED             STATUS                          PORTS               NAMES
6e384fa3274d        ubuntu:16.04        "/bin/bash"        4 minutes ago       Exited (0) About a minute ago                       newbee

2.8、显示容器列表

可以使用 docker ps 或 docker container ls 命令显示容器列表。
不带任何选项执行命令会列出所有正在运行的容器信息。

# 语法
[root@hqs ~]# docker ps --help
Usage:  docker ps [OPTIONS选项]
List containers
Options:
  -a, --all             Show all containers (default shows just running)                        # 显示所有的容器(包括未运行的容器)
  -f, --filter filter   Filter output based on conditions provided                              # 根据条件过滤显示的容器
      --format string   Pretty-print containers using a Go template                             # go模式格式化打印容器
  -n, --last int        Show n last created containers (includes all states) (default -1)       # 列出最近创建的几个容器(含所有状态)
  -l, --latest          Show the latest created container (includes all states)                 # 列出最新创建的容器(含所有状态)
      --no-trunc        Dont truncate output                                                # 不截断输出(ID和COMMAND)
  -q, --quiet           Only display numeric IDs                                            # 只显示容器ID
  -s, --size            Display total file sizes                                            # 显示总文件大小

# 不带选项列出正在运行的容器
[root@hqs ~]# docker ps
CONTAINER ID        IMAGE               COMMAND          CREATED             STATUS              PORTS         NAMES
9de5fc313142        ubuntu:16.04        "/bin/bash"      39 minutes ago      Up 39 minutes                     charming_shirley

# -a选项列出所有的容器
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS        NAMES
f2fff5915399        ubuntu:16.04        "/bin/bash"         16 seconds ago      Exited (0) 15 seconds ago                magical_chaplygin
9de5fc313142        ubuntu:16.04        "/bin/bash"         38 minutes ago      Up 38 minutes                            charming_shirley

# --no-trunc显示完整信息
[root@hqs ~]# docker ps --no-trunc
CONTAINER ID                                                       IMAGE               COMMAND             CREATED             STATUS                   PORTS               NAMES
9de5fc3131423c539fef73f7d558128eda4a491a85e27a99fddc34182ec91082   ubuntu:16.04        "/bin/bash"         49 minutes ago      Up 49 minutes (Paused)                       charming_shirley
ad712d8eb9812209a768ebc3a9da74546473a9ca45202c829cac08b5e5a01b99   ubuntu:16.04        "/bin/bash"         49 minutes ago      Up 49 minutes (Paused)                       flamboyant_jepsen

# -l列出最新容器
[root@hqs ~]# docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
f2fff5915399        ubuntu:16.04        "/bin/bash"         12 minutes ago      Exited (0) 12 minutes ago                       magical_chaplygin

# -n列出最近的几个容器
[root@hqs ~]# docker ps -n 3
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
f2fff5915399        ubuntu:16.04        "/bin/bash"         12 minutes ago      Exited (0) 12 minutes ago                       magical_chaplygin
9de5fc313142        ubuntu:16.04        "/bin/bash"         51 minutes ago      Up 51 minutes (Paused)                          charming_shirley
ad712d8eb981        ubuntu:16.04        "/bin/bash"         51 minutes ago      Up 51 minutes (Paused)                          flamboyant_jepsen

# -s显示容器所用的空间。
[root@hqs ~]# docker ps -s
CONTAINER ID        IMAGE            COMMAND          CREATED          STATUS          PORTS        NAMES           SIZE
6e384fa3274d        ubuntu:16.04     "/bin/bash"      7 hours ago      Up 4 minutes                 newbee         164B (virtual 135MB)

# -f选项可以通过多种条件过滤容器
# 根据id过滤
[root@hqs ~]# docker ps -af id=f2fff5915399   
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
f2fff5915399        ubuntu:16.04        "/bin/bash"         5 minutes ago       Exited (0) 5 minutes ago                       magical_chaplygin
# 根据name过滤
[root@hqs ~]# docker ps -af name=flamboyant_jepsen
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ad712d8eb981        ubuntu:16.04        "/bin/bash"         44 minutes ago      Up 44 minutes                           flamboyant_jepsen
# 状态过滤(created、restarting、running、removing、paused、exited、dead)
[root@hqs ~]# docker ps -f status=exited                   
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
f2fff5915399        ubuntu:16.04        "/bin/bash"         6 minutes ago       Exited (0) 6 minutes ago                       magical_chaplygin
[root@hqs ~]# docker ps -f status=created
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@hqs ~]# docker ps -f status=running
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
9de5fc313142        ubuntu:16.04        "/bin/bash"         45 minutes ago      Up 45 minutes                           charming_shirley
ad712d8eb981        ubuntu:16.04        "/bin/bash"         45 minutes ago      Up 45 minutes                           flamboyant_jepsen
# 其他过滤(待补充)

# 利用-q选项完成批量操作
[root@hqs ~]# docker pause $(docker ps -f status=running -q)
9de5fc313142
ad712d8eb981
[root@hqs ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS         NAMES
9de5fc313142        ubuntu:16.04        "/bin/bash"         47 minutes ago      Up 47 minutes (Paused)                 charming_shirley
ad712d8eb981        ubuntu:16.04        "/bin/bash"         47 minutes ago      Up 47 minutes (Paused)                 flamboyant_jepsen

# --format格式化输出(没理解用途)
[root@hqs ~]# docker ps -a --format asd1dasdw
asd1dasdw
asd1dasdw
asd1dasdw

2.9、inspect查看容器详细信息

使用 docker container inpect 命令查看容器的详细信息(元数据)。
默认情况下,以JSON数组格式输出所有结果。

[root@hqs ~]# docker container inspect --help
Usage:  docker container inspect [OPTIONS选项] CONTAINER容器 [CONTAINER...]
Display detailed information on one or more containers
Options:
  -f, --format string   Format the output using the given Go template     # 格式化输出
  -s, --size            Display total file sizes                          # 显示所有文件大小

# -s显示文件大小
[root@hqs ~]# docker container inspect -s  7021d506cf27 > test1
[root@hqs ~]# docker container inspect  7021d506cf27 > test2
[root@hqs ~]# diff test1 test2
135,136d134
<         "SizeRw": 0,
<         "SizeRootFs": 134821261,
# 以上两行为 -s 参数多出来的数据

# -f(--format)筛选输出内容
# 案例:获取容器的名称
[root@hqs ~]# docker container inspect -f='{{.Name}}' 7021d506cf27  
/elegant_perlman
[root@hqs ~]# docker container inspect --format='{{.Name}}' 7021d506cf27 
/elegant_perlman

# 案例:通过JSON格式的State子节获取容器的状态元数据
# 注意:json要小写、json和.之间要空格
[root@hqs ~]# docker container inspect --format='{{.State}}' 7021d506cf27      
{running true false false false false 1510 0  2022-03-22T14:17:09.74156524Z 2022-03-22T22:16:31.416509298+08:00 <nil>}
[root@hqs ~]# docker container inspect --format='{{json .State}}' 7021d506cf27 
{"Status":"running","Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":1510,"ExitCode":0,"Error":"","StartedAt":"2022-03-22T14:17:09.74156524Z","FinishedAt":"2022-03-22T22:16:31.416509298+08:00"}

# -f多层次筛选信息
[root@hqs ~]# docker container inspect --format='{{.NetworkSettings}}' 7021d506cf27                  # 第一层
{{ 111b5c2bdbc9c32fb9092b7aef3d954561256c890ad1d295457201a1482ead96 false  0 map[] /var/run/docker/netns/111b5c2bdbc9 [] []} {1f36ba204543684fb326104de0d63e3800b19ec116516304c84cc366897cbf18 172.17.0.1  0 172.17.0.3 16  02:42:ac:11:00:03} map[bridge:0xc000374000]}
[root@hqs ~]# docker container inspect --format='{{.NetworkSettings.Networks}}' 7021d506cf27         # 第二层
map[bridge:0xc0004b6000]
[root@hqs ~]# docker container inspect --format='{{.NetworkSettings.Networks.bridge}}' 7021d506cf27           # 第三层
{<nil> [] [] aafc7efe7bfd2294e8ad66662f94670dfcd8d4a29df825eab1b975ca5afceb21 1f36ba204543684fb326104de0d63e3800b19ec116516304c84cc366897cbf18 172.17.0.1 172.17.0.3 16   0 02:42:ac:11:00:03 map[]}
[root@hqs ~]# docker container inspect --format='{{.NetworkSettings.Networks.bridge.Gateway}}' 7021d506cf27   # 第四层
172.17.0.1

2.10、进入容器(重点)

用户可以通过执行相应的 docker 命令进入正在运行的容器进行交互操作。

(1)attach命令

可以使用 docker attach 连接正在运行的容器。
实质是将 Docker 主机本地的标准输入、标准输出和错误流连接到了一个正在运行的容器上。

  • 标准输入文件(STDIN):通常对应终端的键盘。
  • 标准输出文件(STDOUT)、标准错误输出文件(STDERROR):通常对应终端的屏幕。
# 语法
[root@hqs ~]# docker attach --help
Usage:  docker attach [OPTIONS选项] CONTAINER容器
Attach local standard input, output, and error streams to a running container
Options:
      --detach-keys string   Override the key sequence for detaching a container            # 覆盖分离容器的键顺序
      --no-stdin             Do not attach STDIN                   # 不连接标准输入(问题:ctrl+C依然将容器停掉?)                              
      --sig-proxy            Proxy all received signals to the process (default true)       # 将所有接收的信号代理给进程

# 示例:连接到一个运行中的容器并从中退出
[root@hqs ~]# docker run -d --name topdemo ubuntu /usr/bin/top -b
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete 
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
23e12fa1111971ff1d50d0eec9f4b8614c3ac045010d9fd6b4f3929c300d06af
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                NAMES
23e12fa11119        ubuntu              "/usr/bin/top -b"    7 seconds ago       Up 6 seconds                             topdemo
[root@hqs ~]# docker attach topdemo
top - 15:09:32 up 53 min,  0 users,  load average: 0.04, 0.03, 0.05
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  0.3 sy,  0.0 ni, 99.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1982.6 total,    909.5 free,    356.1 used,    717.0 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.   1468.3 avail Mem 
# 此案例中会一直刷新输出top信息,如果按ctrl+c退出容器,容器也会停止。
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE        COMMAND              CREATED              STATUS                      PORTS         NAMES
23e12fa11119        ubuntu       "/usr/bin/top -b"    About a minute ago   Exited (0) 51 seconds ago                 topdemo

# 示例:--sig-proxy选项如果设置为false,则可以不将信息代理给进程,ctrl+C或ctrl+D不能停止容器
[root@hqs ~]# docker attach --sig-proxy=false topdemo
top - 15:14:55 up 58 min,  0 users,  load average: 0.00, 0.01, 0.05
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  0.3 sy,  0.0 ni, 99.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1982.6 total,    909.3 free,    356.0 used,    717.3 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.   1468.4 avail Mem 
   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     1 root      20   0    5960   1700   1276 R   0.0   0.1   0:00.01 top
# 按ctrl+c退出容器,容器没有停止
[root@hqs ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                NAMES
23e12fa11119        ubuntu              "/usr/bin/top -b"    6 minutes ago       Up 29 seconds                            topdemo

使用 attach 命令的问题:当多个窗口同时 attach 到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。

(2)exec命令

使用 docker exec 命令在运行中的容器执行命令。

[root@hqs ~]# docker exec --help
Usage:  docker exec [OPTIONS选项] CONTAINER容器 COMMAND命令 [ARG参数...]
Run a command in a running container
Options:
  -d, --detach               Detached mode: run command in the background            # 后台运行(分离模式)
      --detach-keys string   Override the key sequence for detaching a container     # 覆盖分离容器的键顺序
  -e, --env list             Set environment variables                               # 设置环境变量
  -i, --interactive          Keep STDIN open even if not attached                    # 保持标准输入开启
      --privileged           Give extended privileges to the command                 # 给予扩展权限
  -t, --tty                  Allocate a pseudo-TTY                                   # 分配一个伪输入终端
  -u, --user string          Username or UID (format: <name|uid>[:<group|gid>])      # 用户名或ID
  -w, --workdir string       Working directory inside the container                  # 容器内工作目录

# 案例:进入容器,交互执行命令
[root@hqs ~]# docker exec -ti topdemo /bin/bash
root@23e12fa11119:/# ps
   PID TTY          TIME CMD
     6 pts/0    00:00:00 bash
    13 pts/0    00:00:00 ps
root@23e12fa11119:/# exit
exit
[root@hqs ~]# 

# 案例:不进入容器执行命令
[root@hqs ~]# docker exec -i topdemo echo '1111'
1111
[root@hqs ~]# docker exec -i topdemo /bin/ls
bin
boot
dev
etc
home
lib