51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

解决访问难题:使用Nexus 3搭建自己的Docker镜像代理加速服务

近期,传言许多公开的Docker镜像加速地址由于神秘因素影响纷纷下线,停止对外服务。在此之前官方Docker镜像源在国内也受到屏蔽,使得从国内环境拉取Docker镜像变得异常困难。现在,建立自己的Docker镜像代理显得尤为重要。本文将详细介绍如何使用Nexus 3搭建Docker镜像代理。文章内容较多专业知识,主要面向运维或开发人员,对新手小白用户可能不太友好。 ![47dfe7ab8ab8639b.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/06a6f8741e5b4a1896aea6afe466117f.png.jpg) ### 关于Nexus 3 Nexus 3 是一个强大的包管理和仓库工具,由 Sonatype 开发。它支持多种包格式,包括 Maven, Docker, npm, NuGet 等,适用于软件开发中的依赖管理和仓库托管。以下是一些关于 Nexus 3 的主要特点: * **多种格式支持**:Nexus 3 可以管理多种格式的二进制文件,包括 Java 的 jar 和 war 文件,JavaScript 的 npm 包,Python 的 PyPi 包等。 * **代理和托管仓库**:Nexus 3 允许用户创建代理仓库,可以缓存远程仓库中的组件,也可以创建托管仓库用于存储内部生成的组件。 * **安全性和权限管理**:提供细粒度的权限控制,支持与外部用户管理系统(如 LDAP)的集成,确保仓库的安全访问。 * **高可用性和支持大规模部署**:Nexus 3 支持高可用性部署配置,能够处理大量的请求和存储大量的组件,适合大规模企业环境。 * **仓库健康检查和优化**:提供仓库健康检查工具和数据优化工具,帮助维护仓库的稳定性和效率。 * **界面和集成**:提供了一个用户友好的界面,方便用户管理仓库和组件。同时,Nexus 3 可以与持续集成/持续部署 (CI/CD) 工具如 Jenkins、Bamboo 等集成,优化开发流程。 Nexus 3 是开发和 DevOps 团队在构建和维护软件项目中不可或缺的工具之一,特别是在处理多种依赖和需要确保依赖安全性的场景下。 ### 前提准备 * 一台国外VPS,内存最好在4GB以上 * 服务器已经安装了Docker服务 * 已经安装Nginx * 一个域名,并申请SSL证书 之所以选择使用国外VPS是因为官方Docker镜像源在国内受到屏蔽,导致国内服务器无法正常访问这些镜像。因此,需要借助国外VPS来进行代理中转,以确保可以顺利拉取所需的Docker镜像。 ### 使用场景 接下来,xiaoz通过我个人使用场景来详细说明这一过程。 * 使用Nexus 3搭建Docker镜像代理 * 配置Nexus 3 Docker镜像代理 * 镜像代理允许匿名PULL操作,但不允许PUSH操作 * 为了安全性考虑,避免过多用户使用,导致资源耗尽,我仅对自己的镜像`helloz`(我的Docker官方用户名)进行代理和缓存,其余镜像一律不允许拉取 ### 使用Docker Compose安装Nexus 3 新建一个`docker-compose.yaml`文件,内容如下: ``` version: "3.8" services:  nexus:    image: sonatype/nexus3    container_name: nexus    ports:      - "8081:8081"    volumes:      - ./data:/nexus-data    restart: always ``` * `./data`是Nexus 3持久化存储数据目录,建议改成主机的绝对路径,容器内部路径`/nexus-data`不要修改。 然后使用命令`docker-compose up -d`启动Nexus 3容器,首次启动需要进行初始化操作,过长稍微较长,可能需要等待几分钟才能完全启动。 ### 配置Nexus 3 启动完毕后,输入`http://IP:8081`访问Nexus 3,然后点右上角进行登录,用户名为`admin`,密码需要通过查看挂载目录下的`admin.password`获得。 ![137cffcef57090ab.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/8bd2b1d79e6642edb535741ecb645fb0.png.jpg) 根据引导修改管理员密码。 ![856386691d1ac016.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/42686e1595de4963b1ce0c97afaf014f.png.jpg) 这里我选择启用匿名访问。 ![efa13775bc2df4ff.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/149a408db4954880bb4288941232fa57.png.jpg) ### 通过Nexus 3设置Docker镜像代理 打开"**设置 \>\> Security \>\> Roles \>\> Create Role**" ![5db475d4b2057a8e.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/34c17151614b44d08522a710316b5cee.png.jpg) 然后按照如下填写: * Role ID:填写`DockerPullAnonymous`(也可以自己修改ID) * Role Name:DockerPullAnonymous(可自行修改) * Applied Privileges * nx-repository-view-docker-\*-browse * nx-repository-view-docker-\*-read * nx-repository-view-docker-docker-browse * nx-repository-view-docker-docker-read * Applied Roles:nx-anonymous 如下截图: ![3799b66af3402962.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/34f4956a14724a088aa7d2e188a8c6f7.png.jpg) 继续打开"**设置 \>\> Security \>\> Users** ",找到`Anonymous User`这个用户进行编辑,并添加`DockerPullAnonymous`这个权限。 ![f86732998a8d735d.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/df3d3368288244898dad0fd79a9fa445.png.jpg) 继续打开"**设置 \>\> Security \>\> Realms** ",添加`Docker Bearer Token Realm`这个权限并保存。 ![e48aaed59c8323d8.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/425c3171bca54692a91f13105468ee91.png.jpg) > 上述操作步骤的目的是添加Docker匿名PULL权限,如果不配置,拉取镜像的时候会提示:`Error response from daemon: unauthorized: authentication required` 继续打开"**设置 \>\> Routing Rules**",添加一条新规则: * Name:Allow_helloz(名字可以自己取) * Mode:Allow * Matchers:`^/v2/helloz/.*`(这里我仅配置允许拉取`helloz`这个用户的镜像,多个用户可以写`^/v2/(helloz|user2|user3)/.*`) ![ce9d38c1679e60ae.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/06e0048f93dc40689d2713a8029cb75f.png.jpg) > 这个步骤的目的是防止匿名用户拉取所有的Docker镜像,所以我这里只配置允许拉取我自己`helloz`的镜像(`helloz`是Docker官方注册的用户名)。 打开"**设置 \>\> Repositories \>\> Create repository**"我们开始创建一个Docker镜像仓库。 ![77573247631b22e4.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/70e1e948bba74dba95dbc9369ba7c4c4.png.jpg) 然后选择`docker(proxy)` ![6931f5e839c29141.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/94aba3cc27534024ab3c243b3ae86ee3.png.jpg) 注意下方红框标注的地方(Remote storage填写`https://registry-1.docker.io`)。 ![6a109566d552904e.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/ac40a3ad2a5249948c69f8dd565e60fd.png.jpg) Routing Rule选择之前添加的`Allow_helloz`,其它保持默认即可。 ![911af2c01ced50b1.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/e97cea7450c74396a63cd3e19fea71ce.png.jpg) ### 设置Nginx反向代理 执行 `docker pull` 操作时,Docker 官方要求目标镜像地址必须是 HTTPS 链接。为了满足这一要求,我们可以通过配置 Nginx 作为反向代理来连接 Nexus 3,并通过域名设置镜像地址以支持 HTTPS 访问。具体的 Nginx 配置如下所示: ``` server {     listen 80;     server_name hub.xxx.com; # 填写你自己的域名     rewrite ^(.*) https://hub.xxx.com$1 permanent; } server {     listen 443 ssl http2;     server_name hub.xxx.com; # 填写你自己的域名     ssl_certificate /data/ssl/hub.xxx.com.crt; # 改成你自己的SSL证书     ssl_certificate_key /data/ssl/hub.xxx.com.key; # 改成你自己的SSL私钥     ssl_session_timeout 1d;     ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions     ssl_session_tickets off;     # intermediate configuration     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 off;     # HSTS (ngx_http_headers_module is required) (63072000 seconds)     add_header Strict-Transport-Security "max-age=63072000" always;     # OCSP stapling     ssl_stapling on;     ssl_stapling_verify on;     location / {           client_max_body_size  64m;           proxy_http_version 1.1;           proxy_pass http://IP:8081/repository/docker/;  # 改成你自己在Nexus 3上Docker的镜像地址           proxy_set_header Host $host;           proxy_set_header X-Forwarded-For $remote_addr;           proxy_set_header X-Forwarded-Proto $scheme;           proxy_connect_timeout 60s;             proxy_send_timeout 60s;             proxy_read_timeout 300s;             send_timeout 60s;             proxy_buffers 16 32k;             proxy_buffer_size 64k;             proxy_set_header Connection "";    } } ``` ### 测试 接下来在国内服务器使用命令`docker pull hub.xxx.com/helloz/onenav:0.9.33`拉取镜像测试,可以成功拉取,说明配置成功了。 ![10f5e0bc3a32948c.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/918570b3d5e4448da1b13faa33a5fc31.png.jpg) 继续使用命令`docker pull hub.xxx.com/baiyuetribe/zdir:latest`尝试拉取一个非`helloz`用户的镜像,提示没有权限,符合我们的预期情况。 ![180974dc82ff7443.png](https://img1.51tbox.com/static/2024-06-18/col/2fac3388340d936cccceb6eaf51f003a/ed48a778c86540a68846082f5f2d2448.png.jpg) ### 结语 在本文中,我们详细探讨了如何使用 Nexus 3 搭建 Docker 镜像代理。值得注意的是,每个人的使用场景都有所不同,但 Nexus 3 的灵活性允许用户根据自己的具体需求配置不同的规则,实现精细化的权限控制。这一功能不仅使 Nexus 3 成为管理 Docker 镜像的理想选择,同时也适用于 npm、maven 等其他类型的包管理。 > 最后,感谢 ChatGPT 指导我完成 Nexus 3 的权限设置和协助我排查其中遇到的错误! > > 如需付费搭建`Nexus 3`,请联系我微信:`xiaozme`
赞(5)
未经允许不得转载:工具盒子 » 解决访问难题:使用Nexus 3搭建自己的Docker镜像代理加速服务