Docker 是部署 web 应用程序的一个很好的工具,但前提是你得按它的设计意图来使用。否则很容易自打脚。如果你想省去调试的痛苦,尽量避免这些常见的错误。
1. 不限制资源 ❌顺便说一句:如果你想让生活更轻松,可以去看看[sliplane.io]。这是一个简单的Docker管理解决方案,可以帮助你避免一些在这里提到的坑。
这一点特别重要,如果你在一个服务器上运行多个容器。过于贪婪的服务可能会占用服务器上的所有CPU和内存,这会导致其他容器没有足够的资源运行,最糟糕的情况是,整个服务器可能会冻结,甚至让整个服务器瘫痪。
您可以使用 --cpu-quota
和 --memory
参数来限制容器运行时间的资源使用。
docker运行一个容器,限制内存为512兆,并限制CPU配额为50000,使用的镜像是your-image-name。
全屏 退出全屏
您可以在该官方文档中的资源限制文档中找到更多关于这些标志的信息。默认情况下,容器没有这些限制,您可以在docker run
命令中设置这些资源限制。
如果你可以,尽量不要在同一个服务器上构建镜像和运行容器。这样可以避免构建过程占用大量CPU和内存,导致服务器比你更快地说出“别挂了!😱”还要快地崩溃。
第二点. 不打扫 ❌没有人喜欢打扫卫生,但别让你自己被 💩 堆积如山。如果你想避免被自己的 💩 埋没,这是一项必要的任务。Docker 镜像可能非常大,有时达到几 GB 之巨。如果你部署了新版本的镜像并且不再需要的老版本,你应该删除它们。同样适用的是不再使用的容器和卷。这些东西很快就会累积起来,很快你的部署很快就会失败,你可能又要花上 45 分钟才发现磁盘已满……
要移除未打标签的 Docker 对象,可以使用以下命令来移除:
docker container prune
docker image prune
docker volume prune
docker system prune # (这会移除所有悬挂的镜像、卷和容器,包括之前的容器、卷和未标记的镜像)
切换到全屏 退出全屏
清理所有未使用的 Docker 对象,并通过添加 -a
参数实现(这也包括带有标签的镜像),
docker container prune -a
docker image prune -a
docker volume prune -a
docker system prune -a # 这会清理所有废弃的镜像、卷以及容器
全屏,退出全屏
3. 在图片中泄露秘密 ❌在构建过程中,应用程序需要访问密钥的情况并不罕见。人们没有意识到的是,构建时嵌入了密钥的镜像,应该被视为密钥!Docker 镜像不是一个保险库。镜像中的所有内容都可以被拥有访问权限的人读取。(除非你把其中的内容加密,不然任何人都可以读取)。因此,如果在构建时嵌入了密钥,千万不要将这样的镜像发布到 Docker Hub 上!
如果可能,避免在构建时传递机密信息,而是依赖环境变量或使用秘密管理器。如果绝对不可能,确保只在一个受信任的环境中构建镜像,存放在私有仓库中,只通过加密线路传输,并在不再需要时立即删除。
也可以看看这篇关于如何在Docker构建中处理机密信息的博客文章。
4. 当前没有监控措施 ❌这对安全和便携性来说非常好,但不利于监控和追踪,因为容器是隔离的且生命周期短暂。
每次要看日志文件都得用 docker exec
进入容器,真的很烦人,所以请提前做好准备,免得每次都要这么麻烦。
最简单的方法是挂载一个卷来保存日志文件,这样日志文件至少可以持久保存。但是如果没有日志轮转(log rotation),最好是有一些方法可以直接在日志中进行搜索,那么这种设置很快就会遇到瓶颈。
为了提高可见性,你可以通过将数据流传输到外部系统来实施日志监控,同时还可以配置资源监控工具来跟踪容器的CPU和内存使用情况。
在专业环境中,监控通常使用[ELK Stack]工具来完成。
5. 别忽视了 Docker 镜像的优化 ❌如前所述,Docker 镜像可能会很大(大小可达几个吉字节!)。在这里我想提到的一个最后错误是,没有优化你的 Docker 镜像。不仅节省了大量的存储空间,还缩小了攻击面,并让你的部署速度变得更快。
看看这个关于减小 Nuxt 3 Docker 镜像大小的例子。作者 Jonas Scholz 成功将镜像大小从 1.4GB 减至仅 160MB!这几乎达到了 10 倍的改进,仅通过几个简单的步骤就能实现:
- 使用尽可能小的基础图像
- 在你的
.dockerignore
文件中排除不必要的文件,以减少构建时的冗余文件 - 从 CDN 服务器提供静态资源
- 使用多阶段构建方法
常见的 Docker 部署错误有:
- 忽略资源限制,
- 未能清理资源,
- 将敏感数据嵌入镜像中,
- 忽视日志记录和监控,还有
- 错过了优化镜像的机会。
如果你想让生活更轻松点,可以试试sliplane.io。它是一个简单的Docker托管解决方案,可以帮助你避免这里提到的一些问题。
声明:我共同创立了Sliplane :-)