Azure DevOps的NuGet包存储库和Docker

15

有没有一种好的方式来创建一个认证机制,使得Devops能够访问artifact NuGet feed?我想为我的团队创建一个基础镜像,他们可以从我们的Azure容器注册表中拉取一个可以访问我们的devops nuget feed的镜像。理想情况下,人们不需要在每个项目中都有相同的Dockerfile代码,从其主机构建系统中获取PAT。这也将使我们能够更好地进行CICD。

我的当前解决方案

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

ARG IT_PAT
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS "{\"endpointCredentials\": [{\"endpoint\": \"https://pkgs.dev.azure.com/MNPIT/_packaging/MNP/nuget/v3/index.json\",\"username\": \"build\",\"password\": \"${IT_PAT}\"}]}"
RUN mkdir -p $HOME/.nuget/plugins
WORKDIR /deps

# Downloads and installs the NuGet credential plugin so we can login to the private NuGet feed
RUN curl https://github.com/microsoft/artifacts-credprovider/releases/download/v0.1.24/Microsoft.NetCore2.NuGet.CredentialProvider.tar.gz -L -o creds.tar.gz -s
RUN tar -xzf creds.tar.gz
RUN cp -r plugins/netcore/ ~/.nuget/plugins
  • 每个构建文件中都有股票代码
  • 每个用户都使用PAT配置其环境变量
  • 在每次构建时传递PAT
  • 无法与自动化构建系统配合使用
  • 每个构建文件中都包含股票代码
  • 每个用户都需要使用个人访问令牌(PAT)配置他们的环境变量
  • 在每个构建中传递PAT
  • 无法与自动化构建系统一起使用

  • 嗨,你有机会尝试下面的解决方法了吗?进展如何? - Levi Lu-MSFT
    不好意思,暂时还没有。我已经开始着手处理另一个问题了,但是我会尝试在下周回过来处理这个问题。 - greven
    3个回答

    21

    YAML

    1. 运行 NuGetAuthenticate 任务以将VSS_NUGET_ACCESSTOKEN 添加到环境变量 (获取更多信息)
    2. 将令牌作为参数传递给 Docker 任务
    - task: NuGetAuthenticate@0
    
    - task: Docker@2
      displayName: 'build docker image'
      inputs:
        command: build
        containerRegistry: 'happycodeacr'
        repository: 'hc-app-sample-api-dev'
        buildContext: '$(Pipeline.Workspace)/app'
        Dockerfile: '$(Pipeline.Workspace)/app/src/HappyCode.Api/Dockerfile'
        arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'
        tags: |
          latest
          $(Build.BuildId)
    

    通过 NuGetAuthenticate 任务生成令牌

    Dockerfile

    1. 下载并安装工件提供程序 (更多信息)
    2. 接收令牌
    3. 使用包含 NuGet 恢复过程的 feed URL 和令牌设置 VSS_NUGET_EXTERNAL_FEED_ENDPOINTS 环境变量
    4. 复制 NuGet.config 文件
    5. 运行 dotnet restore
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
    WORKDIR /work
    
    RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh
    ARG FEED_ACCESSTOKEN
    ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS \
        "{\"endpointCredentials\": [{\"endpoint\":\"https://happycode.pkgs.visualstudio.com/_packaging/hc-nuget-feed/nuget/v3/index.json\", \"password\":\"${FEED_ACCESSTOKEN}\"}]}"
    COPY ["NuGet.config", "./"]
    
    COPY ["src/*/*.csproj", "./"]
    RUN for projectFile in $(ls *.csproj); \
        do \
          mkdir -p ${projectFile%.*}/ && mv $projectFile ${projectFile%.*}/; \
        done
    RUN dotnet restore /work/HappyCode.Api/HappyCode.Api.csproj
    
    # further instructions 
    
    

    Docker构建任务期间令牌的消耗量


    2
    不要忘记在构建Docker容器的构建代理中赋予一个读取器角色,特别是如果构件库位于组织级别或不同项目中。希望这能为某些人节省几个小时的调试时间! - krb224
    1
    我在使用传统的Azure DevOps构建流程时遇到了一个问题,即在Docker任务“构建镜像”中,在构建参数中,我必须传递FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)而不是从YAML复制的--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN) - piotr.gradzinski

    14
    我想为我的团队创建一个基础映像,让他们可以从我们的Azure容器注册表中拉取一个具有访问我们devops nuget feed的映像。
    您可以在映像中包含凭据以实现此目的,但出于安全考虑,最好添加一些额外的步骤或代码来从映像外部传递凭据。
    根据您当前的解决方案,您可以使用系统预定义变量 $(System.AccessToken) 在Azure DevOps CICD管道中获取安全令牌。然后在docker构建任务中,将访问令牌作为参数传递给ARG IT_PAT, --build-arg IT_PAT=$(System.AccessToken) 除了使用NuGet凭证插件外,您还可以使用dotnet cli向nuget源添加凭据。然后在构建参数中传递$(System.AccessToken)。请参见下文:
    ARG PAT
    COPY . .
    RUN dotnet nuget add source "your-source-url" --name "source-name" --username "useless" --password "$PAT" --store-password-in-clear-text
    RUN dotnet restore
    

    另一个解决方法是在构建上下文中包含nuget.config文件。但是,您需要先包含一个不带凭据的nuget.config文件,然后添加额外的nuget任务以将凭据添加到配置文件中。然后在docker文件中复制nuget.config。请参见以下内容:
    添加一个nuget任务,运行以下自定义命令以将凭据添加到nuget.config文件中。
    sources Add -Name "MyPackages" -Source "https://my.pkgs.visualstudio.com/_packaging/MyPackages/nuget/v3/index.json" -username any -password $(System.AccessToken) -ConfigFile Source/Nuget.config -StorePasswordInClearText
    

    将nuget.config文件复制到docker文件中,在还原完成后不要忘记删除nuget.config文件:

    COPY *.csproj .
    COPY ./nuget.config .
    RUN dotnet restore
    RUN rm nuget.config
    

    如果您正在使用基于Yaml的管道,您也可以查看容器作业。然后通过设置容器终结点来使用您的私有容器。然后您可以直接在管道中使用还原任务。请参见以下示例,nuget还原任务将在您的私有容器中运行,并且可以通过将属性vstsFeed指定到您的nuget feed来直接访问您的Azure feeds:

    当您在管道中指定容器时,代理将首先获取并启动容器。然后,作业的每个步骤都将在容器内运行。

    container:
      image: myprivate/registry:ubuntu1604
      endpoint: private_dockerhub_connection
    
    steps:
    - task: NuGetCommand@2
      inputs:
        command: 'restore'
        feedsToUse: 'select'
        vstsFeed: 'my-azure-nuget-feed'
        restoreSolution: '**/*.sln'
    

    欲了解更多信息,请查看此帖子


    1
    我最初考虑设置这样的系统(使用CICD访问令牌),但认为这会暴露敏感数据,所以放弃了。不过,在私有ACR中应该没问题。PAT可能很快就会失效,是吗? - greven
    是的,此令牌有效期为48小时,请参见此线程 - Levi Lu-MSFT

    2

    除了其他回复之外 - 您可以避免在运行时修改 nuget.config 并改用环境变量。 在身份验证期间,NuGet 检查格式的环境变量

    NuGetPackageSourceCredentials_'name',其中'name'是 nuget.config 文件中 feed 的键。

    例如

    NuGetPackageSourceCredentials_MyPackages="Username=unused_but_required_by_nuget;Password=$(System.AccessToken)"


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接