容器:向死而生的一生,容器而生一生


尼奥:为什么那些程序会被删除?

先知:或许发生故障了,或许有更好的程序替代它,这种事天天发生,一旦这种事情发生了,程序就会躲在母体里或是选择回到万物之源。

“重启”是一个具有哲学意义的话题,比如《黑客帝国》中特工史密斯可以随时在一个身体上重启自己;《明日边缘》中阿汤哥饰演的男主角在一次次的重启中不断进步,最终战胜了大 Boss;程序员的段子中,“你重启下试试”非常经典。虽然重启不能解决所有的问题,但还是能解决大部分问题的,因为重启能清除应用的当前状态,包括任何不在正常状态的代码。对于 Docker,我们可以将 restart 作为一种自我修复的机制。

如果把 Docker 容器看做生命,那必然是“向死而生”的一生:它们可能会随时被停止或删除。默认情况下,所有运行过程中产生的数据也将被清除。但就像《黑客帝国》中的特工史密斯一样,容器也可以立马以初始的状态被重启。无疑从这个角度来讲,暂时的任务是容器最常用的场景。但实际上,容器也可以完美运行 web 服务,还可以通过 volume 实现数据库和持久化数据存储。MongoDB,MySQL 和 Postgres 都是 Docker Hub 上最流行的 Docker 镜像。

一个容器的“传记”Containers Life Story

都有哪些因素影响了容器的平均寿命呢?我们可以通过容器的整个存在过程进行深入研究。在 Docker Engine 记录了容器整个生命周期的事件,还有其它的重要信息,都保存在了 /var/log/docker.log 中。我们也可以通过 docker events 命令行大体看下某个容器。这个命令会向 Docker Engine 查询某个时间段内容器内发生的重要事件。比如我们先启动一个容器:

然后,运行 docker events 看看哪些事件会被记录下来:

哇!能在命令行看到容器启动过程幕后发生了什么!

  • 首先,由于在本地未能找到镜像,Docker client 通过 Remote API 从 Docker Hub pull 下镜像;

  • 接下来,创建容器,添加 stdout/stderr 到终端;

  • 然后,新容器被加入到默认的 bridge 网络,被 engine 启动;

  • 最终,容器完成自己的使命后,就会被删除。在此之前,Docker engine 会将其移出默认的 bridge 网络中。

容器已死,容器万岁!The container is dead, long live the container!

虽然这个容器已经“死了”,我们还是能用 docker ps -a 命令捕捉到它生前的“音容笑貌”。

看起来这个容器去得很平静,因为 Exit(0) 并不是每个容器都能达到的境界。

而且虽然容器停止了,我们还是能找到它的“遗产”,因为所有容器的数据存储只有在 docker rm 执行后才会被正式销毁。 docker export 命令可以将容器的文件系统存储到一个 tar 包中。然后可以用 docker import 将其导入到同主机上的另一个容器中,或一个新的容器中。

请注意 docker export 导出的数据中不包含容器的历史。实际上,当 tar 包被导入到一个镜像中,结果镜像会被压缩为一层。

如果你在运行短期的前台操作容器,这些数据堆积会额外占用很多空间。docker run -rm 可以在容器停止后自动清理容器状态数据和镜像层。


相关内容

    暂无相关文章