GitLab CI 无需 DinD 即可登录私有仓库

rob*_*liv 2 continuous-integration gitlab gitlab-ci gitlab-ci-runner devops

我是 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"
Run Code Online (Sandbox Code Playgroud)

我想这样做(整个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"
Run Code Online (Sandbox Code Playgroud)

如果我尝试这样做,它会说它无法进行身份验证:

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
Run Code Online (Sandbox Code Playgroud)

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

Bic*_*hon 5

你的问题

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

第一 CI (DinD)

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

  • Gitlab-runner 执行器下载映像docker:18.09.8-dind,然后将映像作为 CI 的服务启动
  • Gitlab-runner 执行器下载基础映像 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-runner 执行器尝试下载作业指定的基础镜像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-runner 执行器的方法。遗憾的是,没有独特的方法可以做到这一点,因为这取决于您使用的执行器。由于您没有在问题中指定执行器,因此我将给出我认为对于 Docker 和 Kubernetes 最常用且最方便的解决方案。

使用DOCKER_AUTH_CONFIG

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

在这里,我介绍第二种准备凭据的方法。调整以下内容来生成您自己的authfid :

echo -n "USERNAME:PASSWORD" | base64
VVNFUk5BTUU6UEFTU1dPUkQ=
Run Code Online (Sandbox Code Playgroud)

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

{
  "auths": {
    "artifactory.example.com:5000": {
      "auth": "VVNFUk5BTUU6UEFTU1dPUkQ="
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

使用这种方法,您的 CI 就变成了:

stages:
  - run_script

run_script:
  image: artifactory.example.com:5000/repo/powershell-core:6.3
  stage:
    run_script
  script:
    - pwsh -command "get-process"
Run Code Online (Sandbox Code Playgroud)

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

Kubernetes 执行器

如果您使用 Kubernetes 执行器,最简单的解决方案是创建一个包含存储库凭据的密钥。使用跑步者的 Helm 图表,可以在图表安装过程中使用图表的 Values.yamlrunners.imagePullSecrets中描述的密钥给出此秘密。此解决方案使用 Kubernetes 的机制对注册表进行身份验证,如Kubernetes 文档中所述。

我给出这个例子是为了说明一个事实,即运行程序对注册表的身份验证是使用独立于运行程序本身的机制。在这种情况下,就是 Kubernetes 的机制。因此,运行者没有唯一的身份验证方法。