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

2023-11-15

作者选择了阿帕奇软件基金会接受捐赠作为为捐款而写程序。

介绍

Docker 注册表是一个管理存储和交付 Docker 容器镜像的应用程序。注册表集中容器映像并减少开发人员的构建时间。 Docker 镜像通过虚拟化保证相同的运行时环境,但构建镜像可能需要大量时间投入。例如,开发人员可以从包含所有必要组件的注册表下载压缩映像,而不是单独安装依赖项和包来使用 Docker。此外,开发人员可以使用持续集成工具自动将图像推送到注册表,例如TravisCI,在生产和开发过程中无缝更新图像。

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

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

先决条件

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

  • 通过以下方式设置两台 Ubuntu 18.04 服务器Ubuntu 18.04 初始服务器设置指南,包括 sudo 非 root 用户和防火墙。一台服务器将托管您的私有 Docker 注册表,另一台服务器将是您的client server.
  • 按照以下步骤在两台服务器上安装 Docker 和 Docker-Compose如何在 Ubuntu 18.04 上安装 Docker-Compose教程。您只需完成本教程的第一步即可安装 Docker Compose。本教程解释了如何安装 Docker 作为其先决条件的一部分。
  • 按照以下步骤将 Nginx 安装在您的私有 Docker 注册表服务器上如何在 Ubuntu 18.04 上安装 Nginx.
  • Nginx 通过 Let’s Encrypt 在您的服务器上为私有 Docker 注册表进行保护,具体方法如下如何使用 Let’s Encrypt 保护 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 注册表的服务器上,您可以创建一个docker-registry目录,移入其中,然后创建一个data子文件夹包含以下命令:

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

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

  1. nanodocker-compose.yml

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

docker-compose.yml
version: '3'

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

The environment部分使用路径在 Docker 注册表容器中设置环境变量/data。 Docker注册表应用程序在启动时检查此环境变量,然后开始将其数据保存到/data folder.

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

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

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

  1. docker 撰写 up

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

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 注册表容器。

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

第 2 步 — 设置 Nginx 端口转发

You already have HTTPS set up on your Docker Registry server with Nginx, which means you can now set up port forwarding from Nginx to port 5000. Once you complete this step, you can access your registry directly at example.com.

As part of the How to Secure Nginx With Let’s Encrypt prerequisite, you have already set up the /etc/nginx/sites-available/example.com file containing your server configuration.

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

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

找到现有的location线。它看起来像这样:

/etc/nginx/sites-available/example.com
...
location / {
  ...
}
...

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

/etc/nginx/sites-available/example.com
...
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;
}
...

The $http_user_agent部分验证客户端的 Docker 版本是否在上面1.5,并确保UserAgent不是一个Go应用。由于您使用的是版本2.0注册表中,不支持旧客户端。欲了解更多信息,您可以找到nginx标头配置在Docker 注册表 Nginx 指南.

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

  1. sudo servicenginx 重启

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

  1. cd〜/ docker-registry
  2. docker 撰写 up

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

https://example.com/v2

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

{}

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

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"

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

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

第 3 步 — 设置身份验证

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

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

  1. sudo apt installapache2-utils

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

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

Next, you will create the first user as follows, replacing username with the username you want to use. The -B flag specifies bcrypt encryption, which is more secure than the default encryption. Enter the password when prompted:

  1. htpasswd -Bc registry.password username

Note:要添加更多用户,请重新运行上一个命令(不带 -c 选项)(c用于创建):

  1. htpasswd registry.password username

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

  1. cd〜/ docker-registry
  2. nanodocker-compose.yml

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

docker-compose.yml
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

For REGISTRY_AUTH,您已指定htpasswd,这是您正在使用的身份验证方案,并设置REGISTRY_AUTH_HTPASSWD_PATH到认证文件的路径。最后,REGISTRY_AUTH_HTPASSWD_REALM表示的名称htpasswd realm.

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

  1. docker 撰写 up

In a browser window, open https://example.com/v2.

After entering username and the corresponding password, you will see {} once again. You’ve confirmed the basic authentication setup: the registry only returned the result after you entered the correct username and password. You have now secured your registry, and can continue to using the registry.

第 4 步 — 将 Docker 注册表作为服务启动

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

  1. nanodocker-compose.yml

在下面添加以下行内容registry::

docker-compose.yml
...
  registry:
    restart: always
...

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

  1. docker 撰写 up -d

当您的注册表在后台运行时,您现在可以准备 Nginx 来上传文件。

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

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

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

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

/etc/nginx/nginx.conf
...
http {
        client_max_body_size 2000M;
        ...
}
...

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

  1. sudo servicenginx 重启

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

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

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

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

  1. docker run -t -iubuntu /bin/bash

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

  1. touch/成功

退出 Docker 容器:

  1. exit

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

提交更改:

  1. docker commit $(docker ps -lq)测试图像

此时,该图像仅存在于本地。现在您可以将其推送到您创建的新注册表中。登录到您的 Docker 注册表:

  1. docker login https://example.com

Enter the username and corresponding password from earlier. Next, you will tag the image with the private registry’s location in order to push to it:

  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 注册表中提取

返回到您的注册表服务器,以便您可以测试从您的注册表中提取映像client服务器。也可以从第三个服务器进行测试。

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

  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 注册表,并发布了 Docker 映像。正如简介中提到的,您还可以使用TravisCI或类似的 CI 工具来自动直接推送到私有注册表。通过在工作流程中利用 Docker 和注册表,您可以确保包含代码的映像将在任何机器上产生相同的行为,无论是在生产中还是在开发中。有关编写 Docker 文件的更多信息,您可以阅读此内容Docker教程解释过程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Ubuntu 18.04 上设置私有 Docker 注册表 的相关文章

随机推荐

  • 如何在 Debian 9 上安装 Webmin

    Webmin是一个用于管理 Linux 服务器的开源 Web 控制面板 使用 Webmin 您可以管理系统用户 组 磁盘配额以及配置最流行的服务 包括 Web ssh ftp 电子邮件和数据库服务器 本教程介绍如何在 Debian Linu
  • 如何在 Debian 11 上为专用连接设置 Squid 代理

    介绍 代理服务器是一种服务器应用程序 充当最终用户和互联网资源之间的网关 通过代理服务器 最终用户能够出于多种目的控制和监视其 Web 流量 包括隐私 安全和缓存 例如 您可以使用代理服务器从与您自己的 IP 地址不同的 IP 地址发出 W
  • 如何在 Ubuntu 16.04 上安装 MySQL

    介绍 MySQL是一个开源数据库管理系统 通常作为流行的一部分安装LAMP Linux Apache MySQL PHP Python Perl 堆栈 它使用关系数据库和 SQL 结构化查询语言 来管理其数据 简短版本的安装很简单 更新您的
  • Java IO 教程

    Java提供了几个类java io用于处理文本 流数据和文件系统的包 我最近提供了几个有关 Java 文件和 Java IO 的示例 这篇文章是所有 Java IO 文章的索引 Java IO 如何在 Java 中创建新文件在这篇文章中 您
  • Java Stream Collect() 方法示例

    Java Streamcollect 对流的元素执行可变归约操作 这是终端操作 什么是可变约简操作 可变归约操作处理流元素 然后将其累积到可变结果容器中 处理元素后 组合函数将合并所有结果容器以创建结果 Java Stream Collec
  • 快速初始化()

    在本 Swift 教程中 我们将讨论一个重要的概念 即 Swift init 或 Swift 初始化 初始化是当我们创建某种类型的实例时发生的事情 快速初始化 初始化是准备类 结构或枚举的实例以供使用的过程 此过程涉及为该实例上的每个存储属
  • 如何在 Debian Wheezy 上使用 Postfix 安装和配置 DKIM

    介绍 对于大多数邮件服务器管理员来说 被错误地标记为垃圾邮件发送者所带来的挫败感并不奇怪 通过排除服务器受损的可能性 错误标记通常是由以下原因之一引起的 该服务器是一个开放的邮件中继 发件人或服务器的 IP 地址已列入黑名单 服务器没有完全
  • Linux/Unix 中的 AWK 命令

    AWK 适用于模式搜索和处理 该脚本运行以搜索一个或多个文件以识别匹配模式以及所述模式是否执行特定任务 在本指南中 我们将了解 AWK Linux 命令并了解它的功能 AWK 可以执行哪些操作 逐行扫描文件 将每个输入行拆分为字段 将输入行
  • 如何在 Python 中将字符串转换为日期时间或时间对象

    介绍 蟒蛇datetime and time模块均包括strptime 将字符串转换为对象的类方法 在本文中 您将使用strptime 将字符串转换为datetime and struct time 对象 将字符串转换为datetime对象
  • 如何在 Ubuntu 18.04 上使用 Python 3 设置 Jupyter Notebook

    介绍 Jupyter笔记本是一个开源 Web 应用程序 可让您创建和共享交互式代码 可视化等 该工具可与多种编程语言一起使用 包括 Python Julia R Haskell 和 Ruby 它通常用于处理数据 统计建模和机器学习 本教程将
  • 了解 Vue.js 生命周期挂钩

    介绍 生命周期挂钩是了解您正在使用的库如何在幕后工作的窗口 生命周期钩子允许您知道组件何时被创建 添加到 DOM 更新或销毁 本文将向您介绍 Vue js 中的创建 安装 更新和销毁钩子 先决条件 要完成本教程 您需要 熟悉 Vue js
  • Java 单例类中的线程安全

    Singleton 是最广泛使用的创建型设计模式之一 用于限制应用程序创建的对象 如果是在多线程环境中使用 那么单例类的线程安全性就非常重要 在现实应用程序中 数据库连接或企业信息系统 EIS 等资源是有限的 应明智地使用以避免任何资源紧缩
  • Fail2Ban 如何保护 Linux 服务器上的服务

    介绍 SSH 是连接云服务器的事实上的方法 它耐用且可扩展 随着新的加密标准的开发 它们可用于生成新的 SSH 密钥 确保核心协议保持安全 然而 没有任何协议或软件堆栈是完全万无一失的 SSH 在互联网上如此广泛的部署意味着它代表了一种非常
  • 如何在运行 Ubuntu 的 VPS 上安装和使用 Composer

    Status 已弃用 本文介绍不再受支持的 Ubuntu 版本 如果您当前运行的服务器运行 Ubuntu 12 04 我们强烈建议您升级或迁移到受支持的 Ubuntu 版本 升级到Ubuntu 14 04 从 Ubuntu 14 04 升级
  • 如何在 Rocky Linux 9 上安装 Node.js

    介绍 Node js是用于服务器端编程的 JavaScript 运行时 它允许开发人员使用 JavaScript 创建可扩展的后端功能 这是许多人在基于浏览器的 Web 开发中已经熟悉的语言 在本指南中 您将了解在 Rocky Linux
  • Java 堆空间与堆栈 - Java 中的内存分配

    不久前我写了几篇关于Java 垃圾收集 and Java 是按值传递 之后我收到了很多电子邮件来解释Java堆空间 Java堆栈内存 Java中的内存分配它们之间有什么区别 您会在 Java Java EE 书籍和教程中看到很多对堆和堆栈内
  • Spring WebFlux - Spring 响应式编程

    Spring WebFlux是Spring 5中引入的新模块 Spring WebFlux是Spring框架中向反应式编程模型迈出的第一步 Spring 响应式编程 如果您是反应式编程模型的新手 那么我强烈建议您阅读以下文章来了解反应式编程
  • 如何在 Ubuntu 16.04 上设置 Apache 虚拟主机

    介绍 Apache Web 服务器是在互联网上提供 Web 内容的最流行的方式 它占互联网上所有活跃网站的一半以上 并且非常强大和灵活 Apache 将其功能和组件分解为可以独立定制和配置的单独单元 描述单个站点或域的基本单位称为virtu
  • Android 倒计时器示例

    在这个 android 倒数计时器示例中 我们将实现一个计时器对象来显示进度进度条 我们将在本教程中构建的应用程序是测验应用程序中的一个有用组件 其中以图形方式显示完成该级别的剩余时间 以增强用户体验 Android 倒计时器 Androi
  • 如何在 Ubuntu 18.04 上设置私有 Docker 注册表

    作者选择了阿帕奇软件基金会接受捐赠作为为捐款而写程序 介绍 Docker 注册表是一个管理存储和交付 Docker 容器镜像的应用程序 注册表集中容器映像并减少开发人员的构建时间 Docker 镜像通过虚拟化保证相同的运行时环境 但构建镜像