返回介绍

六、使用容器:运行和管理容器

发布于 2024-08-17 19:02:34 字数 6260 浏览 0 评论 0 收藏 0

6.1 容器的创建和启动

在了解容器的各项操作之前,我们再来回顾一下之前我们所提及的容器状态流转。

在这幅图中,我们可以看到,Docker 容器的生命周期里分为五种状态,其分别代表着:

  • Created :容器已经被创建,容器所需的相关资源已经准备就绪,但容器中的程序还未处于运行状态。
  • Running :容器正在运行,也就是容器中的应用正在运行。
  • Paused :容器已暂停,表示容器中的所有程序都处于暂停 ( 不是停止 ) 状态。
  • Stopped :容器处于停止状态,占用的资源和沙盒环境都依然存在,只是容器中的应用程序均已停止。
  • Deleted :容器已删除,相关占用的资源及存储在 Docker 中的管理信息也都已释放和移除…

6.2 创建容器

当我们选择好镜像以后,就可以通过 docker create 这个命令来创建容器了

$ sudo docker create nginx:1.12
34f277e22be252b51d204acbb32ce21181df86520de0c337a835de6932ca06c3

执行 docker create 后, Docker 会根据我们所给出的镜像创建容器,在控制台中会打印出 Docker 为容器所分配的容器 ID ,此时容器是处于 Created 状态的

  • 之后我们对容器的操作可以通过这个容器 ID 或者它的缩略形式进行,但用容器 ID 操作容器就和用镜像 ID 操作镜像一样烦闷,所以我们更习惯于使用容器名来操作容器。
  • 要使用容器名操作容器,就先得给容器命名,在创建容器时,我们可以通过 --name 这个选项来配置容器名…
$ sudo docker create --name nginx nginx:1.12

6.3 启动容器

通过 docker create 创建的容器,是处于 Created 状态的,其内部的应用程序还没有启动,所以我们需要通过 docker start 命令来启动它。

$ sudo docker start nginx
  1. 由于我们为容器指定了名称,这样的操作会更加自然,所以我们非常推荐为每个被创建的容器都进行命名
  2. 当容器启动后,其中的应用就会运行起来,容器的几个生命周期也会绑定到了这个应用上,这个之前我们已经提及,这里就不在赘述。只要应用程序还在运行,那么容器的状态就会是 Running ,除非进行一些修改容器的操作。
  3. Docker 里,还允许我们通过 docker run 这个命令将 docker createdocker start 这两步操作合成为一步,进一步提高工作效率…
$ sudo docker run --name nginx -d nginx:1.12
89f2b769498a50f5c35a314ab82300ce9945cbb69da9cda4b022646125db8ca7
  • 通过 docker run 创建的容器,在创建完成之后会直接启动起来,不需要我们再使用 docker start 去启动了。
  • 这里需要注意的一点是,通常来说我们启动容器会期望它运行在“后台”,而 docker run 在启动容器时,会采用“前台”运行这种方式,这时候我们的控制台就会衔接到容器上,不能再进行其他操作了。我们可以通过 -d--detach 这个选项告诉 Docker 在启动后将程序与控制台分离,使其进入“后台”运行…

6.4 管理容器

  • 容器创建和启动后,除了关注应用程序是否功能正常外,我们也会关注容器的状态等内容。
  • 通过 docker ps 这个命令,我们可以罗列出 Docker 中的容器
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89f2b769498a nginx:1.12 "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp nginx...

默认情况下, docker ps 列出的容器是处于运行中的容器,如果要列出所有状态的容器,需要增加 -a--all 选项

$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
425a0d3cd18b redis:3.2 "docker-entrypoint.s…" 2 minutes ago Created redis
89f2b769498a nginx:1.12 "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp nginx...
  1. docker ps 的结果中,我们可以看到几项关于容器的信息。其中 CONTAINER IDIMAGECREATEDNAMES 大家都比较容易理解,分别表示容器 ID ,容器所基于的镜像,容器的创建时间和容器的名称。
  2. 结果中的 COMMAND 表示的是容器中主程序 ( 也就是与容器生命周期所绑定进程所关联的程序 ) 的启动命令,这条命令是在镜像内定义的,而容器的启动其实质就是启动这条命令
  3. 结果中的 STATUS 表示容器所处的状态,其值和我们之前所谈到的状态有所区别,主要是因为这里还记录了其他的一些信息。在这里,常见的状态表示有三种:
  • Created 此时容器已创建,但还没有被启动过。
  • Up [ Time ] 这时候容器处于正在运行状态,而这里的 Time 表示容器从开始运行到查看时的时间。
  • Exited ([ Code ]) [ Time ] 容器已经结束运行,这里的 Code 表示容器结束运行时,主程序返回的程序退出码,而 Time 则表示容器结束到查看时的时间…

当然,在 Docker 逐渐成熟后,命令的命名也没有原来那么随意了,已经逐渐转换为使用大家广泛认可的形式。只是 docker ps 这条命令,还保留着复古的风格。

6.5 停止和删除容器

要将正在运行的容器停止,我们可以使用 docker stop 命令

$ sudo docker stop nginx

正在运行中的容器默认情况下是不能被删除的,我们可以通过增加 -f--force 选项来让 docker rm 强制停止并删除容器,不过这种做法并不妥当

6.6 随手删除容器

与其他虚拟机不同, Docker 的轻量级容器设计,讲究随用随开,随关随删。也就是说,当我们短时间内不需要使用容器时,最佳的做法是删除它而不是仅仅停止它

6.7 进入容器

  • 很多时间,我们需要的操作并不仅仅是按镜像所给出的命令启动容器而已,我们还会希望进一步了解容器或操作容器,这时候最佳的方式就是让我们进入到容器了。
  • 我们知道,容器是一个隔离运行环境的东西,它里面除了镜像所规定的主进程外,其他的进程也是能够运行的, Docker 为我们提供了一个命令 docker exec 来让容器运行我们所给出的命令…

这里我们试试用容器中的 more 命令查看容器的主机名定义。

$ sudo docker exec nginx more /etc/hostname
::::::::::::::
/etc/hostname
::::::::::::::
83821ea220ed...
  • docker exec 命令能帮助我们在正在运行的容器中运行指定命令,这对于服务控制,运维监控等有着不错的应用场景。但是在开发过程中,我们更常使用它来作为我们进入容器的桥梁
  • 熟悉 Linux 的朋友们知道,我们操作 Linux 这个过程,并不是 Linux 内部的某些机能,而是通过控制台软件来完成的。控制台软件分析我们的命令,将其转化为对 Linux 的系统调用,实现了我们对 Linux 的操作。若不是这样,生涩的系统调用方法对普通开发者来说简直就是黑洞一般的存在,更别提用它们控制系统了…
  • Linux 中,大家熟悉的控制台软件应该是 ShellBash 了,它们分别由 shbash 这两个程序启动
  • 由于 bash 的功能要比 sh 丰富,所以在能够使用 bash 的容器里,我们优先选择它作为控制台程序。
$ sudo docker exec -it nginx bash
root@83821ea220ed:/#

在借助 docker exec 进入容器的时候,我们需要特别注意命令中的两个选项不可或缺,即 -i-t ( 它们俩可以利用简写机制合并成 -it )。

其中 -i ( --interactive ) 表示保持我们的输入流,只有使用它才能保证控制台程序能够正确识别我们的命令。而 -t ( --tty ) 表示启用一个伪终端,形成我们与 bash 的交互,如果没有它,我们无法看到 bash 内部的执行结果…

6.8 衔接到容器

Docker 为我们提供了一个 docker attach 命令,用于将当前的输入输出流连接到指定的容器上。

$ sudo docker attach nginx
  • 这个命令最直观的效果可以理解为我们将容器中的主程序转为了“前台”运行 ( 与 docker run 中的 -d 选项有相反的意思 )。
  • 由于我们的输入输出流衔接到了容器的主程序上,我们的输入输出操作也就直接针对了这个程序,而我们发送的 Linux 信号也会转移到这个程序上。例如我们可以通过 Ctrl + C 来向程序发送停止信号,让程序停止 ( 从而容器也会随之停止 )。…

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文