创建最佳的CI/CD工作流程并不总是一个简单的任务。事实上,编写有效和高效的配置代码是许多开发人员在其DevOps旅程中面临的最大障碍。但你不需要成为一个专家来建立一个快速、可靠的测试和部署基础设施。通过一些简单明了的技术,你可以优化你的config.yml 文件,并释放你的CI/CD管道的全部潜力。
在这个系列中,我们将深入探讨我们的解决方案工程师在与企业级客户进行一对一的配置审查时提出的一些常见建议。今天,我们专注于Docker层缓存(DLC),这是一种强大的技术,可以在作业之间保存Docker层,并加快你的工作流程。
直到最近,DLC只适用于性能和规模计划,现在已经包括在新的CircleCI免费计划以及CircleCI服务器的安装中。在这篇文章中,我们将讨论什么是Docker层缓存,为什么它很重要,以及你如何将它添加到你的管道中。
什么是Docker层缓存?
Docker是CircleCI平台上使用的容器化技术。在Docker执行器和机器执行环境中,您可以运行Docker构建命令,将您的应用程序容器化,以便进行测试和部署。通过Docker层缓存,您可以保存您构建的Docker镜像的各个层,以便它们可以在随后的管道运行中重复使用。
Docker层缓存可以绕过部分或全部镜像构建步骤,为你的团队在构建过程中节省大量时间。Docker镜像是由Docker文件构建的,Docker文件中的每条命令都会在镜像中创建一个新的层。当你用docker build 或docker compose 构建Docker镜像时,DLC会将各个层保存到运行该作业的机器或远程Docker实例上的一个卷上。在你下次运行镜像构建作业时,CircleCI将从缓存中检索任何未改变的层。
如果您的Docker文件在管道运行之间保持不变,整个图像将从缓存中检索。如果你在两次运行之间对Dockerfile进行了改变,CircleCI将检索所有的层,直到改变,然后根据新的Dockerfile构建图像的其余部分。你的Dockerfile在两次运行之间的变化越少,你的镜像构建就越快。
什么时候应该使用Docker层缓存?
Docker容器从根本上改变了软件开发的格局,允许团队通过将二进制文件和依赖性打包成一个可移植的软件单元,消除了环境冲突的可能性或 "它在我的机器上工作 "的难题,从而协同、安全和一致地构建、测试和部署应用程序。许多团队已经采用容器化作为实施云原生开发实践的一种方式,并将他们的软件架构转向更多的分布式方法。
如果你的应用程序依赖于容器,你可能会发现自己在CI/CD管道的每次运行中都会构建相同的镜像,这可能会严重消耗你的构建时间。通过启用Docker层缓存,你可以通过重用缓存的镜像层,而不是在每次运行构建时从头开始构建,来实现构建时间的大幅减少。
请注意,DLC只会减少在远程Docker环境中用docker build,docker compose, 或类似的docker命令构建自己的Docker镜像的时间。它不会影响启动主Docker容器的时间。如果你在Docker容器中运行你的管道,但不把构建新的图像作为工作流程的一部分,那么你不会看到通过实施DLC而减少任何构建时间。
如何将Docker层缓存添加到你的管道中
你可以使用Docker层缓存来加快Docker镜像在Docker和机器执行环境中的构建速度。在Docker执行环境中,你创建的任何Docker镜像都是在一个被称为远程Docker环境的辅助容器中构建的,这为构建过程增加了额外的安全性,使你能够访问各种Docker命令,并能够通过SSH进入你的构建中进行调试。你可以用setup-remote-docker 密钥来启动远程Docker环境,然后通过将docker_layer_caching 设置为true ,将Docker层缓存添加到构建作业中。
version: 2
jobs:
build:
docker:
# DLC does nothing here, its caching depends on commonality of the image layers.
- image: cimg/node:17.3.0
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD
steps:
- checkout
- setup_remote_docker:
docker_layer_caching: true
# DLC will explicitly cache layers here and try to avoid rebuilding.
- run: docker build .
在这个例子config.yml 文件中,你将docker 作为build 作业的执行环境,并将docker_layer_caching 设置为true ,建立一个远程Docker环境。CircleCI将缓存你用docker build 命令构建的Docker镜像的层,这样在你下次运行这个作业时,你就可以避免重建任何未改变的层。
机器执行环境不需要远程Docker环境来运行docker 或docker-compose 命令,所以你可以将docker_layer_caching: true 密钥直接包含在你的机器执行器密钥下面。
version: 2
jobs:
build_elixir:
machine:
image: ubuntu-2004:202104-01
docker_layer_caching: true
steps:
- checkout
- run:
name: build Elixir image
command: docker build -t circleci/elixir:example .
在这个例子中,你将ubuntu-2004:202104-01 Linux镜像设置为你的机器执行器类型,然后设置docker_layer_caching: true ,为这个环境启用Docker层缓存。当你用docker build 命令构建Elixir镜像时,CircleCI将缓存各个层,以便在未来的运行中重复使用。
一旦你为你的项目启用了DLC,任何被保存的层将在工作运行之间的三天内可用。任何缓存的图层如果在三天后没有被重新使用,将被删除。你可以在每个项目中最多创建50个DLC卷。
总结
Docker层缓存是在CircleCI上加快Docker构建的一个重要部分,现在已经包含在CircleCI免费计划中。如果您的团队构建了容器化的应用程序,您可以通过在您的项目中重复使用未改变的Docker层来节省宝贵的开发时间。这不仅使您的团队更有效率,为您的组织节省资金,而且还可以帮助您更快地为用户提供价值,这是当今软件开发领域的一个关键区别。
DLC只是你可以对你的配置进行的许多不同的优化中的一个。其他基于缓存的优化包括在工作区持久化数据和缓存依赖关系以加快构建。