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

时间:2019-12-10 11:56:21

标签: azure-devops docker-layer

我正在运行以下yaml脚本来构建docker映像并将其推入kubernetes集群,但与此同时我想在构建yaml脚本时在azure DevOps中启用docker层缓存。请解释如何启用或如何将任务添加到Azure开发人员中以执行此操作。

Yaml:

# 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'

4 个答案:

答案 0 :(得分:5)

编辑:如注释中所述,此功能实际上是没有BuildKit 可用的。 here有一个示例,说明如何在构建过程中使用Docker映像作为缓存源。

通过将变量DOCKER_BUILDKIT: 1(请参阅this link)添加到管道作业并安装buildx,我设法通过将缓存存储为单独的映像来实现层缓存。参见this link for some basics

这是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

这当然需要每次运行都下载映像缓存,但是对于在Docker生成过程中具有较长安装步骤的映像,这无疑是更快的(在我们的情况下,大约是8分钟到2分钟)。

答案 1 :(得分:3)

这是我解决此问题的方法。我只是将映像的最新版本从注册表(在我的情况下为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

答案 2 :(得分:1)

看起来微软不久前为 Azure Devops 引入了管道缓存,并且可以缓存 docker 层。 See this link.

答案 3 :(得分:0)

azure devops当前不支持Docker层缓存。 reason如下所示:

  

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

1,但是,使用自托管代理可以进行Docker层缓存。您可以尝试creating your on-premise agents运行构建管道。

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

2,您还可以使用Cache taskdocker save/load公域将已保存的docker层上传到azure devops服务器,并在以后运行时将其还原。选中此thread以获得更多信息。

3,此blog中所述的另一种解决方法是在dockerfile中使用--cache-from and --target

如果上述解决方法不令人满意。您可以向Microsoft开发团队提交feature request。点击建议功能,然后选择 Azure Devops enter image description here