- 查看 Container Registry
- 使用来自 Container Registry 的镜像
- 镜像命名约定
- 使用 Container Registry 进行身份验证
- 使用 Docker 命令构建和推送镜像
- 使用 GitLab CI/CD 构建和推送
- 删除镜像
- 限制
- 为项目禁用 Container Registry
- 更改 Container Registry 的可见性
- Container Registry 可见性权限
- 极狐GitLab Container Registry 故障排查
GitLab Container Registry
通过将 Docker Container Registry 集成到极狐GitLab 中,每个极狐GitLab 项目都可以拥有自己的空间来存储其 Docker 镜像。
您可以在 https://docs.docker.com/registry/introduction/ 阅读有关 Docker Registry 的更多信息。
本文档是用户指南。要了解如何为您的极狐GitLab 实例启用容器镜像库,请访问管理员文档。
查看 Container Registry
您可以查看项目或群组的 Container Registry。
- 转到您的项目或群组。
- 转至 软件包与镜像库 > 容器镜像库。
您可以在此页面上搜索、排序、过滤和删除容器。您可以通过从浏览器复制 URL 来共享过滤视图。
只有项目或群组的成员才能访问私有项目的 Container Registry。
如果项目是公开的,那么 Container Registry 也是公开的。
查看特定镜像的标签
您可以查看与给定容器镜像关联的标签列表:
- 前往您的项目或小组。
- 转至 软件包与镜像库 > 容器镜像库。
- 选择您感兴趣的容器镜像。
将打开 Container Registry 标签详情 页面。您可以查看每个标签的详细信息,例如发布时间、消耗的存储量以及清单和配置摘要。
您可以在此页面上搜索、排序(按标签名称)、过滤和 删除 标签。 您可以通过从浏览器复制 URL 来共享过滤视图。
使用来自 Container Registry 的镜像
要下载并运行托管在 GitLab Container Registry 中的容器镜像:
- 将链接复制到您的容器镜像:
- 转到您的项目或群组的 软件包与镜像库 > 容器镜像库 并找到您想要的镜像。
- 在镜像名称旁边,单击 复制 按钮。
-
将
docker run
与镜像链接一起使用:docker run [options] registry.example.com/group/project/image [arguments]
身份验证需要从私有仓库下载镜像。
有关运行 Docker 容器的更多信息,请访问 Docker 文档。
镜像命名约定
镜像遵循以下命名约定:
<registry URL>/<namespace>/<project>/<image>
例如,如果您的项目是 gitlab.example.com/mynamespace/myproject
,那么您的镜像必须至少命名为 gitlab.example.com/mynamespace/myproject/my-app
。
您可以将其他名称附加到镜像名称的末尾,深度最多为三层。
例如,这些都是名为 myproject
的项目中镜像的所有有效镜像名称:
registry.example.com/mynamespace/myproject:some-tag
registry.example.com/mynamespace/myproject/image:latest
registry.example.com/mynamespace/myproject/my/image:rc1
使用 Container Registry 进行身份验证
要使用 Container Registry 进行身份验证,您可以使用:
要求最小范围是:
- 对于读(拉取)访问,
read_registry
。 - 对于写(推送)访问,
write_registry
和read_registry
。
要进行身份验证,请运行 docker
命令。 例如:
docker login registry.example.com -u <username> -p <token>
使用 Docker 命令构建和推送镜像
在构建和推送镜像之前,您必须对 Container Registry 进行身份验证。
要构建并推送到 Container Registry:
-
使用 Container Registry 进行身份验证。
-
运行命令构建或推送。例如,要构建:
docker build -t registry.example.com/group/project/image .
或者推送:
docker push registry.example.com/group/project/image
要查看这些命令,请转到您项目的 软件包与镜像库 > 容器镜像库。
使用 GitLab CI/CD 构建和推送
使用 GitLab CI/CD 构建镜像并将其推送到容器镜像库。使用它可以从您创建的 Docker 镜像测试、构建和部署您的项目。
使用 GitLab CI/CD 进行身份验证
在使用 GitLab CI/CD 构建和推送镜像之前,您必须通过 Container Registry 进行身份验证。
要使用 CI/CD 进行身份验证,您可以使用:
-
CI_REGISTRY_USER
CI/CD 变量。此变量具有对 Container Registry 的读写访问权限,并且仅对一项作业有效。它的密码也会自动创建并分配给
CI_REGISTRY_PASSWORD
。docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
-
CI 作业令牌。
docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
-
部署令牌最小范围为:
- 对于读(拉取)访问,
read_registry
。 - 对于写(推送)访问,
write_registry
。
docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
- 对于读(拉取)访问,
-
个人访问令牌 的最小范围为:
- 对于读(拉取)访问,
read_registry
。 - 对于写(推送)访问,
write_registry
。
docker login -u <username> -p <access_token> $CI_REGISTRY
- 对于读(拉取)访问,
配置您的 .gitlab-ci.yml
文件
您可以配置您的 .gitlab-ci.yml
文件来构建镜像并将其推送到 Container Registry。
- 如果多个作业需要身份验证,请将身份验证命令放在
before_script
中。 - 在构建之前,使用
docker build --pull
来获取对基础镜像的更改。它需要稍长的时间,但它可以确保您的镜像是最新的。 - 在每次
docker run
之前,执行一个显式的docker pull
来获取刚刚构建的镜像。如果您使用多个在本地缓存镜像的 runner,这一点尤其重要。 如果您在镜像标签中使用 Git SHA,则每个作业都是独一无二的,您永远不应拥有过期的镜像。但是,如果在依赖项更改后重新构建给定的提交,仍然可能有一个陈旧的镜像。 - 不要直接构建到
latest
标签,因为多个作业可能同时发生。
GitLab CI/CD 的 Container Registry 示例
如果您在 runner 上使用 Docker-in-Docker,.gitlab-ci.yml
应该是:
build:
image: docker:19.03.12
stage: build
services:
- docker:19.03.12-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY/group/project/image:latest .
- docker push $CI_REGISTRY/group/project/image:latest
您还可以使用其他 CI/CD 变量来避免硬编码:
build:
image: docker:19.03.12
stage: build
services:
- docker:19.03.12-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
在这里,$CI_REGISTRY_IMAGE
将被解析为与该项目相关联的库的地址。由于 $CI_COMMIT_REF_NAME
解析为分支或标签名称,并且您的分支名称可以包含正斜杠(例如,feature/my-feature
),所以使用 $CI_COMMIT_REF_SLUG
作为镜像标签会更安全。这是因为镜像标签不能包含正斜杠。我们还声明了我们自己的变量 $IMAGE_TAG
,将两者结合起来以节省我们在 script
部分中的一些输入。
这是一个更详细的示例,它将任务分成 4 个搜了下阶段,包括两个并行运行的测试。build
存储在容器镜像库中,供后续阶段使用,在需要时下载镜像。 对 main
的更改也被标记为 latest
并使用特定于应用程序的部署脚本进行部署:
image: docker:19.03.12
services:
- docker:19.03.12-dind
stages:
- build
- test
- release
- deploy
variables:
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
script:
- docker build --pull -t $CONTAINER_TEST_IMAGE .
- docker push $CONTAINER_TEST_IMAGE
test1:
stage: test
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker run $CONTAINER_TEST_IMAGE /script/to/run/tests
test2:
stage: test
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker run $CONTAINER_TEST_IMAGE /script/to/run/another/test
release-image:
stage: release
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
- docker push $CONTAINER_RELEASE_IMAGE
only:
- main
deploy:
stage: deploy
script:
- ./deploy.sh
only:
- main
environment: production
docker pull
。如果您更喜欢使用 image:
隐式拉取构建的镜像,并使用 Docker 或 Kubernetes executor,确保 pull_policy
设置为 always
。使用 Container Registry 中的 Docker-in-Docker 镜像
要将您自己的 Docker 镜像用于 Docker-in-Docker,除了 Docker-in-Docker 部分中的步骤之外,还请按照以下步骤操作:
- 更新
image
和service
以指向您的镜像库。 - 添加服务别名。
下面是 .gitlab-ci.yml
的例子:
build:
image: $CI_REGISTRY/group/project/docker:19.03.12
services:
- name: $CI_REGISTRY/group/project/docker:19.03.12-dind
alias: docker
stage: build
script:
- docker build -t my-docker-image .
- docker run my-docker-image /script/to/run/tests
如果忘记设置服务别名,docker:19.03.12
镜像无法找到 dind
服务,会抛出类似如下错误:
error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such host
使用带有 Dependency Proxy 的 Docker-in-Docker 镜像
要将您自己的 Docker 镜像与 Dependency Proxy 一起使用,除了 Docker-in-Docker 部分中的步骤之外,还请按照以下步骤操作:
- 更新
image
和service
以指向您的镜像库。 - 添加服务别名。
下面是 .gitlab-ci.yml
的例子:
build:
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:19.03.12
services:
- name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:18.09.7-dind
alias: docker
stage: build
script:
- docker build -t my-docker-image .
- docker run my-docker-image /script/to/run/tests
如果忘记设置服务别名,docker:19.03.12
镜像无法找到 dind
服务,会抛出类似如下错误:
error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such host
删除镜像
您可以通过多种方式从 Container Registry 中删除镜像。
在自助管理的实例上,删除镜像不会释放存储空间 - 它只会将镜像标记为可以删除。要实际删除镜像并恢复存储空间,以防它们未被引用,管理员必须运行垃圾收集。
从极狐GitLab 中删除镜像
从极狐GitLab 中删除镜像:
- 导航到您的项目或群组的 软件包与镜像库 > 容器镜像库。
-
在 容器镜像库 页面,您可以通过以下任一方式选择要删除的内容:
- 通过单击红色的 Trash 图标删除整个仓库及其包含的所有标签。
- 导航到仓库,并通过单击要删除的标签旁边的红色 Trash 图标来单独或批量删除标签。
- 在对话框中,单击 删除标签。
使用 GitLab CI/CD 删除镜像
以下示例定义了两个阶段:build
和 clean
。build_image
作业为分支构建 Docker 映像,delete_image
作业将其删除。下载 reg
可执行文件并用于删除与 $CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG
预定义 CI/CD 变量 匹配的镜像。
要使用此示例,请更改 IMAGE_TAG
变量以满足您的需要:
stages:
- build
- clean
build_image:
image: docker:19.03.12
stage: build
services:
- docker:19.03.12-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
only:
- branches
except:
- main
delete_image:
image: docker:19.03.12
stage: clean
services:
- docker:19.03.12-dind
variables:
IMAGE_TAG: $CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG
REG_SHA256: ade837fc5224acd8c34732bf54a94f579b47851cc6a7fd5899a98386b782e228
REG_VERSION: 0.16.1
before_script:
- apk add --no-cache curl
- curl --fail --show-error --location "https://github.com/genuinetools/reg/releases/download/v$REG_VERSION/reg-linux-amd64" --output /usr/local/bin/reg
- echo "$REG_SHA256 /usr/local/bin/reg" | sha256sum -c -
- chmod a+x /usr/local/bin/reg
script:
- /usr/local/bin/reg rm -d --auth-url $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $IMAGE_TAG
only:
- branches
except:
- main
reg
版本,然后通过更改 delete_image
作业中定义的 REG_SHA256
和 REG_VERSION
变量来更新代码示例。使用清理策略删除镜像
您可以为每个项目创建一个清理策略,以确保定期从 Container Registry 中删除较旧的标签和镜像。
限制
- 推送镜像后,不支持移动或重命名现有的 Container Registry 仓库,因为镜像存储在与仓库路径匹配的路径中。要使用 Container Registry 移动或重命名仓库,您必须删除所有现有镜像。
- 在 12.10 版本之前,清理策略不会删除使用与
latest
标签相同的镜像 ID 的任何标签。
为项目禁用 Container Registry
默认情况下启用容器镜像库。
但是,您可以删除项目的 Container Registry:
- 转到您项目的 设置 > 常规 页面。
- 展开可见性、项目功能、权限部分并禁用Container Registry。
- 单击保存更改。
软件包与镜像库 > 容器镜像库 条目从项目的侧边栏中删除。
更改 Container Registry 的可见性
引入于 14.2 版本。
默认情况下,每个有权访问项目的人都可以看到 Container Registry。 但是,您可以更改项目的 Container Registry 的可见性。
有关此设置授予用户的权限的更多详细信息,请参阅 Container Registry 可见性权限。
- 转到您项目的 设置 > 通用 页面。
- 展开可见性、项目功能、权限部分。
-
在 容器镜像库 下,从下拉列表中选择一个选项:
-
具有访问权限的任何人(默认):Container Registry 对所有有权访问项目的人可见。如果项目是公开的,那么 Container Registry 也是公开的。如果项目是内部的或私有的,那么 Container Registry 也是内部的或私有的。
-
仅项目成员:Container Registry 仅对具有报告者角色或更高角色的项目成员可见。这类似于将 Container Registry 可见性设置为 具有访问权限的任何人 的私有项目的行为。
-
- 选择 保存修改。
Container Registry 可见性权限
查看 Container Registry 和拉取镜像的能力由 Container Registry 的可见性权限控制。您可以通过 UI 上的可见性设置 或 API 更改。其它权限如更新 Container Registry、推送或删除镜像等不受此设置影响。但是,禁用 Container Registry 会禁用所有 Container Registry 操作。
匿名 (互联网上的任何人) | Guest | 报告者、开发者、维护者和所有者 | ||
---|---|---|---|---|
具有 Container Registry 可见性的公开项目 设置为 具有访问权限的任何人 (UI) 或 enabled (API)
| 查看容器镜像库 并拉取镜像 | Yes | Yes | Yes |
具有 Container Registry 可见性的公开项目 设置为 仅项目成员 (UI) 或 private (API)
| 查看容器镜像库 并拉取镜像 | No | No | Yes |
具有 Container Registry 可见性的内部项目 设置为 具有访问权限的任何人 (UI) 或 enabled (API)
| 查看容器镜像库 并拉取镜像 | No | Yes | Yes |
具有 Container Registry 可见性的内部项目 设置为 仅项目成员 (UI) 或 private (API)
| 查看容器镜像库 并拉取镜像 | No | No | Yes |
具有 Container Registry 可见性的私有项目 设置为 具有访问权限的任何人 (UI) 或 enabled (API)
| 查看容器镜像库 并拉取镜像 | No | No | Yes |
具有 Container Registry 可见性的私有项目 设置为 仅项目成员 (UI) 或 private (API)
| 查看容器镜像库 并拉取镜像 | No | No | Yes |
容器镜像库设置为 disabled 的任何项目
| Container Registry 上的所有操作 | No | No | No |
极狐GitLab Container Registry 故障排查
Docker 连接错误
当群组、项目或分支名称中存在特殊字符时,可能会发生 Docker 连接错误。特殊字符可以包括:
- 前导下划线
- 尾随连字符/破折号
要解决此问题,您可以更改群组路径、更改项目路径或更改分支名称。
如果您使用早于 17.12 的 Docker engine 版本,您还可能会收到 404 Not Found
或 Unknown Manifest
消息。更高版本的 Docker engine 使用 v2 API。
GitLab Container Registry 中的镜像也必须使用 Docker v2 API。 有关如何更新镜像的信息,请参阅 Docker 帮助。
作为 GitLab 服务器管理员进行故障排查
大多数情况下,对 GitLab Container Registry 进行故障排查,需要您以管理员角色登录到 GitLab 服务器。
阅读如何对 Container Registry 进行故障排查。
无法更改路径或传输项目
如果您尝试更改项目的路径或将项目转移到新的命名空间,您可能会收到以下错误之一:
- “Project cannot be transferred, because tags are present in its container registry.”
- “Namespace cannot be moved because at least one project has tags in container registry.”
当项目在 Container Registry 中有镜像时会出现此问题。 您必须先删除或移动这些镜像,然后才能更改路径或传输项目。
以下过程使用这些示例项目名称:
- 对于当前项目:
gitlab.example.com/org/build/sample_project/cr:v2.9.1
- 对于新项目:
gitlab.example.com/new_org/build/new_sample_project/cr:v2.9.1
使用您自己的 URL 完成以下步骤:
-
在您的计算机上下载 Docker 镜像:
docker login gitlab.example.com docker pull gitlab.example.com/org/build/sample_project/cr:v2.9.1
-
重命名镜像以匹配新项目名称:
docker tag gitlab.example.com/org/build/sample_project/cr:v2.9.1 gitlab.example.com/new_org/build/new_sample_project/cr:v2.9.1
- 使用 UI 或 API 删除两个项目中的镜像。镜像排队和删除时可能会有延迟。
- 通过转到 设置 > 通用 并展开 高级 来更改路径或传输项目。
-
恢复镜像:
docker push gitlab.example.com/new_org/build/new_sample_project/cr:v2.9.1