专栏首页张戈的专栏Nexus3最佳实践系列:搭建Docker私有仓库

Nexus3最佳实践系列:搭建Docker私有仓库

文章目录

容器仓库是容器化管理中非常重要的一环,相当于 SVN 在程序研发、运维发布中的地位。因此,一个稳定、可靠的容器仓库尤为重要。

目前我知道的的数据仓库有:

  • Docker 官方的 Registry 原生仓库
  • SuSE 团队推出的出的 Portus:https://github.com/SUSE/Portus
  • VMWare 中国团队推出的企业级仓库—Harbor
  • 大家熟知的 Maven 私服:Sonatype Nexus3

本文主要介绍下 Sonatype Nexus 3 这个功能强大的产品,它不仅能够用于创建 Maven 私服,还可以用来创建 yum、pypi、npm、nuget、rubygems 等各种私有仓库。而且,Nexus 从 3.0 版本也开始支持创建 Docker 镜像仓库了!

因此,在上述几个产品里面我毫不犹豫的选择了 Nexus3 作为部门的公共数据仓库,一举多得。

一、部署

这里依然使用最简单的 Docker 化部署,过程非常之简单!在一台有外网的机器上安装好 docker 之后,执行如下启动脚本即可:

#!/bin/bash
docker run -dti \
        --net=host \
        --name=nexus \
        --privileged=true \
        --restart=always \
        --ulimit nofile=655350 \
        --ulimit memlock=-1 \
        --memory=16G \
        --memory-swap=-1 \
        --cpuset-cpus='1-7' \
        -e INSTALL4J_ADD_VM_PARAMS="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=8g" \
        -v /etc/localtime:/etc/localtime \
        -v /data/nexus:/nexus-data \
        sonatype/nexus3:latest

大概 2 分钟左右可以完成启动,此时可以通过浏览器访问 http://IP 地址:8081 即可出现 nexus 的 web 界面:

二、配置

1、配置 Blob 存储

点击右上角的 Sign in,输入默认账号密码:admin/admin123 登录到管理员身份。

打开控制页面的按钮,默认进入了仓库配置界面,选择 Blob Stores 开始创建存储空间:

我这边创建了如下 Blob,以备后用:

2、创建 Docker 仓库

回到前面的 repository 界面,点击 repositories 打开页面后点击【create repository】打开仓库类型选择界面(真的非常丰富!):

可以看到 Docker 有三种类型,分别是 docker(group),docker(hosted),docker(proxy)。其含义解释如下:

  • hosted : 本地存储,即同 docker 官方仓库一样提供本地私服功能
  • proxy : 提供代理其他仓库的类型,如 docker 中央仓库
  • group : 组类型,实质作用是组合多个仓库为一个地址

下面开始创建 Docker 仓库:

首先,我们创建一个 docker 代理仓库,点击 docker(proxy),如图填写信息:

往下翻页,勾上 “Allow clients to use the V1 API to interact with this Repository”,允许 Docker V1 API 请求。

至于代理的对象,我可以选择官方的镜像地址:https://registry-1.docker.io,但是官方的比较慢,所以这里我们可以填写国内的 Docker 镜像加速器地址,比如阿里云或DaoCloud的容器加速:

我这里选择了 DaoCloud 的镜像加速,这里为了确保能够拉取 DockerHub 最新的镜像,我选择了 Use DockerHub 这个 Index。

接着,再创建一个本地仓库,这里比较简单,只需要填写本地仓库的名称,比如 docker-hosted,然后填写 HTTP 端口即可,比如 8083:

保存之后,最后创建一个聚合仓库(group),将代理仓库和本地仓库聚合到一起使用,这里我命名为 docker,然后端口选择 8082:

这里成员仓库的顺序可以稍微规划下,一般来说将本地的放前面,代理第三方的放后面,好处就是优先使用本地或小众的镜像仓库。我这边是用了多个第三方仓库,所有有多个:

至此,nexus 在 docker 这一块是部署已经完成了,但是这样并不能很好的使用。因为 group 仓库并不能推送镜像,因为你推送自己制作的镜像到仓库还得通过本地仓库的端口去推送,很不方便!

下面分享一下我这边原创的解决方法:通过 Nginx 来判断推镜像还是拉镜像,然后代理到不同端口,解决这个问题,还是非常巧妙的。

3、配置 Nginx

在部署 Nginx 部分,我们先需要生成自签名 SSL 证书,因为后面不想在 docker pull 的时候还要带一个端口!这里我们需要 2 个域名,一个用来展示 nexus 前台,另一个用做 docker 仓库,比如:

nexus 前台:repo.xxx.com

docker 仓库:idocker.io

生成自签名 SSL 证书的方法网上很多,这里推荐一个一键生成工具,大家可以尝试使用:https://github.com/Fishdrowned/ssl ,使用方法请参考作者说明。

Ps:如果你打算做外网仓库服务,那也可以去申请一个免费 SSL 证书,我这边是内部 oa 域名使用,所以只能用自签名证书了。

Nginx 的规则如下:

upstream nexus_web {
    server 192.168.1.100:8081;
}
 
upstream nexus_docker_get {
    server 192.168.1.100:8082;
}
 
upstream nexus_docker_put {
    server 192.168.1.100:8083;
}
server {
    listen 80;
    listen 443 ssl;
    server_name idocker.io;
    access_log /data/wwwlogs/idocker.io.log access_log_json;
    # 证书
    ssl_certificate /data/wwwroot/ssl/out/idocker.io/idocker.io.crt;
    ssl_certificate_key /data/wwwroot/ssl/out/idocker.io/idocker.io.key.pem;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    # 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/docker/docker/issues/1486)
    chunked_transfer_encoding on;
    # 设置默认使用推送代理
    set $upstream "nexus_docker_put";
    # 当请求是GET,也就是拉取镜像的时候,这里改为拉取代理,如此便解决了拉取和推送的端口统一
    if ( $request_method ~* 'GET') {
        set $upstream "nexus_docker_get";
    }
    index index.html index.htm index.php;
    location / {
            proxy_pass http://$upstream;
            proxy_set_header Host $host;
            proxy_connect_timeout 3600;
            proxy_send_timeout 3600;
            proxy_read_timeout 3600;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_buffering off;
            proxy_request_buffering off;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto http;
    }
}
server {
    listen 80;
    listen 443 ssl;
    server_name repo.xxx.com;
    index index.html index.htm index.php;
    ssl_certificate /data/wwwroot/ssl/out/repo.xxx.com/repo.xxx.com.crt;
    ssl_certificate_key /data/wwwroot/ssl/out/repo.xxx.com/repo.xxx.com.key.pem;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    access_log /data/wwwlogs/repo.xxx.com.log access_log_json;
    location /download {
        root /data/wwwroot/repo.xxx.com;
    }
    location / {
            proxy_pass http://nexus_web;
            proxy_set_header Host $host;
            client_max_body_size 512m;
            proxy_connect_timeout 3600;
            proxy_send_timeout 3600;
            proxy_read_timeout 3600;
            proxy_buffering off;
            proxy_request_buffering off;
    }
}

Nginx 部署完成之后,我们还需要将自签名的根证书(ca.crt)导入到客户端才可以正常使用,否则会报不信任错误。

在上文介绍的一键生成自签名工具中,会生成一个根证书,名称为 ca.crt,我们将这个文件上传到客户端服务器的 /etc/docker/certs.d/idocker.io 目录即可(注意目录需要创建,最后的文件夹名称和仓库域名保持一致:idocker.io)。

为了方便后面的人使用,我将上述部署证书的过程弄成一个在线脚本,实现快速部署:

#!/bin/bash
bakfile=/tmp/hosts_$RANDOM
# 定义仓库域名和nexus前台域名
docker_domain=idocker.io
repo_domain=repo.xxx.com
# 绑定仓库域名解析
cp /etc/hosts $bakfile || exit 1
echo "/etc/hosts is bakcup to $bakfile"
if grep -q "$idocker_domain" /etc/hosts;then
    sed -i 's/.*$docker_domain/192.168.1.100 $docker_domain/g' /etc/hosts
else
    echo "192.168.1.100 $docker_domain" >> /etc/hosts
fi
echo
# 探测到仓库是否畅通
if which telnet >/dev/null 2>&1;then
    echo start trying to connect to $docker_domain:443 ...
    if ! echo "e" | telnet -e "e" $docker_domain 443 >/dev/null;then
       echo "Can not connect to $docker_domain:443,Plz check!"
    else
       echo connect success.
    fi
fi
echo
# 开始部署证书
mkdir -p /etc/docker/certs.d/$docker_domain
curl -s -o /etc/docker/certs.d/$docker_domain/ca.crt http://$repo_domain/download/cert/ca.crt
 
echo Docker repository init success, you need login when you want upload docker images.
echo 'Plz Run "docker login --username=idocker $docker_domain"'

脚本保存为 docker_init.sh,上传到 nginx 服务器的 /data/wwwroot/repo.xxx.com/download/cert 目录即可。

最终,我们可以使用如下命令行一键部署 docker 证书:

curl -sSL http://repo.xxx.com/download/scripts/docker_init.sh | sh -s

是不是非常方便?

4、关于高可用

相信用心的同学已经注意到了,Nexus3 存在一个单点问题。在看完官方文档后,发现 Nexus3 的免费版本仅支持单点,只有收费版才支持集群模式:

在高可用方面,我前后做了 2 个尝试:

①、将数据保存到 ceph 分布式存储:能用,但是 push 的速度实在不敢恭维!layer 文件越小越慢。

②、折中方案:另外部署一个节点,每隔一段时间将主节点数据同步过去,然后备份节点每隔一段时间重启一次(不重启的话数据不会更新),并且数据再同步一份到 ceph 确保安全。在 Nginx 中,将备份节点加入到 backup,当主节点宕机的时候,备机可以顶上来继续使用。

当然, 觉得这样做还不够的同学也可以参考官方的备份文档进一步优化:https://help.sonatype.com/repomanager3/high-availability/designing-your-cluster-backup-restore-process

三、小结

docker 仓库的使用我就不再赘述了,nexus 我们使用的是 group 这个聚合仓库,本地没有的镜像会去外网搜索,如果存在则拉取并缓存到本地,下次再拉取则直接使用缓存数据。所以,在拉取外网的镜像时,第一次会比较慢,第二次就和本地基本一致了。

上文提到,Nexus 还有其他很多实用仓库,比如 yum、python、npm、maven 等等。我所在的部门也全部用到了,非常好用!感兴趣的同学可以自己去尝试配置,都非常直观简单!当然,后面有空我也会整理一下各个种类仓库的最佳实践,比如各种仓库一键初始化的经验,敬请期待!

0

分享

hitokoto()

(function() { var s = "_" + Math.random().toString(36).slice(2); document.write('<div id="' + s + '"></div>'); (window.slotbydup=window.slotbydup || []).push({ id: '5538464', container: s, size: '836,100', display: 'inlay-fix' });})();

  • 2018年10月05日
  • 2
  • 16
  • A+

所属分类:大数据

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Docker 入门实践

    本文从新手视角记录了一个实际的 Dokcer 应用场景从创建、上传直到部署的详细过程,并简单的介绍了腾讯云容器服务的使用方法。

    张戈
  • Docker新手入门实战教程

    摘 要 本文从新手视角记录了一个实际的Dokcer应用场景从创建、上传直到部署的详细过程,并简单的介绍了腾讯云容器服务的使用方法。通过Docker快速拉起一个...

    张戈
  • 禁止百度转码和百度快照缓存的META声明

    今天手机 site 中国博客联盟时,发现网被转码了,虽然这个网站没做移动站,但是我也不希望被百度转码,因为这相当于拦截了所有来自手机的流量。下面说一下禁止百度转...

    张戈
  • docker私有仓库搭建与使用实战

    hub.docker.com上可以保存镜像,但是网速相对较慢,在内部环境中搭建一个私有的公共仓库是个更好的方案,今天我们就来实战搭建私有docker仓库吧; 环...

    程序员欣宸
  • Docker系列学习文章 - 镜像仓库的介绍(七)

    | 导语 前面我们讲了镜像的制作,知道了镜像是怎么生成的。但是镜像制作好了后,要怎么管理?他们存在哪里。通过本篇文章的讲解,大家就清楚了。

    宝哥@devops运维
  • 四、docker 仓库(让我们的镜像有处可存)

    前面讲完了docker 镜像和容器,以及通过Dockerfile 定制属于我们自己的镜像,那那现在就是需要将我们自己定制的镜像存放到仓库中供他们使用。这一套流程...

    程序员爱酸奶
  • Docker入门-搭建docker私有仓库

    目前Docker官方维护了一个公共仓库Docker Hub,其中已经包括了数量超过15000个镜像。大部分需求都可以通过在Docker Hub中直接下载镜像来使...

    小码农薛尧
  • [视频教程] 使用docker的方式安装redis

    直接使用docker拉取redis的镜像,并且进行端口映射与文件目录共享,这样可以直接在宿主机的端口上就可以进行访问了。其实本质上也是在一个简化版的ubuntu...

    陶士涵
  • Docker 仓库使用

    登录需要输入用户名和密码,登录成功后,可以从 docker hub 上拉取自己账号下的全部镜像。

    李小白是一只喵
  • 超详细记录公司多用户Docker仓库创建安全认证和应用

    概述:超详细记录建立公司内部多用户Docker仓库,自定义CA证书,https安全认证。服务器作为远程Docker仓库,其他开发端(如server2,serve...

    王小雷

扫码关注云+社区

领取腾讯云代金券