Docker 开发的最佳实践

2,006 阅读4分钟

以下开发模式已经被证实是有用的,对于使用Docker进行应用开发的人

如何保持镜像的大小最小

小镜像在启动容器或服务时更快地通过网络传输,更快地加载到内存中。 有一些经验法则可以使镜像尺寸较小:

  • 从适当的基础映像开始。例如,如果您需要JDK,请考虑将映像基于正式的openjdk映像,而不是从通用的ubuntu映像开始并将openjdk作为Dockerfile的一部分进行安装

  • 使用多级构建。例如,您可以使用Maven映像来构建Java应用程序,然后重置为tomcat映像并将Java构件复制到正确的位置以部署您的应用程序,所有这些操作都在同一Dockerfile中。 这意味着您的最终映像不包括构建所引入的所有库和依赖项,而仅包括运行它们所需的工件和环境。

    • 如果您需要使用一个不包含多级构建的Docker版本,那么尝试通过最小化Dockerfile中独立运行命令的数量来减少映像中的层数。可以将多个命令合并到一个运行行中,并使用Shell的机制将它们组合在一起。 考虑以下两个片段。 第一层在图像中创建两层,而第二层仅创建一层。
    RUN apt-get -y update
    RUN apt-get install -y python
    
    RUN apt-get -y update && apt-get install -y python
    
  • 如果您有多个具有很多共同点的镜像,请考虑使用共享的组件创建自己的基本镜像,并在此基础上创建唯一的镜像。 Docker只需要加载一次公共层,然后将它们缓存。 这意味着您的派生镜像将更有效地使用Docker主机上的内存,并更快地加载。

  • 为了使生产镜像保持精简但允许进行调试,请考虑将生产镜像用作调试镜像的基础镜像。 可以在生产镜像的顶部添加其他测试或调试工具。

  • 在构建映像时,请始终使用有用的标签对其进行标记,这些标签可将版本信息,预期目标(例如,产品或测试),稳定性或其他在不同环境中部署应用程序时有用的信息进行整理。 不要依赖自动创建的最新标签。

在何处以及如何持久化应用程序数据

  • 避免使用存储驱动程序将应用程序数据存储在容器的可写层中。这增加了容器的大小,并且从I/O的角度来看,效率不如使用卷或绑定装载。
  • 相反,使用卷存储数据。
  • 在开发期间使用绑定挂载是合适的一种情况,此时您可能希望挂载源目录或刚构建到容器中的二进制文件。对于生产环境,应该使用卷,将其安装到与开发期间安装绑定安装相同的位置。
  • 对于生产,使用Docker secrets来存储服务使用的应用程序的私密数据,使用configs存储非私密性数据,例如配置文件。如果你目前使用的是独立的容器,请考虑迁移以使用单一副本服务,以便可以利用这些单服务功能。

使用CI / CD进行测试和部署

  • 当您检查对源代码控制的更改或创建拉取请求时,请使用Docker Hub或其他CI / CD管道自动构建并标记Docker映像并对其进行测试。
  • 通过要求您的开发,测试和安全团队在可部署到生产中的映像之前对Docker Engine-Enterprise进行进一步的处理。 这样,您可以确定在将映像部署到生产中之前,它已经由开发,质量和安全团队进行了测试和签名。

开发和生产环境的差异

开发环境 测试环境
使用绑定挂载使您的容器可以访问源代码。 使用卷来存储容器数据。
使用适用于Mac的Docker Desktop或适用于Windows的Docker Desktop。 如果可能,请使用Docker Engine-Enterprise,并通过用户映射来更好地将Docker进程与主机进程隔离。
不用担心时间差异。 始终在Docker主机和每个容器进程中运行NTP客户端,并将它们全部同步到同一NTP服务器。 如果使用群集服务,还请确保每个Docker节点将其时钟同步到与容器相同的时间源。