如何在 Ubuntu 18.04 上设置私有 Docker 注册表如何在 Ubuntu 18.04 上设置私有 Docker 注册表如何在 Ubuntu 18.04 上设置私有 Docker 注册表如何在 Ubuntu 18.04 上设置私有 Docker 注册表
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何在 Ubuntu 18.04 上设置私有 Docker 注册表

作者选择了 Write for DOnations 计划。

介绍

TravisCI,在生产和开发过程中无缝更新图像。

Docker 还有一个免费的公共注册表 Docker Hub,可以托管您的自定义 Docker 映像,但在某些情况下您不希望您的映像公开可用。映像通常包含运行应用程序所需的所有代码,因此在使用专有软件时最好使用私有注册表。

在本教程中,您将设置并保护您自己的私有 Docker Registry。您将使用 Docker Compose 来定义运行 Docker 应用程序的配置,并使用 Nginx 将服务器流量从 HTTPS 转发到正在运行的 Docker 容器。完成本教程后,您将能够将自定义 Docker 镜像推送到您的私有注册表,并从远程服务器安全地拉取该镜像。

先决条件

在开始本指南之前,您需要具备以下条件:

  • 按照 Ubuntu 18.04 初始服务器设置指南设置两台 Ubuntu 18.04 服务器,包括 sudo 非根用户和防火墙。一台服务器将托管您的私有 Docker Registry,另一台将作为您的客户端服务器。
  • 按照如何在 Ubuntu 18.04 上安装 Docker-Compose 教程在两台服务器上安装 Docker 和 Docker-Compose。您只需完成本教程的第一步即可安装 Docker Compose。本教程解释了如何安装 Docker 作为其先决条件的一部分。
  • 按照如何在 Ubuntu 18.04 上安装 Nginx,将 Nginx 安装在您的私有 Docker Registry 服务器上。
  • 按照如何使用 Let's Encrypt 保护 Nginx,在您的服务器上使用 Let's Encrypt 为私有 Docker Registry 保护 Nginx。确保在第 4 步中将所有流量从 HTTP 重定向到 HTTPS。
  • 解析为您用于私有 Docker 注册表的服务器的域名。您将把它设置为 Let's Encrypt 先决条件的一部分。

第 1 步 — 安装和配置 Docker 注册表

Docker 命令行工具对于启动和管理一个或两个 Docker 容器很有用,但是,对于完全部署,在 Docker 容器内运行的大多数应用程序都需要其他组件并行运行。例如,许多 Web 应用程序由一个 Web 服务器(如 Nginx)组成,它提供应用程序代码、一种解释性脚本语言(如 PHP)和一个数据库服务器(如 MySQL)。

使用 Docker Compose,您可以编写一个 .yml 文件来设置每个容器的配置以及容器之间需要相互通信的信息。然后,您可以使用 docker-compose 命令行工具向构成应用程序的所有组件发出命令。

Docker Registry 本身是一个具有多个组件的应用程序,因此您将使用 Docker Compose 来管理您的配置。要启动注册表实例,您将设置一个 docker-compose.yml 文件来定义注册表将存储其数据的位置。

在您创建的用于托管私有 Docker Registry 的服务器上,您可以创建一个 docker-registry 目录,移入该目录,然后使用以下命令创建一个 data 子文件夹:

  1. mkdir ~/docker-registry && cd $_
  2. mkdir data

使用文本编辑器创建 docker-compose.yml 配置文件:

  1. nano docker-compose.yml

将以下内容添加到文件中,该文件描述了 Docker Registry 的基本配置:

version: '3'

services:
  registry:
    image: registry:2
    ports:
    - "5000:5000"
    environment:
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      - ./data:/data

environment 部分在路径为 /data 的 Docker Registry 容器中设置环境变量。 Docker Registry 应用程序在启动时检查此环境变量,结果开始将其数据保存到 /data 文件夹中。

但是,由于您包含了 volumes: - ./data:/data 行,Docker 将开始将该容器中的 /data 目录映射到 /data 在您的注册表服务器上。最终结果是 Docker Registry 的数据全部存储在注册表服务器上的 ~/docker-registry/data 中。

ports 部分,配置为 5000:5000,告诉 Docker 将服务器上的端口 5000 映射到端口 5000在运行的容器中。这允许您向服务器上的端口 5000 发送请求,并将请求转发到注册表应用程序。

您现在可以启动 Docker Compose 来检查设置:

  1. docker-compose up

您将在输出中看到下载条,显示 Docker 从 Docker 自己的注册表下载 Docker Registry 映像。在一两分钟内,您将看到类似于以下内容的输出(版本可能会有所不同):

Output of docker-compose up
Starting docker-registry_registry_1 ... done Attaching to docker-registry_registry_1 registry_1 | time="2018-11-06T18:43:09Z" level=warning msg="No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable." go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="redis not configured" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="Starting upload purge in 20m0s" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="using inmemory blob descriptor cache" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="listening on [::]:5000" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2

您将在本教程后面处理 No HTTP secret provided 警告消息。输出显示容器正在启动。输出的最后一行显示它已成功开始侦听端口 5000。

默认情况下,Docker Compose 将继续等待您的输入,因此请按 CTRL+C 关闭您的 Docker Registry 容器。

您已经在端口 5000 上设置了一个完整的 Docker Registry。此时注册表不会启动,除非您手动启动它。此外,Docker Registry 没有任何内置的身份验证机制,因此它目前是不安全的并且完全向公众开放。在以下步骤中,您将解决这些安全问题。

第 2 步 — 设置 Nginx 端口转发

您已经使用 Nginx 在 Docker Registry 服务器上设置了 HTTPS,这意味着您现在可以设置从 Nginx 到端口 5000 的端口转发。完成此步骤后,您可以直接在 example.com 访问您的注册表。

作为如何使用 Let's Encrypt 保护 Nginx 先决条件的一部分,您已经设置了包含服务器配置的 /etc/nginx/sites-available/example.com 文件.

使用文本编辑器打开此文件:

  1. sudo nano /etc/nginx/sites-available/example.com

查找现有的 location 行。它看起来像这样:

...
location / {
  ...
}
...

您需要将流量转发到端口 5000,您的注册表将在该端口运行。您还希望将标头附加到对注册表的请求,它为每个请求和响应提供来自服务器的附加信息。删除location部分的内容,并在该部分添加以下内容:

...
location / {
    # Do not allow connections from docker 1.5 and earlier
    # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
    if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
      return 404;
    }

    proxy_pass                          http://localhost:5000;
    proxy_set_header  Host              $http_host;   # required for docker client's sake
    proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_read_timeout                  900;
}
...

$http_user_agent 部分验证客户端的 Docker 版本是否在 1.5 以上,并确保 UserAgent 不是 Go 应用程序。由于您使用的是注册表的 2.0 版本,因此不支持较旧的客户端。有关更多信息,您可以在 Docker 的 Registry Nginx 指南中找到 nginx 标头配置。

保存并退出文件。通过重新启动 Nginx 来应用更改:

  1. sudo service nginx restart

您可以通过运行注册表确认 Nginx 正在将流量转发到端口 5000:

  1. cd ~/docker-registry
  2. docker-compose up

在浏览器窗口中,打开以下 url:

https://example.com/v2

您将看到一个空的 JSON 对象,或者:

{}

在您的终端中,您会看到类似于以下内容的输出:

Output of docker-compose up
registry_1 | time="2018-11-07T17:57:42Z" level=info msg="response completed" go.version=go1.7.6 http.request.host=cornellappdev.com http.request.id=a8f5984e-15e3-4946-9c40-d71f8557652f http.request.method=GET http.request.remoteaddr=128.84.125.58 http.request.uri="/v2/" http.request.useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" http.response.contenttype="application/json; charset=utf-8" http.response.duration=2.125995ms http.response.status=200 http.response.written=2 instance.id=3093e5ab-5715-42bc-808e-73f310848860 version=v2.6.2 registry_1 | 172.18.0.1 - - [07/Nov/2018:17:57:42 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7"

您可以从最后一行看到向 /v2/ 发出了 GET 请求,这是您从浏览器向其发送请求的端点。容器从端口转发接收到您发出的请求,并返回了 {} 的响应。输出最后一行的代码 200 表示容器成功处理了请求。

现在您已经设置了端口转发,您可以继续提高注册表的安全性。

第 3 步 — 设置身份验证

通过 Nginx 正确代理请求,您现在可以使用 HTTP 身份验证来保护您的注册表,以管理谁可以访问您的 Docker 注册表。为此,您将使用 htpasswd 创建一个身份验证文件并将用户添加到其中。 HTTP 身份验证可以通过 HTTPS 连接快速设置和保护,这是注册表将使用的。

您可以通过运行以下命令来安装 htpasswd 包:

  1. sudo apt install apache2-utils

现在您将创建一个目录,您将在其中存储我们的身份验证凭据,然后切换到该目录。 $_ 扩展为上一个命令的最后一个参数,在本例中为 ~/docker-registry/auth:

  1. mkdir ~/docker-registry/auth && cd $_

接下来,您将按如下方式创建第一个用户,将 username 替换为您要使用的用户名。 -B标志指定bcrypt加密,比默认加密更安全。出现提示时输入密码:

  1. htpasswd -Bc registry.password username

注意:要添加更多用户,请在不使用 -c 选项的情况下重新运行之前的命令(c 用于创建):

  1. htpasswd registry.password username

接下来,您将编辑 docker-compose.yml 文件以告知 Docker 使用您创建的文件对用户进行身份验证。

  1. cd ~/docker-registry
  2. nano docker-compose.yml

您可以为您创建的 auth/ 目录添加环境变量和卷,方法是编辑 docker-compose.yml 文件以告诉 Docker 您希望如何对用户进行身份验证。将以下突出显示的内容添加到文件中:

version: '3'

services:
  registry:
    image: registry:2
    ports:
    - "5000:5000"
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      - ./auth:/auth
      - ./data:/data

对于 REGISTRY_AUTH,您已指定 htpasswd,这是您正在使用的身份验证方案,并将 REGISTRY_AUTH_HTPASSWD_PATH 设置为身份验证文件的路径。最后,REGISTRY_AUTH_HTPASSWD_REALM 表示 htpasswd 领域的名称。

您现在可以通过运行注册表并检查它是否提示用户输入用户名和密码来验证您的身份验证是否正常工作。

  1. docker-compose up

在浏览器窗口中,打开 https://example.com/v2。

输入 username 和相应的密码后,您将再次看到 {}。您已确认基本身份验证设置:注册表仅在您输入正确的用户名和密码后返回结果。您现在已经保护了注册表,可以继续使用注册表。

第 4 步 — 将 Docker Registry 作为服务启动

您希望确保您的注册表将在系统启动时启动。如果有任何不可预见的系统崩溃,您要确保在服务器重新启动时重新启动注册表。打开 docker-compose.yml:

  1. nano docker-compose.yml

在registry:下添加如下一行内容:

...
  registry:
    restart: always
...

您可以将注册表作为后台进程启动,这将允许您退出 ssh 会话并保留该进程:

  1. docker-compose up -d

随着您的注册表在后台运行,您现在可以为文件上传准备 Nginx。

第 5 步 — 增加 Nginx 的文件上传大小

在将图像推送到注册表之前,您需要确保您的注册表能够处理大文件上传。尽管 Docker 将大型图像上传拆分为单独的层,但它们有时会超过 1GB。默认情况下,Nginx 对文件上传有 1MB 的限制,因此您需要编辑 nginx 的配置文件并将最大文件上传大小设置为 2GB。

  1. sudo nano /etc/nginx/nginx.conf

找到 http 部分,并添加以下行:

...
http {
        client_max_body_size 2000M;
        ...
}
...

最后,重启 Nginx 以应用配置更改:

  1. sudo service nginx restart

您现在可以将大图像上传到 Docker Registry 而不会出现 Nginx 错误。

第 6 步 — 发布到您的私有 Docker 注册表

您现在已准备好将映像发布到您的私有 Docker Registry,但首先您必须创建一个映像。在本教程中,您将创建一个基于来自 Docker Hub 的 ubuntu 映像的简单映像。 Docker Hub 是一个公共托管的注册表,具有许多可用于快速 Dockerize 应用程序的预配置图像。使用 ubuntu 映像,您将测试对注册表的推送和拉取。

从您的客户端服务器创建一个小的空图像以推送到您的新注册表,-i 和 -t 标志使您可以通过交互式 shell 访问容器:

  1. docker run -t -i ubuntu /bin/bash

下载完成后,您将进入 Docker 提示符,请注意 root@ 之后的容器 ID 会有所不同。通过创建一个名为 SUCCESS 的文件来快速更改文件系统。在下一步中,您将能够使用此文件来确定发布过程是否成功:

  1. touch /SUCCESS

退出 Docker 容器:

  1. exit

以下命令基于已运行的映像以及您所做的任何更改创建一个名为 test-image 的新映像。在我们的例子中,添加的 /SUCCESS 文件包含在新图像中。

提交更改:

  1. docker commit $(docker ps -lq) test-image

此时,镜像只存在于本地。现在您可以将它推送到您创建的新注册表。登录到您的 Docker 注册表:

  1. docker login https://example.com

输入之前的 username 和相应的密码。接下来,您将使用私有注册表的位置标记图像以便推送到它:

  1. docker tag test-image example.com/test-image

将新标记的图像推送到注册表:

  1. docker push example.com/test-image

您的输出将类似于以下内容:

Output
The push refers to a repository [example.com/test-image] e3fbbfb44187: Pushed 5f70bf18a086: Pushed a3b5c80a4eba: Pushed 7f18b442972b: Pushed 3ce512daaf78: Pushed 7aae4540b42d: Pushed ...

您已验证您的注册表处理用户身份验证,并允许经过身份验证的用户将图像推送到注册表。接下来,您将确认您也能够从注册表中提取图像。

第 7 步 — 从您的私有 Docker 注册表中拉取

返回到您的注册表服务器,以便您可以测试从客户端服务器拉取映像。也可以从第三台服务器对此进行测试。

使用您之前设置的用户名和密码登录:

  1. docker login https://example.com

您现在已准备好拉取图像。使用您在上一步中标记的域名和图像名称:

  1. docker pull example.com/test-image

Docker 将下载图像并将您返回到提示符。如果您在注册表服务器上运行图像,您将看到您之前创建的 SUCCESS 文件在那里:

  1. docker run -it example.com/test-image /bin/bash

在 bash shell 中列出您的文件:

  1. ls

您将看到为此图像创建的 SUCCESS 文件:

SUCCESS  bin  boot  dev  etc  home  lib  lib64  media   mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

您已经完成了一个安全注册表的设置,用户可以向其推送和拉取自定义图像。

结论

在本教程中,您设置了自己的私有 Docker Registry,并发布了一个 Docker 镜像。如介绍中所述,您还可以使用 Docker 教程解释该过程。

©2015-2025 艾丽卡 support@alaica.com