[译]Docker开发最佳实践

原文地址:Docker development best practices

下面的开发模式已经被证明有助于人们使用Docker构建应用程序。如果你发现了我们应该补充的东西,请告诉我们

How to keep your images small

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

  • 从一个合适的基础镜像开始。例如,如果您需要一个jdk,可以考虑基于官方的openjdk镜像,而不是用通用的ubuntu镜像,再安装openjdk
  • Use multistage builds。例如,您可以使用maven镜像来构建Java应用程序,然后重置为tomcat镜像,并将Java工件复制到部署应用程序的正确位置,所有这些都在同一个Dockerfile中。这意味着您的最终镜像不包括构建所拉入的所有库和依赖项,而只包括运行它们所需的工件和环境
    • 如果需要使用不包含多级构建功能(multistage build)的Docker版本,请尝试通过最小化DockerfileRUN命令的数量来减少镜像层数。您可以通过将多个命令合并到一个RUN中,并使用shell的机制将它们组合在一起来实现。考虑以下两个片段。第一个在镜像中创建两个层,而第二个只创建一个层 RUN apt-get -y update RUN apt-get install -y python

      RUN apt-get -y update && apt-get install -y python * 如果您有多个具有许多共同点的镜像,请考虑使用共享组件创建自己的基础镜像Docker只需要加载一次公共层即可(因为它们在本地缓存了)。这意味着您的后续镜像可以更高效地使用Docker主机上的内存并更快地加载 * 要使生产镜像保持精简但允许调试,请考虑使用生产镜像作为调试镜像的基础镜像。可以在生产镜像的顶部添加额外的测试或调试工具 * 在构建镜像时,请始终使用有用的标记对其进行标记,这些标记用于编码版本信息、预期目标(例如prodtest)、稳定性或在不同环境中部署应用程序时有用的其他信息。不要依赖于自动创建的latest标记

Where and how to persist application data

  • 避免使用存储驱动程序(storage drivers)将应用程序数据存储在容器的可写层中。这会增加容器的大小,从I/O的角度来看,这比使用卷(volume)或绑定装载(bind mount)效率低
  • 使用卷(volume)存储数据
  • 在开发过程中,可能需要挂载源目录或刚刚构建到容器中的二进制文件,这时使用绑定挂载(bind mounts)是合适的。对于生产环境,请改用卷(volume),将其挂载到与开发过程中进行绑定挂载相同的位置
  • 在生产环境中,使用secrets存储服务使用的敏感应用程序数据,并对非敏感数据(如配置文件)使用configs。如果您当前使用独立容器,请考虑迁移到使用单个副本服务,以便您可以利用这些仅限服务的功能

Use swarm services when possible

  • 尽可能的使用swarm服务设计应用程序
  • 即使只需要运行应用程序的单个实例,swarm服务也比独立容器提供了一些优势。服务的配置是声明性的,Docker总是保持所需的和实际的状态同步
  • 网络和卷可以与swarm服务连接和断开,docker以非干扰(non-disruptive)的方式处理单个服务容器的重新部署。而独立容器需要手动停止、删除和重新创建以适应配置更改
  • 一些特性,例如存储secretsconfigs的能力,只针对服务而不是独立容器可用。这些特性允许您尽可能地保持镜像通用性,并避免在Docker镜像或容器本身中存储敏感数据
  • 使用docker stack deploy处理任何镜像拉取,而不是使用docker pull。这样,部署就不会试图从已关闭的节点中拉取。此外,当新的节点被添加到swarm中时,镜像会被自动提取

swarm服务的节点之间共享数据有一些限制。如果你使用Docker for AWSDocker for Azure,你可以使用Cloudstor插件在swarm服务节点之间共享数据。您还可以将应用程序数据写入支持同步更新的单独数据库

Use CI/CD for testing and deployment

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

Differences in development and production environments