不可不知的七个 Docker 优秀实践
Docker 是流行的容器化软件,但不是每个人都在高效地使用它。如果您不遵循 Docker 的优秀实践,您的应用程序就很容易受到安全问题或性能问题的影响。
本文介绍了您可以用来高效地使用 Docker 功能的几个最佳实践。这些措施提高了安全性,并确保您创建易于维护的 Docker 文件。
1.使用官方 Docker 镜像
在容器化处理应用程序时,必须使用 Docker 镜像。您可以使用自定义配置构建镜像,也可以使用 Docker 的官方镜像。
构建自己的镜像需要您自行处理所有配置。比如说,若为 Node.js 应用程序构建镜像,您必须下载 Node.js 及其依赖项。这个过程很耗时,可能不会生成所有正确的配置。
Docker 建议您使用官方的 Node.js 镜像,它包含所有正确的依赖项。Docker 镜像有更好的安全措施,具有轻量级的优点,并针对各种环境进行了测试。你可以在 Docker 的官方镜像页面上找到官方镜像。
2.使用 Docker 镜像的特定版本
当您拉取官方镜像时,它通常带有最新标签,这代表该镜像的最新更新版本。每当使用该镜像构建容器,它都是上一个容器的不同版本。
使用不同的 Docker 镜像版本进行构建可能导致应用程序出现不可预测的行为。版本可能会与其他依赖项冲突,最终导致应用程序失败。
Docker 建议您使用特定版本的镜像进行拉取和构建。官方镜像也有说明文档,介绍了最常见的用例。
比如说,使用 docker pull alpine:3.18.3,而不是 docker pull alpine。Docker 将提取该特定版本。然后,您可以在后续构建中使用它,从而减少应用程序中的错误。您可以在 Docker 官方镜像页面的 Supported 标签和相应的 Dockerfile 链接下找到镜像的特定版本:
3.扫描镜像以查找安全漏洞
如何确定想要构建的镜像没有安全漏洞?扫描就行。可以使用 Docker scan 命令扫描 Docker 镜像。语法如下:
您必须先登录到 Docker 才能扫描镜像。
然后,扫描您想要检查的特定镜像:
一种名为 Synk 的工具可以扫描镜像,根据严重程度列出任何漏洞。您可以看到漏洞的类型和指向相关信息的链接(包括如何修复它)。您可以从扫描结果中判断镜像对您的应用程序而言是否足够安全。
4.使用小型 Docker 镜像
当您拉取 Docker 镜像时,它附带所有系统实用程序。这增加了不需要的工具的镜像大小。
大型 Docker 镜像占用存储空间,并且减慢容器的运行速度。它们存在安全漏洞的可能性也更大。
您可以使用 Alpine 镜像减小 Docker 镜像的大小。Alpine 镜像是轻量级的,只附带必要的工具。它们减少了存储空间,使应用程序运行起来更快速、更高效。
可以在 Docker 上找到大多数官方镜像的 Alpine 版本。下面是 PostgreSQL 的 Alpine 版本的示例:
5.优化缓存镜像层
Dockerfile 中的每个命令代表镜像上的一个层。这些层有不同的实用程序,并执行不同的功能。如果您查看 Docker Hub 上的官方镜像,将会看到用于创建它们的说明。
Dockerfile 包含创建镜像所需的全部内容。这就是为什么许多开发人员青睐 Docker 而不是虚拟机的原因之一。
下面是示例 Alpine 镜像的结构:
当您构建基于镜像的应用程序时,实际上在为镜像添加更多的层。Docker 从上到下在 Dockerfile 上运行指令,如果一个层发生了变化,Docker 必须重建后续的层。
最佳实践是将您的 Dockerfile 按照由更改最少的文件到更改最频繁的文件这个顺序排列。不会改变的指令(比如安装)可以放在文件的顶部。
当您修改一个文件时,Docker 根据修改后的文件进行构建,并在上面缓存未修改的文件。因此,流程运行速度更快。
请看上图所示的例子。如果应用程序文件发生了变化,Docker 将从那里构建,它没必要再次安装 NPM 包。
如果从镜像构建,该过程将比从头重建所有其他层运行得更快。缓存也加快了从 Docker Hub 拉取和推送镜像的速度。
6.使用.dockerignore 文件
在使用 Dockerfile 构建镜像时,您可能希望保留某些信息的私密性。一些文件和文件夹可能是项目的一部分,但您不希望将它们包含在构建过程中。
使用.dockerignore 文件可以大大减小镜像大小。这是由于构建过程只包含必要的文件。它还有助于保持文件的私密性,避免暴露密钥或密码。
.dockerignore 文件是您在与 Dockerfile 相同的文件夹中创建的一个文件。它是一个文本文件,酷似.gitignore 文件,含有您不希望在构建过程中包含的任何文件的名称。
这里有一个例子:
7.使用最小权限用户原则
默认情况下,Docker 使用 root 用户作为管理员以便获得运行命令的权限,但这种做法不好。如果其中一个容器存在漏洞,黑客就可以访问 Docker 主机。
为了避免这种情况,应创建专用的用户和用户组。您可以为用户组设置相应的权限,以保护敏感信息。如果用户受到危及,您可以在不暴露整个项目的情况下删除该用户。
下面这个例子展示了如何创建用户并设置权限:
一些基本镜像在其中创建了伪用户。您可以使用已安装的用户,而不是 root 用户权限。
最佳实践是减少漏洞和编写更简洁代码的好方法。您可以将许多最佳实践应用于使用的每项 Docker 特性。
一个组织良好的项目可以更容易与 Kubernetes 等其他编排工具进行同步。您可以从本文中概述的这些方法入手,在学习 Docker 的过程中采用更多的方法。
8.推荐一款开发工具
一款基于 jar · /Docker 部署方式的开发平台。
JNPF 快速开发平台,很多人都用过它,它是功能的集大成者,任何信息化系统都可以基于它开发出来。原理是将开发过程中某些重复出现的场景、流程,具象化成一个个组件、api、数据库接口,避免了重复造轮子。因而极大的提高了程序员的生产效率。
官网: https://www.jnpfsoft.com?infoq ,如果你有闲暇时间,可以做个知识拓展。
这是一个基于 Java Boot/.Net Core 构建的简单、跨平台快速开发框架。前后端封装了上千个常用类,方便扩展;集成了代码生成器,支持前后端业务代码生成,满足快速开发;框架集成了表单、报表、图表、大屏等各种常用的 Demo 方便直接使用;后端框架支持 Vue2、Vue3;支持本地化部署,也支持 K8S 部署。
为了支撑更高技术要求的应用开发,从数据库建模、Web API 构建到页面设计,与传统软件开发几乎没有差异,只是通过低代码可视化模式,减少了构建“增删改查”功能的重复劳动。
作为开发者,永远是动手>理解,你可以尝试基于 JNPF 自己搭建一个应用。
版权声明: 本文为 InfoQ 作者【树上有只程序猿】的原创文章。
原文链接:【http://xie.infoq.cn/article/0e1239e08b0d5245a580a3915】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论