Docker(四)容器

Docker(四)容器

第一节 Docker容器

1.1 简介

  容器是镜像的运行时实例。正如从虚拟机模板上启动VM一样,用户也同样可以从单个镜像上启动一个或多个容器。虚拟机和容器最大的区别是容器更快并且更轻量级——与虚拟机运行在完整的操作系统之上相比,容器会共享其所在主机的操作系统/内核。

  启动容器的简便方式是使用docker container run命令。该命令可以携带很多参数,在其基础的格式docker container run < image> < app>中,指定了启动所需的镜像以及要运行的应用。docker container run -it ubuntu /bin/bash则会启动某个Ubuntu Linux容器,并运行Bash Shell作为其应用;如果想启动 PowerShell并运行一个应用,则可以使用命令docker container run -it microsoft- /powershell:nanoserver pwsh.exe。

  -it参数可以将当前终端连接到容器的Shell终端之上。

  容器随着其中运行应用的退出而终止。在上面两个示例中,Linux容器会在Bash Shell退出后终止,而Windows容器会在PowerShell进程终止后退出。一个简单的验证方法就是启动新的容器,并运行sleep命令休眠10s。容器会启动,然后运行休眠命令,在10s后退出。如果在Linux主机(或者在Linux容器模式下的Windows主机上)运行docker container run alpine:latest sleep 10命令,Shell会连接到容器Shell 10s的时间,然后退出;可以在Windows容器上运行docker container run microsoft/powershell:nanoserver StartSleep -s 10来验证这一点。可以使用docker container stop命令手动停止容器运行,并且使用docker container start再次启动该容器。如果再也不需要该容器,则使用docker container rm命令来删除容器。


1.2 详解

1.2.1 容器vs虚拟机

  容器和虚拟机都依赖于宿主机才能运行。宿主机可以是笔记本,是数据中心的物理服务器,也可以是公有云的某个实例。假设宿主机是一台需要运行4个业务应用的物理服务器。在虚拟机模型中,首先要开启物理机并启动Hypervisor引导程序(跳过了BIOS和Bootloader代码等)。一旦Hypervisor启动,就会占有机器上的全部物理资源,如CPU、RAM、存储和NIC。Hypervisor接下来就会将这些物理资源划分为虚拟资源,并且看起来与真实物理资源完全一致。然后Hypervisor会将这些资源打包进一个叫作虚拟机(VM)的软件结构当中。这样用户就可以使用这些虚拟机,并在其中安装操作系统和应用。前面提到需要在物理机上运行4个应用,所以在Hypervisor之上需要创建4个虚拟机并安装4个操作系统,然后安装4个应用。当操作完成后,结构如图7.2所示。

运行4个业务应用的物理服务器

  而容器模型则略有不同。服务器启动之后,所选择的操作系统会启动。在Docker世界中可以选择Linux,或者内核支持内核中的容器原语的新版本Windows。与虚拟机模型相同,OS也占用了全部硬件资源。在OS层之上,需要安装容器引擎(如Docker)。容器引擎可以获取系统资源,比如进程树、文件 系统以及网络栈,接着将资源分割为安全的互相隔离的资源结构,称之为容器。每个容器看起来就像一个真实的操作系统,在其内部可以运行应用。按照前面的假设,需要在物理机上运行4个应用。因此,需要划分出4个容器并在每个容器中运行一个应用,如图7.3所示。

划分4个容器

  从更高层面上来讲,Hypervisor是硬件虚拟化(Hardware Virtualization)——Hypervisor将硬件物理资源划分为虚拟资源;另外,容器是操作系统虚拟化(OS Virtualization)——容器将系统资源划分为虚拟资源。

1.2.2 虚拟机的额外开销

  接下来着重探讨Hypervisor模型的一个主要问题。

  首先我们的目标是在一台物理机上运行4个业务相关应用。每种模型示例中都安装了一个操作系统或者Hypervisor(一种针对虚拟机高度优化后的操作系统)。截至目前,两个模型还很相似,但是也就到此为止了。

  虚拟机模型将底层硬件资源划分到虚拟机当中。每个虚拟机都是包含了虚拟CPU、虚拟RAM、虚拟磁盘等资源的一种软件结构。因此,每个虚拟机都需要有自己的操作系统来声明、初始化并管理这些虚拟资源。但不幸的是,操作系统本身是有其额外开销的。例如,每个操作系统都消耗一点CPU、一点RAM、一点存储空间等。每个操作系统都需要独立的许可证,并且都需要打补丁升级,每个操作系统也都面临被攻击的风险。通常将这种现象称作OS Tax或者VM Tax,每个操作系统都占用一定的资源

  容器模型具有在宿主机操作系统中运行的单个内核。在一台主机上 运行数十个甚至数百个容器都是可能的,容器共享一个操作系统/内核,意味着只有一个操作系统消耗CPU、RAM和存储资源,只有一个操作系统需要授权,只有一个操作系统需要升级和打补丁,同时只有一个操作系统面临被攻击的风险。简言之就是只有一份OS损耗!

  因为容器并不是完整的操作系统,所以其启动要远比虚拟机快。在容器内部并不需要内核,也就没有定位、解压以及初始化的过程——更不用提在内核启动过程中对硬件的遍历和初始化了。唯一需要的是位于下层操作系统的共享内核是启动了的!最终结果就是,容器可以在1s内启动。唯一对容器启动时间有影响的就是容器内应用启动所花费的时间。

  这些就是容器模型要比虚拟机模型简洁并且高效的原因了。使用容器可以在更少的资源上运行更多的应用,启动更快,并且支付更少的授权和管理费用,同时面对未知攻击的风险也更小。

1.2.3 检查Docker daemon

  通常登录Docker主机后的第一件事情是检查Docker是否正在运行。当命令输出中包含Client和Server的内容时,可以继续下面的示例。如果在Server部分中包含了错误码,这表示Docker daemon很可能没有运行,或者当前用户没有权限访问。

1
$ docker version 

  如果在Linux中遇到无权限访问的问题,需要确认当前用户是否属于本地Docker UNIX组。如果不是,可以通过usermod -aG docker < user>来添加,然后退出并重新登录Shell,改动即可生效。如果当前用户已经属于本地docker用户组,那么问题可能是Docker daemon没有运行导致。根据下列指令检查Docker daemon的状态。

1
2
3
4
//使用Systemd在Linux系统中执行该命令 
$ service docker status docker start/running, process 29393
//使用Systemd在Linux系统中执行该命令
$ systemctl is-active docker active

1.2.4 启动一个简单容器

  启动容器的一个简单的方式是通过docker container run命令。下面的命令启动了一个简单的容器,其中运行了容器化版本的centos Linux。

1
2
3
4
5
6
7
8
9
10
11
$ docker container run -it ubuntu:latest /bin/bash 
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
952132ac251a: Pull complete
82659f8f1b76: Pull complete
c19118ca682d: Pull complete
8296858250fe: Pull complete
24e0251a0e2c: Pull complete
Digest: sha256:f4691c96e6bbaa99d9...e95a60369c506dd6e6f6ab
Status: Downloaded newer image for ubuntu:latest
root@3027eb644874:/#

  命令的基础格式为docker container run < options> < image>:< tag> < app>。

  使用docker container run来启动容器,这也是启动新容器的标准命令。命令中使用了-it参数使容器具备交互性并与终端进行连接。接下来,命令中指定了具体镜像ubuntu:latest。最终,在命令中指定了运行在容器中的程序Bash Shell。

  当敲击回车键之后,Docker客户端选择合适的API来调用Docker daemon。Docker daemon接收到命令并搜索Docker本地缓存,观察是否有命令所请求的镜像。在上面引用的示例中,本地缓存并未包含该镜像,所以Docker接下来查询在Docker Hub中是否存在对应镜像。找到该镜像后,Docker将镜像拉取到本地,存储在本地缓存当中。

  一旦镜像拉取到本地,daemon就创建容器并在其中运行指定的应用。在上面的示例中,Shell提示符已经变为root@3027eb644874:/#,说明目前已经位于容器内部了。@之后的一长串数字就是容器唯一ID的前12个字符。

  若尝试在容器内执行一些基础命令,可能会发现某些指令无法正常工作。这是因为大部分容器镜像都是经过高度优化的。这意味着某些命令或者包可能没有安装。下面的示例展示了两个命令——一条执行成功,一条执行失败。

1
2
root@3027eb644874:/# ls -l
root@3027eb644874:/# ping www.docker.com

1.2.5 容器进程

  启动Ubuntu容器之时,让容器运行Bash Shell(/bin/bash)。这使得Bash Shell成为容器中运行的且唯一运行的进程。可以通过ps -elf命令在容器内部查看(ps -elf进程在输出后即结束)。

  这意味着如果通过输入exit退出Bash Shell,那么容器也会退出(终止)。原因是容器如果不运行任何进程则无法存在——杀死Bash Shell即杀死了容器唯一运行的进程,导致这个容器也被杀死。

  按下Ctrl-PQ组合键则会退出容器但并不终止容器运行。这样做会切回到Docker主机的Shell,并保持容器在后台运行。可以使用docker container ls命令来观察当前系统正在运行的容器列表。

1
2
3
$ docker container ls 
CNTNR ID IMAGE COMMAND CREATED STATUS NAMES
302...74 ubuntu:latest /bin/bash 6 mins Up 6mins sick_montalcini

  当前容器仍然在运行,并且可以通过docker container exec命令将终端重新连接到Docker,理解这一点很重要。

1
2
$ docker container exec -it 3027eb644874 bash 
root@3027eb644874:/#

  Shell提示符切换到了容器,如果再次运行ps命令,会看到两个Bash或者PowerShell进程,这是因为docker container exec命令创建了新的Bash或者PowerShell进程并且连接到容器。这意味着在当前Shell输入exit并不会导致容器终止,因为原Bash或者PowerShell进程还在运行当中。

  输入exit退出容器,并通过命令docker container ps来确认容器依然在运行中。如果在自己的Docker主机上运行示例,则需要使用下面两个命令来停止并删除容器。

1
2
$ docker container stop 3027eb64487 
$ docker container rm 3027eb64487

1.2.6 容器生命周期

  通常会认为容器不擅长持久化工作或者持久化数据,很大程度上是因为容器在非持久化领域上表现得太出色。但是在一个领域做得很好并不意味着不擅长其他的领域。很多虚拟机管理员会记得微软或者Oracle告诉他们不能在虚拟机中运行他们的应用,至少他们不会支持这么做。

  容器的生命周期——从创建、运行、休眠,直至销毁的整个过程。

  新建容器,命名为“percy”,意指持久化(persistent)。

1
2
$ docker container run --name percy -it ubuntu:latest /bin/bash
root@9cb2d2fd1d65:/#

  接下来将一部分数据写入容器中。在新容器内部Shell中,执行下面的步骤来将部分数据写入到tmp目录下的某个文件中,并确认数据是否写入成功。

1
2
3
4
5
6
7
8
9
10
11
12
13
root@9cb2d2fd1d65:/# cd tmp

root@9cb2d2fd1d65:/tmp# ls -l
total 0

root@9cb2d2fd1d65:/tmp# echo "DevOps FTW" > newfile

root@9cb2d2fd1d65:/tmp# ls -l
total 4
-rw-r--r-- 1 root root 14 May 23 11:22 newfile

root@9cb2d2fd1d65:/tmp# cat newfile
DevOps FTW

  按Ctrl-PQ组合键退出当前容器。现在使用docker container stop命令来停止容器运行,切换到暂停(vacation)状态。

1
$ docker container stop percy

  现在运行docker container ls命令列出全部处于运行中状态的容器。

1
2
$ docker container ls 
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

  新建的容器没有列表中出现,原因是docker container stop命令使该容器停止运行。加上-a参数再次运行前面的命令,就会显示出全部的容器,包括处于停止状态的。

1
2
3
$ docker container ls -a 
CNTNR ID IMAGE COMMAND CREATED STATUS NAMES
9cb...65 ubuntu:latest /bin/bash 4 mins Exited (0) perc

  现在可以看到该容器显示当前状态为Exited(0)。停止容器就像停止虚拟机一样。尽管已经停止运行,容器的全部配置和内容仍然保存在Docker主机的文件系统之中,并且随时可以重新启动。

  使用docker container start命令可以将容器重新启动。

1
2
3
4
5
6
$ docker container start percy 
percy

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
9cb2d2fd1d65 ubuntu:latest "/bin/bash" 4 mins Up 3 secs percy

  现在停止的容器已经重新启动了,此时可以确认之前创建的文件是否还存在。使用docker container exec命令连接到重启后的容器。

1
2
$ docker container exec -it percy bash 
root@9cb2d2fd1d65:/#

  Shell提示符发生变化,提示正在容器内部空间进行操作。确认之前创建的文件依然存在,并且文件中仍包含之前写入的数据。

1
2
3
4
5
6
root@9cb2d2fd1d65:/# cd tmp 
root@9cb2d2fd1d65:/# ls -l
-rw-r--r-- 1 root root 14 Sep 13 04:22 newfile
root@9cb2d2fd1d65:/#
root@9cb2d2fd1d65:/# cat newfile
DevOps FTW

  之前创建的文件依然存在,数据也是当时的状态,这证明停止容器运行并不会损毁容器或者其中的数据。

  尽管上面的示例阐明了容器的持久化特性,还是需要指出(volume)才是在容器中存储持久化数据的首选方式。到目前为止,我们应该对容器和虚拟机之间的主要区别有了深刻的印象。

  现在停止该容器并从系统中删除它。通过在docker container rm命令后面添加-f参数来一次性删除运行中的容器是可行的。但是,删除容器的最佳方式还是分两步,先停止容器然后删除。这样可以给容器中运行的应用/进程一个停止运行并清理残留数据的机会。

1
2
3
4
5
6
$ docker container stop percy percy

$ docker container rm percy percy

$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAME

  总结一下容器的生命周期。可以根据需要多次停止、启动、暂停以及重启容器,并且这些操作执行得很快。但是容器及其数据是安全的。直至明确删除容器前,容器都不会丢弃其中的数据。就算容器被删除了,如果将容器数据存储在卷中,数据也会被保存下来。

1.2.7 优雅地停止容器

  Linux中的大部分容器都会运行单一进程;在Windows中可能运行若干个,但是下面的原则对于两者都适用。

  前面的示例中容器正在运行/bin/bash应用。当使用docker container rm < container> -f来销毁运行中的容器时,不会发出任何告警。这个过程相当暴力,但是,docker container stop命令就有礼貌多了。该命令给容器内进程发送将要停止的警告信息,给进程机会来有序处理停止前要做的事情。一旦docker stop命令返回后,就可以使用docker container rm命令删除容器了。

  这背后的原理可以通过Linux/POSIX信号来解释。stop命令向容器内的PID 1进程发送了SIGTERM这样的信号。就像前文提到的一样,会为进程预留一个清理并优雅停止的机会。如果10s内进程没有终止,那么就会收到SIGKILL信号。这是致命一击。但是,进程起码有10s的时间来“解决”自己。而rm命令会直接发出SIGKILL。

1.2.8 利用重启策略进行容器的自我修复

  通常建议在运行容器时配置好重启策略。这是容器的一种自我修复能力,可以在指定事件或者错误后重启来完成自我修复。

  重启策略应用于每个容器,可以作为参数被强制传入docker container run命令中,或者在Compose文件中声明(在使用Docker Compose以及Docker Stacks的情况下)。容器支持的重启策略包括always、unless stopped和on-failed。

  always策略是一种简单的方式。除非容器被明确停止,比如通过docker container stop命令,否则该策略会一直尝试重启处于停止状态的容器。

  一种简单的证明方式是启动一个新的交互式容器,并在命令后面指定–restart always策略,同时在命令中指定运行Shell进程。当容器启动的时候,会登录到该Shell。退出Shell时会杀死容器中PID为1的进程,并且杀死这个容器。但是因为指定了–restart always策略,所以容器会自动重启。如果运行docker container ls命令,就会看到容器的启动时间小于创建时间。下面请看示例。

1
2
3
4
5
6
7
8
9
$ docker container run --name neversaydie -it --restart always alpine sh

//等待几秒后输入exit

/# exit

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS
0901afb84439 alpine "sh" 35 seconds ago Up 1 second

  注意,容器于35s前被创建,但却在1s前才启动。这是因为在容器中输入退出命令的时候,容器被杀死,然后Docker又重新启动了该容器。

  –restart always策略有一个很有意思的特性,当daemon重启的时候,停止的容器也会被重启。例如,新创建一个容器并指定-restart always策略,然后通过docker container stop命令停止该容器。现在容器处于Stopped (Exited)状态。但是,如果重启Docker daemon,当daemon启动完成时,该容器也会重新启动。

  always和unless-stopped的最大区别,就是那些指定了-restart unless-stopped并处于Stopped (Exited)状态的容器,不会在Docker daemon重启的时候被重启。

  下面创建两个新容器,其中“always”容器指定–restart always策略,另一个“unless- stopped”容器指定了–restart unlessstopped策略。两个容器均通过docker container stop命令停止,接着重启Docker。结果“always”容器会重启,但是“unless-stopped”容器不会。

  (1)创建两个新容器。

1
2
3
4
5
6
7
8
9
10
11
12
$ docker container run -d --name always \  
--restart always \
alpine sleep 1d

$ docker container run -d --name unless-stopped \
--restart unless-stopped \
alpine sleep 1d

$ docker container ls
CONTAINER ID IMAGE COMMAND STATUS NAMES
3142bd91ecc4 alpine "sleep 1d" Up 2 secs unless-stopped
4f1b431ac729 alpine "sleep 1d" Up 17 secs always

  现在有两个运行的容器了。一个叫作“always”,另一个叫作“unlessstopped”。

  (2)停止两个容器。

1
2
3
4
5
6
$ docker container stop always unless-stopped

$ docker container ls -a
CONTAINER ID IMAGE STATUS NAMES
3142bd91ecc4 alpine Exited (137) 3 seconds ago unless-stopped
4f1b431ac729 alpine Exited (137) 3 seconds ago always

  (3)重启Docker。重启Docker的过程在不同的操作系统上可能不同。

1
$ systemlctl restart docker

  (4)一旦Docker重启成功,检查两个容器的状态。

1
2
3
4
$ docker container ls -a 
CONTAINER CREATED STATUS NAMES
314..cc4 2 minutes ago Exited (137) 2 minutes ago unless-stoppe d
4f1..729 2 minutes ago Up 9 seconds always

  注意到“always”容器已经重启了,但是“unless-stopped”容器并没有重启。on-failure策略会在退出容器并且返回值不是0的时候,重启容器。就算容器处于stopped状态,在Docker daemon重启的时候,容器也会被重启。

  如果使用Docker Compose或者Docker Stack,可以在service对象中配置重启策略,示例如下。

1
2
3
4
5
6
version: "3.5" 
services:
myservice:
<Snip>
restart_policy:
condition: always | unless-stopped | on-failure

1.2.9 Web服务器示例

  在该示例中,会使用到作者用于Pluralsight视频教程网站中的一个镜像。这个镜像会在8080端口启动一个相当简单的Web服务。

  使用docker container stop以及docker container rm命令清理当前系统中的全部容器,然后运行下面的docker container run命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker container run -d --name webserver -p 80:8080 \  
nigelpoulton/pluralsight-docker-ci

Unable to find image 'nigelpoulton/pluralsight-docker-ci:latest' locally
latest: Pulling from nigelpoulton/pluralsight-docker-ci
a3ed95caeb02: Pull complete
3b231ed5aa2f: Pull complete
7e4f9cd54d46: Pull complete
929432235e51: Pull complete
6899ef41c594: Pull complete
0b38fccd0dab: Pull complete
Digest: sha256:7a6b0125fe7893e70dc63b2...9b12a28e2c38bd8d3d
Status: Downloaded newer image for nigelpoulton/plur...docker-ci:latest 6efa1838cd51b92a4817e0e7483d103bf72a7ba7ffb5855080128d85043fef21

  注意,当前Shell提示符并未发生变化。这是因为使用了-d参数启动容器,并在后台运行。这种后台启动的方式不会将当前终端连接到容器当中。

  该示例在docker container run命令中抛出了一些额外的参数,已知docker container run会启动一个新容器,但是这次使 用-d参数替换了-it。-d表示后台模式,告知容器在后台运行。然后为容器命名,并且指定了-p 80:8080。-p参数将Docker主机的端口映射到容器内。本例中,将Docker主机的80端口映射到了容器内的8080端口。这意味着当有流量访问主机的80端口的时候,流量会直接映射到容器内的8080端口。之所以如此是因为当前使用的镜像,其Web服务监听了8080端口。这意味着容器启动时会运行一个Web服务,监听8080端口。

  最终,命令中还指定Docker所使用的镜像:nigelpoulton/pluralsight-docker-ci。这个镜像不一定保持更新,并且可能存在缺陷。使用docker container ls命令可以查看当前运行的容器以及端口的映射情况。端口信息按照host-port:container-port的格式显 示,明确这一点很重要。

1
2
3
4
$ docker container ls 
CONTAINER ID COMMAND STATUS PORTS NAMES
6efa1838cd51 /bin/sh -c... Up 2 mins 0.0.0.0:80->8080/tcp webserver
......

  现在容器已经运行,端口也映射成功,可以通过浏览器来访问该容器,需要在浏览器中指定Docker主机的IP地址或DNS名称,端口号是80。

1.2.10 查看容器详情

  在前面的示例当中,我们可能发现当运行docker container run命令的时候,并没有指定容器中的具体应用。但是容器却启动了一个简单的Web服务,这是如何发生的?

  当构建Docker镜像的时候,可以通过嵌入指令来列出希望容器运行时启动的默认应用。如果运行docker image inspect命令来查看运行容器时使用的镜像,就能看到容器启动时将要运行的应用列表了。

1
2
$ docker image inspect nigelpoulton/pluralsight-docker-ci
...

  Cmd一项中展示了容器将会执行的命令或应用,除非在启动的时候指定另外的应用。如果去掉示例脚本中的转义字符,可以得到这样的命令:/bin/sh -c “cd /src && node ./app.js。这是基于该镜像的容器会默认运行的应用。在构建镜像时指定默认命令是一种很普遍的做法,因为这样可以简化容器的启动。这也为镜像指定了默认的行为,并且从侧面阐述了镜像的用途——可以通过Inspect镜像的方式来了解所要运行的应用。

1.2.11 快速清理

  接下来了解一种简单且快速的清理Docker主机上全部运行容器的方法。这种处理方式会强制删除所有的容器,并且不会给容器 完成清理的机会。这种操作一定不能在生产环境系统或者运行着重要容器的系统上执行

  在Docker主机的Shell中运行下面的命令,可以删除全部容器。

1
2
$ docker container rm $(docker container ls -aq) -f 
6efa1838cd51

  在本例中,因为只有一个运行中的容器,所以只有一个容器被删除(6efa1838cd51)。如果将$(docker container ls -aq)作为参数传递给docker container rm命令,等价于将系统中每个容器的ID传给该命令。-f标识表示强制执行,所以即使是处于运行状态的容器也会被删除。


1.3 命令

  容器中常用命令。

  • docker container run是启动新容器的命令。该命令的最简形式接收镜像和命令作为参数。镜像用于创建容器,而命令则是希望容器运行的应用。docker container run -it ubuntu /bin/bash命令会在前台启动一个Ubuntu容器,并运行Bash Shell。
  • Ctrl-PQ会断开Shell和容器终端之间的链接,并在退出后保持容器在后台处于运行(UP)状态。
  • docker container ls用于列出所有在运行(UP)状态的容器。如果使用-a标记,还可以看到处于停止(Exited)状态的容器。
  • docker container exec允许用户在运行状态的容器中,启动一个新进程。该命令在将Docker主机Shell连接到一个运行中容器终端时非常有用。docker container exec -it < container-name or container-id> bash命令会在容器内部启动一个Bash Shell进程,并连接到该Shell。为了使该命令生效,用于创建容器的镜像必须包含Bash Shell。
  • docker container stop命令会停止运行中的容器,并将状态置为Exited(0)。该命令通过发送SIGTERM信号给容器内PID为1的进程达到目的。如果进程没有在10s之内得到清理并停止运行,那么会接着发送SIGKILL信号来强制停止该容器。docker container stop可以接收容器ID以及容器名称作为参数。
  • docker container start会重启处于停止(Exited)状态的容器。可以在docker container start命令中指定容器的名称或者ID。
  • docker container rm会删除停止运行的容器。可以通过容器名
    称或者ID来指定要删除的容器。推荐首先使用docker container stop命令停止容器,然后使用docker container rm来完成删除。
  • docker container inspect命令会显示容器的配置细节和运行时信息。该命令接收容器名称和容器ID作为主要参数。

参考博客和文章书籍等:

《深入浅出Docker》

因博客主等未标明不可引用,若部分内容涉及侵权请及时告知,我会尽快修改和删除相关内容