不带DinD的GitLab CI登录到私人仓库

时间:2020-01-13 15:18:10

标签: continuous-integration gitlab devops gitlab-ci gitlab-ci-runner

我是GitLab的新手,不确定是否可行,我已经在内部安装了GitLab并与Artifactory私人仓库一起工作。

我一直使用DinD配置,使用Docker作为DinD服务的主要映像,然后在登录和从私有存储库提取不同映像的阶段。

但是我听说有可能在没有DinD的情况下缩短执行时间。所需的图像会在阶段开始时拉出。

代替此:

image: docker:latest

services:
  - docker:18.09.8-dind

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_HOST: tcp://localhost:2375 

stages:
  - run_script

run_script:
  stage:
    run_script
  script:
    - docker login -u $DOCKER_TECHNICAL_USER -p $DOCKER_TECHNICAL_USER_PASSWORD $DOCKER_REGISTRY_URL
    - docker pull artifactory.example.com:5000/repo/powershell-core:6.3
    - docker run -it artifactory.example.com:5000/repo/powershell-core:6.3 pwsh -command "get-process"

我想这样做(整个yml):

stages:
  - run_script

run_script:
  before_script:
    - docker login -u $DOCKER_TECHNICAL_USER -p $DOCKER_TECHNICAL_USER_PASSWORD $DOCKER_REGISTRY_URL
  image: artifactory.example.com:5000/repo/powershell-core:6.3
  stage:
    run_script
  script:
    - pwsh -command "get-process"

如果我尝试此操作,它说它无法验证:

ERROR: Job failed: image pull failed: rpc error: code = Unknown desc = Get https://artifactory.example.com:5000/v2/repo/powershell-core/manifests/6.3: unknown: Authentication is required

这是不可能的吗,还是我在某个地方犯了一个错误并且可以修复?

1 个答案:

答案 0 :(得分:3)

您的问题

您的CI失败,因为在下载基本映像artifactory.example.com时它不知道artifactory.example.com:5000/repo/powershell-core:6.3的凭据。 为了让您理解,我将解释您提供的2个CI的不同步骤,然后提供解决方案的轨道。

第一个CI(DinD)

在您的第一个CI(使用DinD的CI)中,发生的事情是:

  • Gitlab运行程序执行程序下载图像docker:18.09.8-dind,然后启动该图像作为CI的服务
  • Gitlab运行程序执行程序下载基本映像 docker:latest,然后使用它执行您的工作run_script
  • 在您的docker docker:latest中,作业run_script使用您的凭据并通过DinD服务登录您的私有存储库
  • 然后,它通过DinD服务下载图像artifactory.example.com:5000/repo/powershell-core:6.3并使用该图像运行脚本

第二个CI

在此示例中,您试图仅执行图像artifactory.example.com:5000/repo/powershell-core:6.3并使用该图像运行脚本。 您是对的,对于一个简单的目标,例如,不需要DinD。 这是您的CI所做的分析:

  • Gitlab运行程序执行程序尝试下载作业run_scriptartifactory.example.com:5000/repo/powershell-core:6.3
  • 指定的基本映像
  • 存储库artifactory.example.com要求提供凭据
  • 执行程序不知道任何凭据,因此它返回错误并停止运行

如您所见,在这种情况下,作业run_script从未执行过,因为执行者无法下载作业指定的基本映像。 作业的before_script部分(负责登录)不会执行,因为 before_script是在基本映像中执行的,而最后一个不能由执行者下载。

因此,解决方案是简单地将凭据提供给执行者,以便它可以登录,然后下载作业的基本映像。 另外,应删除作业的before_script部分,因为它在您打算的时间没有执行,因此没有必要。

解决方案

因此,您寻求的是一种将存储库artifactory.example.com的凭据提供给您的工作正在使用的Gilab运行器执行程序的方法。 可悲的是,没有唯一的方法可以执行此操作,因为它取决于您使用的执行程序。 由于您没有在问题中指定执行器,因此,我将为Docker和Kubernetes提供最常用和最方便的解决方案。

使用DOCKER_AUTH_CONFIG

一种与多个执行程序一起使用的解决方案是直接在Gitlab中定义一个(秘密)变量,如this Gitlab documentation中所述。

在这里,我介绍第二种方法来准备您的凭据。修改以下内容以生成自己的auth文件:

echo -n "USERNAME:PASSWORD" | base64
VVNFUk5BTUU6UEFTU1dPUkQ=

然后在Gitlab中创建一个变量DOCKER_AUTH_CONFIG,其中包含您首先适应的以下内容:

{
  "auths": {
    "artifactory.example.com:5000": {
      "auth": "VVNFUk5BTUU6UEFTU1dPUkQ="
    }
  }
}

使用此方法,您的CI只需变为:

stages:
  - run_script

run_script:
  image: artifactory.example.com:5000/repo/powershell-core:6.3
  stage:
    run_script
  script:
    - pwsh -command "get-process"

此解决方案适用于大多数情况。 但是,根据执行者和您对其的访问权限,您可能需要使用其他特定的解决方案。

Kubernetes执行器

如果使用Kubernetes执行器,最简单的解决方案是创建一个包含存储库凭据的密钥。 使用跑步者的Helm图表,可以在values.yaml of the chart中描述的runners.imagePullSecrets键在图表安装过程中提供此秘密。 此解决方案使用Kubernetes的机制向Kubernetes documentation中所述的注册表进行身份验证。

我给出这个示例来说明一个事实,即跑步者对注册表的身份验证使用的机制与跑步者本身无关。在这种情况下,这就是Kubernetes的机制。因此,跑步者没有唯一的身份验证方式。