使用来自 Gitlab Registry 的私有 Docker 镜像作为 CI 的基础镜像

Posted

技术标签:

【中文标题】使用来自 Gitlab Registry 的私有 Docker 镜像作为 CI 的基础镜像【英文标题】:Using a private Docker Image from Gitlab Registry as the base image for CI 【发布时间】:2016-11-11 04:51:23 【问题描述】:

如果我想使用来自 Gitlab Registry 的镜像作为另一个 CI 构建的基础镜像,我应该如何进行身份验证?

根据https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md#using-a-private-docker-registry我首先要手动登录runner机器。不知何故,用现有的 Gitlab 用户登录感觉很奇怪。

有没有办法使用 CI 变量“CI_BUILD_TOKEN”(描述为“用于通过 GitLab 容器注册表进行身份验证的令牌”)进行身份验证以从 Gitlab 注册表中提取基础映像?

编辑:我发现我可以使用来自公共项目的图像。但我并不想公开我的 docker 项目。

更新:从 Gitlab 8.14 开始,您可以只使用 docker 注册表中构建的 docker 镜像。见https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md#support-for-gitlab-integrated-registry

【问题讨论】:

【参考方案1】:

上述所有答案(包括已接受的答案)均已弃用,这可能在 2021 年实现:

https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#access-an-image-from-a-private-container-registry


TL;DR

使用以下格式的适当身份验证信息设置 CI/CD 变量 DOCKER_AUTH_CONFIG 值:

第 1 步:

# The use of "-n" - prevents encoding a newline in the password.
echo -n "my_username:my_password" | base64

# Example output to copy
bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=

第 2 步(此 JSON 是要为 DOCKER_AUTH_CONFIG 变量设置的值):


    "auths": 
        "registry.example.com:5000": 
            "auth": "(Base64 content from above)"
        
    

【讨论】:

【参考方案2】:

您可能首先必须登录到您要使用的镜像的 gitlab 容器注册表,请参见下面的示例。注意 before_script: 基本上是在使用图像之前对您进行身份验证。

image: docker:latest
services:
  - docker:dind

stages:
  - build

variables:
  CONTAINER_RELEASE_IMAGE: registry.gitlab.com/obonyojimmy/node-mono-clr:latest

before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_BUILD_TOKEN registry.gitlab.com

build-app:
  stage: build
  image: $CONTAINER_RELEASE_IMAGE
  script:
    - npm run build

【讨论】:

docker 会抛出一个错误,除非你添加 "$": $CONTAINER_RELEASE_IMAGE【参考方案3】:

截至 2018 年 9 月,这绝对是可能的。我将在此处发布我的幼稚实现。

上下文:

您将需要利用 docker:dind 服务,该服务可让您在 docker 容器内运行 docker 命令。 这将要求您使用有效的docker login,您可以使用 GitLab 的内置变量(gitlab-ci-token$CI-JOB-TOKEN)来做到这一点。 然后您应该能够对您的存储库的注册表进行身份验证(例如 $REGISTRY 值:registry.gitlab.com/$USER/$REPO:$TAG),这将允许您从 CI/CD 上下文以及任何经过身份验证的环境中推送或拉取 docker 容器码头服务器。

实施:

在顶层创建此块以确保它在以下作业之前运行:

before_script: 
        - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $REGISTRY

构建图像并将其保存到注册表的工作:

build_container:
    image: docker:latest
    stage: build
    services:
        - docker:dind
    script:
        - docker build -t $REGISTRY .
        - docker push $REGISTRY

使用自定义图像的作业:

build_app:
    image: $REGISTRY
    stage: deploy
    script:
        - npm run build

关于跨仓库作业:

我通过创建一个“bot”GitLab 用户并为他们分配对 repos/groups 的访问权限来实现这一点。然后只需将gitlab-ci-token$CI_JOB_TOKEN 替换为适当的环境变量即可。仅当基本映像是私有的时才需要这样做。

【讨论】:

before_script 不会在作业“之前”运行。它简单地与脚本元素连接,并在作业中指定的图像的上下文中运行。鉴于此,这看起来行不通? 我通常在扩展作业中使用before_script,以便它可以与多个其他 docker 作业共享(每个用于推送到 gitlab/dockerhub/等,具体取决于标签/分支)。它旨在在映像的上下文中运行并利用dind 服务,因为映像需要能够访问任何loginbuildpush 的docker 命令才能工作。只要login 先出现,这一切都按预期工作。我将此策略用于多个生产应用程序;如果您遇到特定问题,我可以尝试帮助您。【参考方案4】:

现在有可能,他们几个月前就包含了这个选项。

使用gitlab-ci-token作为用户,变量$CI_BUILD_TOKEN作为密码。

此示例适用于 GitLab 8.13.6。如果需要,它会构建测试映像,并在下一阶段使用它来执行语法检查:

build_test:
  stage: build_test_image
  script:
    - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
    - docker build -t $CI_REGISTRY_IMAGE:test -f dockerfiles/test/Dockerfile .
    - docker push $CI_REGISTRY_IMAGE:test
  tags:
    - docker_build
  environment: test

test_syntax:
  image: $CI_REGISTRY_IMAGE:test
  stage: test
  script:
    - flake8 --ignore=E501,E265,E402 .

更新:重新阅读问题,接受的答案是正确的。在我的示例中,作业test_syntax 将无法向注册表进行身份验证,除非用户从运行机器手动登录。虽然,如果 2 个 runner 在同一个主机上,它可以工作,但无论如何这不是最好的解决方案。

在gitlab-ci-multi-runner 1.8 中有一个选项可以将注册表凭据添加为变量,因此您只需登录一次即可获取编码凭据。见documentation。

【讨论】:

你用什么类型的跑步者来做这个?如果您使用的是 shell 运行器,那么 GitLab CI 不会从注册表中提取镜像,而是使用您在前一阶段在主机上构建的镜像。 实际上我使用了 2 个跑步者。一个带有 shell 执行器,另一个带有 docker 执行器。 shell 执行器的预期用途只是构建 Docker 映像,这就是我使用标签 docker_build 的原因。还要注意工作test_syntax 中的image 指令以及build_test 中缺少它。【参考方案5】:

不,这目前无法以任何优雅的方式实现。 GitLab 应该为基础镜像实现显式凭据,这将是最直接和正确的解决方案。

您需要在 GitLab Runner 机器上docker login。您不能使用gitlab-ci-token,因为它们过期并且依赖于项目,因此您实际上不能为每个项目使用一个令牌。使用您自己的登录几乎是目前唯一可用的解决方案(很高兴在这个问题上得到纠正)。

【讨论】:

谢谢。你说得对。现在不可能。我发现的指针:gitlab.com/gitlab-org/gitlab-ce/issues/19219 和 gitlab.com/gitlab-org/gitlab-ce/issues/19275 为了跟进这件事,有几个 gitlab 票证与以更优雅的方式公开此功能有关 (gitlab.com/gitlab-org/gitlab-ce/issues/19275)。但是,这似乎现在积压了。希望在获得更多支持的情况下,该功能将成为团队认为与用户社区一样重要的东西。

以上是关于使用来自 Gitlab Registry 的私有 Docker 镜像作为 CI 的基础镜像的主要内容,如果未能解决你的问题,请参考以下文章

来自守护进程的错误响应:registry.gitlab.com 存储库的拉取访问被拒绝或可能需要“docker login”

docker中建立私有git服务器[gitlab]

构建Docker私有仓库Gitlab仓库和持续集成环境

docker使用registry搭建本地私有仓库

.npmrc 忽略了私有包

无法在 Gitlab 上发布私有 npm 包 - E404 Not found PUT