【问题标题】:Using a private Docker Image from Gitlab Registry as the base image for CI使用来自 Gitlab Registry 的私有 Docker 镜像作为 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

【问题讨论】:

    标签: gitlab gitlab-ci gitlab-ci-runner


    【解决方案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,因为它们过期并且依赖于项目,因此您实际上不能为每个项目使用一个令牌。使用您自己的登录几乎是目前唯一可用的解决方案(很高兴在这个问题上得到纠正)。

      【讨论】:

      猜你喜欢
      • 2023-01-28
      • 2020-02-24
      • 2019-08-03
      • 2017-12-31
      • 1970-01-01
      • 2020-01-20
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      相关资源
      最近更新 更多