如何在 Azure DevOps 中启用 Docker 层缓存

PRA*_*EEN 7 azure-devops docker-layer

我正在运行以下 yaml 脚本来构建 docker 镜像并推送到 kubernetes 集群,但同时我想在构建 yaml 脚本时在 azure DevOps 中启用 docker 层缓存。请解释一下如何启用或如何添加azure devops 中的任务来做到这一点。

亚姆:

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

variables:
  tag: 'web'
  DockerImageName: 'boiyaa/google-cloud-sdk-nodejs'


steps:
- task: Docker@2
  inputs:
    command: 'build'
    Dockerfile: '**/Dockerfile'
    tags: 'web'
  
- script: |
    echo ${GCLOUD_SERVICE_KEY_STAGING} > ${HOME}/gcp-key.json
               gcloud auth activate-service-account --key-file ${HOME}/gcp-key.json --project ${GCLOUD_PROJECT_ID_STAGING}
               gcloud container clusters get-credentials ${GCLOUD_PROJECT_CLUSTER_ID_STAGING} \
        --zone ${GCLOUD_PROJECT_CLUSTER_ZONE_STAGING} \
        --project ${GCLOUD_PROJECT_ID_STAGING}
  displayName: 'Setup-staging_credentials'


- bash: bash ./deploy/deploy-all.sh staging
  displayName: 'Deploy_script_staging'
Run Code Online (Sandbox Code Playgroud)

小智 22

这是我解决这个问题的方法。我只是将最新版本的映像从我的注册表(在我的例子中是 Azure 容器注册表)拉到 Azure DevOps 托管代理。然后我添加--cache-from到指向这个最新标签的 Docker 构建参数,它刚刚下载到本地机器/缓存。

- task: Docker@2
  inputs:
    containerRegistry: '$(ContainerRegistryName)'
    command: 'login'

- script: "docker pull $(ACR_ADDRESS)/$(REPOSITORY):latest"
  displayName: Pull latest for layer caching
  continueOnError: true # for first build, no cache

- task: Docker@2
  displayName: build
  inputs:
    containerRegistry: '$(ContainerRegistryName)'
    repository: '$(REPOSITORY)'
    command: 'build'
    Dockerfile: './dockerfile '
    buildContext: '$(BUILDCONTEXT)'
    arguments: '--cache-from=$(ACR_ADDRESS)/$(REPOSITORY):latest' 
    tags: |
      $(Build.BuildNumber)
      latest

- task: Docker@2
  displayName: "push"
  inputs:
    command: push
    containerRegistry: "$(ContainerRegistryName)"
    repository: $(REPOSITORY) 
    tags: |
      $(Build.BuildNumber)
      latest
Run Code Online (Sandbox Code Playgroud)


Lev*_*SFT 8

目前 azure devops 不支持 Docker 层缓存。该理由陈述如下:

在 Microsoft 托管代理的当前设计中,每个作业都被分派到新配置的虚拟机。这些虚拟机在作业完成后会被清除,不会被持久化,因此不可重用于后续作业。虚拟机的短暂特性阻止了缓存的 Docker 层的重用。

1,但是,使用自托管代理可以实现 Docker 层缓存。您可以尝试创建您的本地代理来运行您的构建管道。

您可能需要禁用作业的选项“允许脚本访问 OAuth 令牌”。对于 $(System.AccessToken) 使用 --build-arg ACCESS_TOKEN=$(System.AccessToken) 传递给 docker build,其值因每次运行而异,这将使缓存无效。

2,您也可以使用Cache taskdocker save/loadcommonds将保存的docker层上传到azure devops服务器并在以后运行时恢复它。检查此线程以获取更多信息。

3,本博客中描述的另一种解决方法是--cache-from and --target在您的 dockerfile 中使用。

如果上述解决方法不令人满意。您可以向Microsoft 开发团队提交功能请求。单击“建议功能”并选择“ Azure Devops”在此处输入图片说明


Seb*_*n N 6

编辑:正如评论中所指出的,此功能实际上在没有 BuildKit 的情况下可用。这里有一个例子在这里就如何在构建过程中使用泊坞窗图像作为高速缓存源。

通过将变量DOCKER_BUILDKIT: 1(请参阅此链接)添加到管道作业并安装buildx,我设法通过将缓存存储为单独的图像来实现层缓存。有关一些基础知识,请参阅此链接

这是 Azure DevOps 中的示例步骤

- script: |
    image="myreg.azurecr.io/myimage"
    tag=$(Build.SourceBranchName)-$(Build.SourceVersion)
    cache_tag=cache-$(Build.SourceBranchName)

    docker buildx create --use
    docker buildx build \
      -t "${image}:${tag}"
      --cache-from=type=registry,ref=${image}:${cache_tag}\
      --cache-to=type=registry,ref=${image}:${cache_tag},mode=max \
      --push \
      --progress=plain \
      .
  displayName: Build & push image using remote BuildKit layer cache
Run Code Online (Sandbox Code Playgroud)

这当然需要每次运行都下载图像缓存,但对于在 Docker 构建过程中具有长时间运行安装步骤的图像,这绝对更快(在我们的例子中从大约 8 分钟到 2 分钟)。

  • 不知道为什么 a) buildkit 和 buildx 都是必需的。您可以简单地从 reg 中提取目标图像。在构建和使用cache-from 之前。因此,如果我们构建“fooimg:tag”,我们会在构建之前执行“docker pull fooimg:tag”,然后执行“docker build --cache-from fooimg:tag”。-t fooimg:标签` (2认同)
  • 请务必注意,使用 BUILDKIT:1 将要求您将 `--build-arg BUILDKIT_INLINE_CACHE=1` 添加到您的构建参数中,以支持将缓存层缓存到远程注册表。 (2认同)
  • 仅“--cache-from”本身无法在多阶段构建中工作。事实上,您需要在最终映像中内联缓存以进行多阶段构建,以便从 MS 托管代理上的缓存中受益。 (2认同)