使用来自 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
服务,因为映像需要能够访问任何login
、build
、push
的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”