【问题标题】:Deploy ARM Template and Docker image部署 ARM 模板和 Docker 映像
【发布时间】:2020-07-17 19:49:06
【问题描述】:

好吧,每个人都在说要在这次大流行期间尝试学习新东西,所以这就是我正在尝试做的事情。我对 YAML 和 Docker 很陌生,对 ARM 模板也很陌生。

我已经能够使用 YAML 通过 dotnet YAML 命令构建和发布 .NET Core 应用程序。我已经能够使用 YAML 构建 .NET Core 3.1 Web API 应用程序的 Docker 映像。

我正在将 docker 映像发布到 Azure 资源容器。

我被困在哪里:

理想情况下,我想在 .NET Core 项目中使用 ARM 模板,以便能够通过代码部署我的 Azure 门户资源,而不是在门户中手动创建。这应该包括 Azure 资源容器。

看来我需要做的是在构建阶段构建 docker 映像,然后将其发布到 $(System.ArtifactsDirectory) 以便我可以将它保存在那里,直到通过部署 Azure 资源ARM 模板。

不过,我找不到任何关于将 docker 映像发布为管道工件的信息。只有关于推送到 DockerHub、GitHub 和 Azure 资源容器的事情,这不是我现在想做的事情。

有人知道我该如何解决这个问题吗?

【问题讨论】:

  • 您将容器发布到 Azure 容器注册表。容器不是传统意义上的构建工件。

标签: azure docker azure-devops devops azure-pipelines-yaml


【解决方案1】:

我实际上找到了解决这个问题的方法。我在dev.to读到的关于这个的文章已经结束了

我需要做一些事情来完成这项工作。

首先,不要在构建时设置 containerRegistry。

- task: Docker@2
  displayName: Build Docker Image
  inputs:            
    repository: $(imageName)
    command: build
    dockerfile: '**/Dockerfile'
    buildContext: 'HopefulMommaDesignsAPI'
    tags: $(Build.BuildId)

这样做的原因是,如果您设置了容器注册表,那么至少使用 ACR,它会将 ACR URL 作为 docker 映像名称的前缀。但是,在 Azure DevOps 中执行此操作时,该 URL 会被加密。这没有什么问题,但是当您列出图像时会引起混乱,因为它会显示为 ***/ImageName。

其次,将图像保存为artifact staging目录中的TAR文件。

- task: Docker@2
  displayName: 'Save image to TAR'
  inputs:
    repository: '$(imageName)'
    command: save            
    arguments: '--output $(build.artifactstagingdirectory)/$(imageName).image.tar $(imageName):$(Build.BuildId)'
    addPipelineData: false   

这将包括您发布构建时的 .tar 文件。

接下来的步骤是在部署作业期间。

下载构建工件并部署 ARM 模板后,您需要从 .tar 文件加载 docker 映像。

- task: Docker@2
  displayName: 'Load Image from Tar'
  inputs: 
    command: load
    arguments: '--input $(build.artifactstagingdirectory)/$(buildArtifactName)/$(imageName).image.tar'

现在 docker 镜像已加载,您需要重新标记该镜像并发布它。

- task: Docker@2
  displayName: 'ReTag Image with ACR URL - BuildId'
  inputs:
    containerRegistry: 'Hopeful Momma Designs ACR'
    repository: $(imageName)
    command: tag
    arguments: '$(imageName):$(Build.BuildId) $(containerRegistryUrl)/$(imageName):$(Build.BuildId)'
- task: Docker@2
  displayName: 'ReTag Image with ACR URL - latest'
  inputs:
    containerRegistry: 'Hopeful Momma Designs ACR'
    repository: $(imageName)
    command: tag
    arguments: '$(imageName):$(Build.BuildId) $(containerRegistryUrl)/$(imageName):latest'
      
- task: Docker@2
  displayName: push
  inputs:
    containerRegistry: 'Hopeful Momma Designs ACR'    
    repository: $(imageName)       
    command: push
    dockerfile: '**/Dockerfile'
    buildContext: 'HopefulMommaDesignsAPI'  
    tags: |
      $(Build.BuildId)
      latest

注意:如果您的 Azure 容器注册表是 ARM 模板的一部分,则包含 containerRegistry 的 Docker 命令将失败,因为您必须手动设置从 Azure DevOps 到 Azure 的服务连接Container Registry,然后您才能在 YAML 文件中将其作为 containerRegistry 引用。

这对我来说没什么大不了的,因为无论如何我通常都会分段处理管道。我将确保构建工作,然后我将确保 ARM 模板工作,然后我将确保 docker 图像推送到 ACR。如果您要从头开始重建环境,只需注释掉 ARM 模板步骤之后的部署步骤即可部署基础架构,然后取消注释其余步骤。这不是最干净的解决方案,但我更喜欢这样,而不是使用单独的管道来部署基础设施。

【讨论】:

    【解决方案2】:

    您将容器发布到 Azure 容器注册表。容器不是传统意义上的构建工件。

    我怀疑您有鸡/蛋问题。您想在部署过程中创建注册表,但在构建过程中没有注册表。那么如何将容器部署到直到下一阶段才会存在的注册表,对吗?事实上,您会发现您需要为 ACR 创建一个服务连接,然后才能向它发布资源。 ARM 模板无法为您做到这一点。

    在这种情况下,将应用程序的需求与更大的基础设施需求分开是很常见的。 ACR 是基础设施的支持部分。在这种情况下,通常有一个单独的管道来创建所需的支持基础设施来解决先有鸡还是先有蛋的问题。

    另外,请注意正确的术语。没有什么叫做“Azure 资源容器”。有一种叫做“Azure Container Registry”的东西,我假设你正在谈论它。

    【讨论】:

    • 是的,我指的是 Azure 容器注册表。我可以看到我可能需要先手动或通过不同的管道创建 ACR。不过,我会将 docker 映像加载到其中的应用服务怎么样,或者只是我还没有遇到过的完全不同的东西?
    猜你喜欢
    • 2019-10-01
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多