如何在 Rocky Linux 8 上设置私有 Docker 注册表
在此页
- 先决条件
- 第 1 步 - 配置防火墙
- 第 2 步 - 安装 Docker 和 Docker Compose
- 第 3 步 - 配置 Docker 注册表
- 创建用户目录
- 创建 Amazon S3 存储桶
- 创建 Docker 组合文件
- 设置身份验证
- 将Dhparam文件复制到容器中
如果您在某个组织工作并希望将您的 docker 镜像保留在内部以便快速部署,那么托管私有 Docker 存储库是完美的选择。拥有私有 docker registry 可以让您拥有自己的图像分发管道,并对图像存储和分发有更严格的控制。您可以将注册表与 CI/CD 系统集成,从而改善您的工作流程。
本教程将教您如何使用 Amazon S3 作为存储位置在基于 Rocky Linux 8 的服务器上设置和使用私有 Docker 注册表。
先决条件
- 两台装有 Rocky Linux 8 的 Linux 服务器。一台服务器将充当注册表主机,而另一台将用作客户端以发送请求并从主机接收图像。
- 指向主机服务器的注册域名。我们将在教程中使用
registry.example.com
。 - 在两台机器上都具有 sudo 权限的非根用户。
第 1 步 - 配置防火墙
第一步是配置防火墙。 Rocky Linux 使用 Firewalld 防火墙。检查防火墙状态。
$ sudo firewall-cmd --state running
防火墙适用于不同的区域,公共区域是我们将使用的默认区域。列出防火墙上所有活动的服务和端口。
$ sudo firewall-cmd --permanent --list-services
它应该显示以下输出。
cockpit dhcpv6-client ssh
允许 HTTP 和 HTTPS 端口。
$ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https
重新检查防火墙的状态。
$ sudo firewall-cmd --permanent --list-services
您应该会看到类似的输出。
cockpit dhcpv6-client http https ssh
重新加载防火墙以启用更改。
$ sudo firewall-cmd --reload
第 2 步 - 安装 Docker 和 Docker Compose
服务器和客户端计算机都需要执行此步骤。
安装官方 Docker 存储库。
$ sudo dnf install yum-utils $ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
安装泊坞窗。
$ sudo dnf install docker-ce docker-ce-cli containerd.io
启用并运行 Docker 守护进程。
$ sudo systemctl enable docker --now
将您的系统用户添加到 Docker 组以避免使用
sudo
运行 Docker 命令。$ sudo usermod -aG docker $(whoami)
注销后再次登录到您的服务器以启用更改。
下载并安装 Docker Compose 的最新稳定版本。
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
对下载的二进制文件应用可执行权限。
$ sudo chmod +x /usr/local/bin/docker-compose
安装 Docker-compose Bash Completion 脚本。
$ sudo curl \ -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose \ -o /etc/bash_completion.d/docker-compose
重新加载您的配置文件设置以使 bash-completion 工作。
$ source ~/.bashrc
第 3 步 - 配置 Docker 注册表
创建用户目录
为注册表配置创建一个目录。
$ mkdir ~/docker-registry
切换到
docker-registry
目录。$ cd ~/docker-registry
创建一个目录,用于存放HTTP认证密码、Nginx配置文件和SSL证书。
$ mkdir auth
创建另一个目录来存储 Nginx 日志。
$ mkdir logs
创建 Amazon S3 存储桶
您可以将注册表数据和图像存储在您的服务器上或使用云托管服务。对于我们的教程,我们将使用 Amazon S3 云服务。
下一步是使用一些重要的设置来设置配置文件。这些设置也可以在
docker-compose.yml
文件中定义,但有一个单独的文件会更好。使用以下设置创建存储桶。
- 应该禁用 ACL。
- 应该禁用对存储桶的公共访问。
- 应禁用存储桶版本控制。
- 使用 Amazon S3 托管密钥启用存储桶加密。 (SSE-S3)
- 应该禁用对象锁定。
使用以下策略创建 IAM 用户。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation", "s3:ListBucketMultipartUploads" ], "Resource": "arn:aws:s3:::S3_BUCKET_NAME" }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload" ], "Resource": "arn:aws:s3:::S3_BUCKET_NAME/*" } ] }
将
S3_BUCKET_NAME
替换为您的 S3 存储桶的名称。记下您的存储桶的密钥、密钥值和存储桶区域,以供稍后使用。
创建 Docker 组合文件
创建
docker-compose.yml
文件并打开它进行编辑。$ nano docker-compose.yml
将以下代码粘贴到其中。
version: '3.3' services: registry: image: registry:2 restart: always environment: - REGISTRY_STORAGE=s3 - REGISTRY_STORAGE_S3_REGION=us-west-2 - REGISTRY_STORAGE_S3_BUCKET=hf-docker-registry - REGISTRY_STORAGE_S3_ENCRYPT=true - REGISTRY_STORAGE_S3_CHUNKSIZE=5242880 - REGISTRY_STORAGE_S3_SECURE=true - REGISTRY_STORAGE_S3_ACCESSKEY=AKIA3FIG4NVFCJ6STMUA - REGISTRY_STORAGE_S3_SECRETKEY=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 - REGISTRY_STORAGE_S3_V4AUTH=true - REGISTRY_STORAGE_S3_ROOTDIRECTORY=/image-registry - REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR=inmemory - REGISTRY_HEALTH_STORAGEDRIVER_ENABLED=false nginx: image: "nginx:alpine" ports: - 443:443 links: - registry:registry volumes: - ./auth:/etc/nginx/conf.d - ./auth/nginx.conf:/etc/nginx/nginx.conf:ro - ./logs:/var/log/nginx - /etc/letsencrypt:/etc/letsencrypt
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
让我们来看看我们在 compose 文件中设置的内容。
<开始> <李> 第一步是从中心获取 Docker 注册表版本 2 的最新映像。我们没有使用 latest 标签,因为在大版本升级的情况下它可能会导致问题。将其设置为 2 允许您获取所有 2.x 更新,同时防止自动升级到下一个主要版本,这可能会引入重大更改。 <李> 注册表容器设置为在发生故障或意外关闭时始终重新启动。 <李> 我们为 Amazon S3 存储设置了各种环境变量。让我们快速浏览一下。
- REGISTRY_STORAGE 设置存储类型。我们选择了 s3,因为我们使用的是 Amazon S3。
- REGISTRY_STORAGE_S3_REGION 设置您的 S3 存储桶的区域。
- REGISTRY_STORAGE_S3_BUCKET 设置您的 S3 存储桶的名称。
- REGISTRY_STORAGE_S3_ENCRYPT - 如果您启用了存储桶加密,请将其设置为真。
- REGISTRY_STORAGE_S3_CHUNKSIZE 设置上传块的大小。它应该大于 5MB (5 * 1024 * 1024)。
- REGISTRY_STORAGE_S3_SECURE - 如果您要使用 HTTPS,请将其设置为 true。
- REGISTRY_STORAGE_S3_ACCESSKEY 和 REGISTRY_STORAGE_S3_SECRETKEY - 您在创建 IAM 用户后获取的用户凭据。
- REGISTRY_STORAGE_S3_V4AUTH - 如果您使用 AWS 身份验证的 v4,请将其设置为 true。如果您遇到与 S3 登录相关的错误,请将其设置为 false。
- REGISTRY_STORAGE_S3_ROOTDIRECTORY - 设置存储桶中的根目录,您的注册表数据将存储在该目录下。
- REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR - 设置缓存的位置。在我们的例子中,我们将它存储在内存中。您也可以将其设置为使用 Redis。
- REGISTRY_HEALTH_STORAGEDRIVER_ENABLED - 将其设置为 false 以禁用注册表存储健康检查服务。注册表有一个错误,如果您不将其设置为 false,可能会导致问题。
./auth:/etc/nginx/conf.d
映射确保所有 Nginxs 设置在容器中可用。 <李>./auth/nginx.conf:/etc/nginx/nginx.conf:ro
以只读模式将 Nginx 设置文件从系统映射到容器中。 <李>./logs:/var/log/nginx
允许通过映射到容器中的 Nginx 日志目录来访问系统上的 Nginxs 日志。 <李> Docker 注册表设置存储在容器中的/etc/docker/registry/config.yml
文件中,我们已将其映射到config.yml
文件在当前目录中,我们将在下一步中创建该文件。
设置身份验证
要设置 HTTP 身份验证,您需要安装 httpd-tools
包。
$ sudo dnf install httpd-tools
在 ~/docker-registry/auth
目录中创建密码文件。
$ htpasswd -Bc ~/docker-registry/auth/nginx.htpasswd user1
New password:
Re-type new password:
Adding password for user user1
-c
标志指示命令创建一个新文件,-B
标志是使用Docker支持的bcrypt算法。将 user1
替换为您选择的用户名。
如果要添加更多用户,请再次运行该命令,但不要使用 -c
标志。
$ htpasswd -B ~/docker-registry/auth/registry.password user2
现在,该文件将映射到注册表容器以进行身份验证。
第 4 步 - 安装 SSL
要使用 Lets Encrypt 安装 SSL 证书,我们需要下载 Certbot 工具,该工具可从 Epel 存储库获得。
安装 EPEL 存储库和 Certbot。
$ sudo dnf install epel-release
$ sudo dnf install certbot
生成 SSL 证书。
$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m -d registry.example.com
上面的命令会将证书下载到服务器上的 /etc/letsencrypt/live/registry.example.com
目录。
生成 Diffie-Hellman 组证书。
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
测试证书的更新。
$ sudo certbot renew --dry-run
如果试运行成功,则意味着您的证书将自动更新。
将 Dhparam 文件复制到容器中
将Diffie-Hellman组证书复制到~/docker-registry/auth
目录下,会映射到容器中。
$ sudo cp /etc/ssl/certs/dhparam.pem ~/docker-registry/auth
第 5 步 - 配置 Nginx
下一步涉及将 Nginx 服务器配置为 Docker 注册表服务器的前端代理。 Docker registry 带有一个在端口 5000 上运行的内置服务器。我们将把它放在 Nginx 后面。
创建并打开文件 ~/docker-registry/auth/nginx.conf
进行编辑。
$ sudo nano ~/docker-registry/auth/nginx.conf
将以下代码粘贴到其中。
events {
worker_connections 1024;
}
http {
upstream docker-registry {
server registry:5000;
}
## Set a variable to help us decide if we need to add the
## 'Docker-Distribution-Api-Version' header.
## The registry always sets this header.
## In the case of nginx performing auth, the header is unset
## since nginx is auth-ing before proxying.
map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
'' 'registry/2.0';
}
server {
listen 443 ssl http2;
server_name registry.example.com;
# SSL
ssl_certificate /etc/letsencrypt/live/registry.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/registry.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/registry.example.com/chain.pem;
access_log /var/log/nginx/registry.access.log;
error_log /var/log/nginx/registry.error.log;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
ssl_session_cache shared:SSL:10m;
ssl_dhparam /etc/nginx.d/conf.d/dhparam.pem;
resolver 8.8.8.8;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486)
chunked_transfer_encoding on;
location /v2/ {
# 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;
}
# To add basic authentication to v2 use auth_basic setting.
auth_basic "Registry realm";
auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;
## If $docker_distribution_api_version is empty, the header is not added.
## See the map directive above where this variable is defined.
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
proxy_pass http://docker-registry;
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;
}
}
}
完成后按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
配置 SELinux 以允许私有 Docker 注册表的网络连接。
$ sudo setsebool -P httpd_can_network_connect on
第 6 步 - 启动 Docker Registry
切换到 Docker 注册表目录。
$ cd ~/docker-registry
启动 docker 容器。
$ docker-compose up -d
检查容器的状态。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
88d6addc1687 nginx:alpine "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp docker-registry_nginx_1
2b112edc1c72 registry:2 "/entrypoint.sh /etc…" 5 minutes ago Up 5 minutes 5000/tcp docker-registry_registry_1
登录到 Docker 注册表。
$ docker login -u=testuser -p=testpassword https://registry.example.com
您还可以在浏览器中打开 URL https://registry.example.com/v2/
,它会询问用户名和密码。您应该会看到一个带有 {} 的空白页面。
您可以使用 curl
在终端上检查 URL。
$ curl -u testuser -X GET https://registry.nspeaks.xyz/v2/
Enter host password for user 'testuser':
{}
下载最新的 Ubuntu docker 镜像。
$ docker pull ubuntu:latest
为私有注册表标记此图像。
$ docker tag ubuntu:latest registry.example.com/ubunt4
将映像推送到注册表。
$ docker push registry.example.com/ubunt4
测试是否推送成功。
$ curl -u testuser -X GET https://registry.nspeaks.xyz/v2/_catalog
Enter host password for user 'testuser':
{"repositories":["ubunt4"]}
出现提示时输入您的 Nginx 身份验证密码,您将看到通过注册表可用的存储库列表。
查看当前可用的 Docker 镜像列表。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2 d3241e050fc9 5 days ago 24.2MB
nginx alpine 53722defe627 5 days ago 23.4MB
httpd 2 118b6abfbf55 5 days ago 144MB
ubuntu latest ff0fea8310f3 2 weeks ago 72.8MB
registry.nspeaks.xyz/ubunt4 latest ff0fea8310f3 2 weeks ago 72.8MB
第 7 步 - 从客户端机器访问和使用 Docker 注册表
登录到您的客户端服务器。在第 1 步中,我们在客户端机器上安装了 Docker。
从客户端计算机登录到私有 Docker 注册表。
$ docker login -u=testuser -p=testpassword https://registry.example.com
从注册表中拉取 Ubuntu 映像。
$ docker pull registry.example.com/ubunt4
列出客户端计算机上的所有图像。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.nspeaks.xyz/ubunt4 latest ff0fea8310f3 2 weeks ago 72.8MB
使用下载的图像创建并启动容器。
$ docker run -it registry.example.com/ubunt4 /bin/bash
您将登录到 Ubuntu 容器内的 Shell。
:
运行以下命令来检查 Linux 版本。
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
现在,您可以开始从客户端计算机使用 Docker 注册表。
结论
我们关于在使用 Amazon S3 作为存储的基于 Rocky Linux 8 的服务器上设置私有 Docker 注册表的教程到此结束。如果您有任何问题,请在下面的评论中发表。