Aldebaran

人生最棒的感觉,就是你做到别人说你做不到的事。

0%

使用nexus3.x配置docker镜像仓库及仓库代理

三田寺円

前言

我们一直使用 docker registry 作为docker的镜像仓库,但docker registry只能作为私有仓库,当需要Docker Hub 或 Google Cloud Containers 上的镜像时,我们只能自己手动pull,重新打tag,再push到docker registry上。

当需要拉取多个镜像时,这样相当麻烦,尤其是我们使用Kubespray来部署Kubernetes集群,仅仅准备镜像就需要花费很多时间。

我们希望有一个Docker仓库,能同时托管私有镜像,还能代理访问公共的镜像仓库。

正好我们在使用Nexus作为Maven的仓库,同时nexus3提供了Docker, yum, apt, npm, ruby gems, pypi 等诸多类型的仓库功能。

经过技术调研,Nexus3完全可以达到我们的预期。

注意事项

Nexus3 提供了的3种类型的Docker仓库,前两者都可以创建多个仓库,最后一个则可以将他们全部聚合到一个URL来访问。

  • docker (hosted): 自托管
  • docker (proxy): 代理
  • docker (group): 聚合

建议为你想要创建的每个新仓库创建一个新的blob store。这样,每个仓库的数据都将位于/nexus-data中的不同文件夹中(在Docker容器内)

需要注意的重要事项:Docker repo需要2个不同的端口。我们将使用5001端口从代理仓库获取镜像,5002端口用于拉动并推送到私人仓库。

配置docker仓库

1. 为了仓库数据的独立性和安全性,我们可以给每一个repository创建一个独立的Blob块存储。

  • Name:填写一个易于辨认的名字

  • Path:会自动生成并补全。默认在Nexus安装目录下面的sonatype-work/nexus3/blobs/下,也可以修改到其它目录或磁盘,甚至可以是NFS或者cephfs的目录。

    分别创建三个blobs: docker-hub-hosted, docker-hub-proxy, docker-hub-group

    01

    02

2. 创建一个hosted类型的docker仓库

Hosted类型仓库用作我们的私有仓库

03

  • 点击 Repository下面的 Repositories - Create repository - docker(hosted) :

  • Name: 输入一个简洁直观的名字

  • Online: 勾选。这个开关可以设置这个Docker repo是在线还是离线。

  • Repository Connectors

    下面包含HTTP和HTTPS两种类型的port。

    有什么用呢?说明讲得很清楚:

    连接器允许docker客户端直接连接到docker仓库,并实现一些请求操作,如docker pull, docker push, API查询等。

    因此,这里我们勾选http并且填写端口 15002, Nexus就会启动一个监听到15002端口的连接器。

  • Force basic authentication

    勾选。这样的话就不允许匿名访问了,执行docker pull或 docker push之前,都要先登录:docker login

  • Docker Registry API Support

    Docker registry默认使用的是API v2, 但是为了兼容性,我们可以勾选启用API v1。

  • Storage

    Blob store,我们下拉选择前面创建好的专用blob:docker-hub-hosted

  • Hosted

    开发环境,我们运行重复发布,因此Delpoyment policy 我们选择Allow redeploy。

3. 创建一个proxy类型的docker仓库

proxy类型仓库,可以帮助我们访问不能直接到达的网络,如另一个私有仓库,或者国外的公共仓库,如Google cloud registry。

04

05

对于代理Docker hub, 官方有简要的文档可以参考Proxy Repository for Docker

  • 点击 Repository下面的 Repositories - Create repository - docker(proxy) :

  • Name: 输入一个简洁直观的名字

  • Online: 勾选。这个开关可以设置这个Docker repo是在线还是离线。

  • Repository Connectors: 不设置。

  • Proxy

    Remote Storage: 当配置docker hub的proxy时,这里填写: https://registry-1.docker.io

    Docker Index: 当配置docker hub的Docker Index时,点选Use Docker Hub或者填写:https://index.docker.io/

  • Storage

    Blob store,我们下拉选择前面创建好的专用blob:docker-hub-proxy

4. 创建一个group类型的docker仓库

group类型的docker仓库,是一个聚合类型的仓库。它可以将前面我们创建的3个仓库聚合成一个URL对外提供服务,可以屏蔽后端的差异性,实现类似透明代理的功能。

06

07

  • 点击 Repository下面的 Repositories - Create repository - docker(group) :

  • Name: 输入一个简洁直观的名字,

  • Online: 勾选。这个开关可以设置这个Docker repo是在线还是离线。

  • Repository Connectors

    这里我们勾选http并且填写端口 15001, Nexus就会启动一个监听到15001端口的连接器。

  • Storage:选择专用的blob存储docker-hub-hosted

  • group : 将左边选择需要添加的仓库,添加到右边的members下;

设置SSL(可选)

默认情况下,Docker客户端是使用HTTPS与repo通信,但是这不是必须的。

Nexus3上SSL有两种方式Nginx反向代理和JAVA Keytool。

  • JAVA Keytool

    这个建议参考官网的文档: Configuring SSL

  • Nginx反向代理

    使用Nginx反向代理,需要配置前面定义好的 5001和5002, 假设我们分别将5001和5002反代成 15001和15002。

    参考配置如下:

      upstream register_5000
      {
          server 127.0.0.1:5001;
      }
    
      server {
          listen       15001 ssl;
          server_name your-repo;
    
          ssl_certificate /usr/local/nginx/conf/ssl-key/STAR.your-repo.crt;
          ssl_certificate_key /usr/local/nginx/conf/ssl-key/STAR.your-repo.key;
    
          ssl_session_timeout  5m;
          ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
          ssl_ciphers  HIGH:!aNULL:!MD5;
          ssl_prefer_server_ciphers   on;
          large_client_header_buffers 4 32k;
    
          client_max_body_size 1000m;
          client_body_buffer_size 512k;
          proxy_connect_timeout 600;
          proxy_read_timeout   600;
          proxy_send_timeout   600;
          proxy_buffer_size    128k;
          proxy_buffers       4 64k;
          proxy_busy_buffers_size 128k;
          proxy_temp_file_write_size 512k;
    
          location / {
              proxy_set_header Host $host;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_set_header X-Forwarded-Port $server_port;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_http_version 1.1;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_pass http://register_5000;
              proxy_read_timeout 900s;
          }
    
          #error_page   500 502 503 504  /50x.html;
          access_log  /data/httplogs/your-repo-access.log weblog;
          error_log  /data/httplogs/your-repo-error.log;
      }
    

配置客户端和项目以使用Nexus存储库

1. 配置/etc/docker/daemon.json,并重启docker。

  • http

    如果配置http, 那么daemon.json需要配置 5001和5002

      $ vim /etc/docker/daemon.json
      {
          "insecure-registries": [
              "your-repo:5001",
              "your-repo:5002"
          ],
          "disable-legacy-registry": true
      }
    

    如果不使用SSL证书和域名,那么可能会遇到的问题: failed with status: 401 Unauthorized

    在Nexus上点击 Security->Realms->Docker Bearer Token Realm。

    08

    参考链接: docker-login-401-unauthorized

  • https

    如果配置https, 那么daemon.json需要配置 15001和15002

      $ vim /etc/docker/daemon.json
      {
          "registry-mirrors": [
              "https://your-repo:15001",
              "https://your-repo:15002"
          ]
      }
    

2. 登陆docker

在服务器上登陆docker,这里需要登陆两次,以15001和15002为例

$ docker login -u docker-user -p XXXXX https://your-repo:15001

$ docker login -u docker-user -p XXXXX https://your-repo:15002

3. 使用docker

拉取镜像,15001反代的是 docker hub,因此我们通过15001拉取。

$ docker pull your-repo:15001/rabbitmq:3.7

修改docker tag

$ docker tag abd3fc84b335 your-repo:15002/rabbitmq:3.7

上传到私服

$ docker push your-repo:15002/rabbitmq:3.7

参考链接

https://segmentfault.com/a/1190000015629878

https://blog.sonatype.com/using-nexus-3-as-your-repository-part-3-docker-images

https://help.sonatype.com/repomanager3/private-registry-for-docker/proxy-repository-for-docker

https://blog.csdn.net/sinat_31908303/article/details/79799654