概述
这篇文章主要是我日常工作中的制作镜像的实践, 同时结合我学习到的关于镜像制作的相关文章总结出来的. 包括通用的容器最佳实践, java, nginx, python 容器最佳实践. 最佳实践的目的一方面保证镜像是可复用的, 提升 DevOps 效率, 另一方面是为了提高安全性. 希望对各位有所帮助.
本文分为四部分内容, 分别是:
- 通用容器镜像最佳实践
- Java 容器镜像最佳实践
- NGINX 容器镜像最佳实践
- 以及 Python 容器最佳实践
通用容器镜像最佳实践
使用 LABEL maintainer
LABEL maintainer
指令设置镜像的作者姓名和邮箱字段。示例如下:
LABEL maintainer="[email protected]"
复用镜像
建议尽量使用 FROM
语句复用合适的上游镜像。这可确保镜像在更新时可以轻松从上游镜像中获取安全补丁,而不必直接更新依赖项。
此外,在 FROM
指令中使用标签 tag(例如 alpine:3.13
),使用户能够清楚地了解镜像所基于的上游镜像版本。
❗ 禁止使用 latest
tag以确保镜像不会受到 latest
上游镜像版本的重大更改的影响。
保持标签 TAGS 的兼容性
给自己的镜像打标签时,注意保持向后兼容性。例如,如果制作了一个名为example
的镜像,并且它当前为 1.0 版,那么可以提供一个 example:1
标签。后续要更新镜像时,只要它继续与原始镜像兼容,就可以继续标记新镜像为 example:1
,并且该 tag 的下游消费者将能够在不中断的情况下获得更新。
如果后续发布了不兼容的更新,那么应该切换到一个新 tag,例如 example:2
。那么下游消费者可以按照自身实际情况升级到新版本,而不会因为新的不兼容镜像而造成事故。但是任何使用 example:latest
的下游消费者都会承担引入不兼容更改的风险, 所以这也是前面我强烈建议不要使用 latest
tag 的原因.
避免多个进程
建议不要在一个容器内启动多个服务,例如 nginx 和 后端 app。因为容器是轻量级的,可以很容易地通过 Docker Compose 或 Kubernetes 链接在一起。Kubernetes 或基于此的 TKE 容器平台通过将相关镜像调度到单个 pod 中,轻松地对它们进行集中管理。
在封装脚本中使用 EXEC
指令
许多镜像会通过在启动应用程序之前使用封装脚本进行一些设置。如果您的镜像使用这样的脚本,那么该脚本最后应该使用 exec
启动应用程序,以便用应用程序的进程替换该脚本的进程。如果不使用 exec
,那么容器运行时发送的信号(比如 TERM
或 SIGKILL
)将转到封装脚本,而不是应用程序的进程。这不是我们所期望的。
清除临时文件
应删除在生成过程中创建的所有临时文件。这还包括使用 ADD
指令添加的任何文件。例如,