Nginx+Portus+Registry搭建Docker私有镜像仓库

一、Portus介绍

Portus是SUSE为Docker Registry(v2)提供的一款开源用户前端和授权管理软件。实现企业私有Docker Registry的用户和权限管理功能,并提供Web界面使得管理员能够更加简易的进行相关操作。可以简单的理解为

Nginx+Portus+Registry = Private “Docker Hub”

Portus特性
  • 安全Portus实现私有Docker Registry中所有镜像的权限管理,针对不同的镜像设置不同用户或组的Push和Pull权限。
  • 用户管理Portus提供Web界面管理方式,可非常容易的进行用户和组的添加、修改、授权和删除等操作。
  • 搜索Portus提供了私有仓库所有镜像的概览,但是也可以通过搜索功能更快找到需要的镜像。

Portus的功能还有很多,如LDAP支持、操作审计等等。

Portus权限管理的安全性和细粒度还算比较高,Repository层面设置不同用户和组的权限,User层面也设置了不同的角色权限,通过多方面的授权实现镜像的安全管理。

个人觉得如果企业内的开发测试环境需要一个私有的Registry的话,Portus不妨一试。

二、Registry v2验证过程

Docker

 

Portus主要职能就是上面的”有关部门”(Authorization Service)了,负责用户请求的验证和授权功能。

三、环境介绍

Docker

私有”Docker Hub“整个环境所需的5个容器均跑在同一台Docker宿主机上,并使用两个Alias实现Portus和Registry的不同访问。

  • Docker宿主机:docker04.onlyeric.com
  • 容器:
    portus_nginx_1: Nginx反向代理服务
    portus_registry_1: 私有Registry服务
    portus_web_1: Portus的Web服务
    portus_crono_1: Portus服务
    portus_db_1: Portus数据库服务
  • 别名
    onlyeric.reg: 用户pull/push操作的镜像服务器
    portus.onlyeric.com: 管理员访问的Portus界面
四、环境准备

Server: 内网KVM虚机

OS: CentOS 7.2

IP: 192.168.2.14

Docker Engine: 1.11.2

Docker Compose: 1.7.1

Docker Images:

  • library/registry:2.3.1
  • library/mariadb:10.0.23
  • library/rails:4.2.2
  • nginx:1.10.1

(rails是构建portus的基础镜像,其他三个顾名思义了)

Alias:

192.168.2.14 onlyeric.reg
192.168.2.14 portus.onlyeric.com
(由于内网没有配置DNS服务器,所以需要在客户端和服务端都添加以上记录到hosts文件)

Docker Engine配置:

“–insecure-registry onlyeric.reg”

Portus容器化部署脚本:

https://github.com/SUSE/Portus.git
(该脚本由SUSE官方提供,旨在方便Portus的开发和测试,也可以用来搭建容器化的Portus环境)

在以上准备工作搞定之后就可以开始进行Portus的部署了。需要的Image可以不用提前准备,因为SUSE提供的部署脚本已含有镜像的下载内容。但是考虑到国内访问Docker Hub经常抽风,个人建议先把镜像给下载或者从哪儿Load过来。

五、安装部署
Portus安装脚本修改
默认的Portus脚本里不含nginx容器和配置,Portus和Registry的访问需要加端口。以下配置的变更主要是为了实现Nginx到Potus和Registry端口转发,实现不带端口(80端口)的访问下载Portus脚本
# git clone git clone https://github.com/SUSE/Portus.git
修改Gemfile
# vi Gemfile
#source “https://rubygems.org”
source “http://rubygems.org”
(国外的服务器无需修改)
创建Nginx配置目录
# mkdir nginx/conf.d
创建nginx配置文件
# pwd
 /root/Portus/nginx/conf.dPortus反向代理配置文件
 # vi portus.conf
 server {
 listen 0.0.0.0:80;
 server_name portus.onlyeric.com;
location / {
proxy_set_header Host $host;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_set_header X-Forwarded-Host $http_host;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_redirect off;
 proxy_pass http://web:3000/;
 proxy_http_version 1.1;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection "upgrade";
 proxy_read_timeout 900s;
 }
access_log /var/log/nginx/portus.access.log main;
 error_log /var/log/nginx/portus.error.log error;
 }
registry反向代理配置文件
 # vi registry.conf
 upstream onlyeric.reg {
 server registry:5000;
 }
map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
 'registry/2.0' '';
 default registry/2.0;
 }
server {
 listen 80;
 server_name onlyeric.reg;
 client_max_body_size 0;
 chunked_transfer_encoding on;
location /v2/ {
 if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
 return 404;
 }
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
proxy_pass                          http://onlyeric.reg;
 proxy_set_header  Host              $http_host;
 proxy_set_header  X-Real-IP         $remote_addr;
 proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
 proxy_set_header  X-Forwarded-Proto $scheme;
 proxy_read_timeout                  900;
 }
 }

(配置文件中使用到的registry和web会在后续的compose文件中做link)

修改compose文件

# pwd
 /root/Portus/compose
# vi docker-compose.yml.template
 web:
 build: .
 command: puma -b tcp://0.0.0.0:3000 -w 3
 environment:
 - PORTUS_MACHINE_FQDN_VALUE=EXTERNAL_IP
 - PORTUS_DB_HOST=portus_db_1
 volumes:
 - .:/portus
 ports:
 - 3000:3000
 links:
 - db
 extra_hosts:
 - "onlyeric.reg:192.168.2.14"
 - "portus.onlyeric.com:192.168.2.14"
crono:
 image: portus_web
 entrypoint: bin/crono
 environment:
 - PORTUS_MACHINE_FQDN=EXTERNAL_IP
 - PORTUS_DB_HOST=portus_db_1
 volumes:
 - .:/portus
 links:
 - db
 extra_hosts:
 - "onlyeric.reg:192.168.2.14"
 - "portus.onlyeric.com:192.168.2.14"
db:
 image: library/mariadb:10.0.23
 environment:
 MYSQL_ROOT_PASSWORD: portus
 extra_hosts:
 - "onlyeric.reg:192.168.2.14"
 - "portus.onlyeric.com:192.168.2.14"
registry:
 image: library/registry:2.3.1
 volumes:
 - /registry:/registry_data
 - ./compose/registry/portus.crt:/etc/docker/registry/portus.crt:ro
 - ./compose/registry/config.yml:/etc/docker/registry/config.yml:ro
 ports:
 - 5000:5000
 - 5001:5001 # required to access debug service
 links:
 - web
 extra_hosts:
 - "onlyeric.reg:192.168.2.14"
 - "portus.onlyeric.com:192.168.2.14"
nginx:
 image: nginx:1.10.1
 links:
 - registry
 - web
 volumes:
 - ./nginx/conf.d:/etc/nginx/conf.d
 ports:
 - 80:80
 extra_hosts:
 - "onlyeric.reg:192.168.2.14"
 - "portus.onlyeric.com:192.168.2.14"
(添加nginx容器,并将alias的解析添加到所有容器中。将registry容器中images存放的目录给mount到Docker host的文件系统上)

修改registry配置文件

# pwd
 /root/Portus/compose/registry# vi config.yml.template
 version: 0.1
 storage:
 filesystem:
 rootdirectory: /registry_data
 delete:
 enabled: true
 http:
 addr: 0.0.0.0:5000
 debug:
 addr: 0.0.0.0:5001
 auth:
 token:
 realm: http://EXTERNAL_IP:3000/v2/token
 service: EXTERNAL_IP
 issuer: EXTERNAL_IP
 rootcertbundle: /etc/docker/registry/portus.crt
 notifications:
 endpoints:
 - name: portus
 url: http://EXTERNAL_IP:3000/v2/webhooks/events
 timeout: 500ms
 threshold: 5
 backoff: 1s
(将service后的5000端口去掉)
Portus环境部署

运行compose-setup.sh自动部署脚本,-e参数后接Registry的Alias

# pwd
 /root/Portus# ./compose-setup.sh -e onlyeric.reg
 ###########
 # WARNING #
 ###########This deployment method is intended for testing/development purposes.
 To deploy Portus on production please take a look at: http://port.us.org/documentation.htmlThe setup will destroy the containers used by Portus, removing also their volumes.
 Are you sure to delete all the data? (Y/N) [Y] Y
.
 .
 .###################
 #     SUCCESS     #
 ###################
Make sure port 3000 and 5000 are open on host onlyeric.reg
Open http://onlyeric.reg:3000 with your browser and perform the following steps:
1. Create an admin account
 2. You will be redirected to a page where you have to register the registry. In this form:
 - Choose a custom name for the registry.
 - Enter onlyeric.reg:5000 as the hostname.
 - Do *not* check the "Use SSL" checkbox, since this setup is not using SSL.
Perform the following actions on the docker hosts that need to interact with your registry:
- Ensure the docker daemon is started with the '--insecure-registry onlyeric.reg:5000'
 - Perform the docker login.
To authenticate against your registry using the docker cli do:
$ docker login -u <portus username> -p <password> -e <email> onlyeric.reg:5000
To push an image to the private registry:
$ docker pull busybox
 $ docker tag busybox onlyeric.reg:5000/<username>busybox
 $ docker push onlyeric.reg:5000/<username>busybox
确认脚本运行的WARNING很友善的提示了该部署方式主要是用于开发测试环境,个人猜测原因可能是没有激活SSL安全配置。

部署的过程主要是使用docker compose来基于编辑好的compose文件启动容器化环境,涵盖portus_web:latest镜像的build以及5个容器的启动。

如果是在国内的网络环境部署的话整个过程非常长,因为portus_web镜像构建的时候需要更新很多软件包。且之前没将需要的images准备好的话,该过程可能会更长。国外服务器的话大概30分钟之内可以搞定。

Docker的魅力就在此了。任何应用不需要过多的安装和配置,拿着镜像启动成容器直接用就行。(部署具体过程日志由于篇幅原因省略)

部署成功后会提示SUCCESS并提供了很多链接和操作说明。这里需要注意的是由于我们使用了Nginx做了Portus和Registry的反向代理,所以在访问应用时后面的端口可以省略。

按照之前的规划: 

Portus Web的link为 http://portus.onlyeric.com

Registry为 onlyeric.reg

Portus配置

登录Portushttp://portus.onlyeric.com

创建admin帐号

Docker

(帐号密码任意设置)

配置Registry

在首次登录Portus的时候会自动弹出配置Registry的窗口

Docker

(Name任意,Hostname为onlyeric.reg)

Docker
(配置成功后会跳转到如上界面)

基本验证
登录测试
# docker login -u onlyeric -p zaq12wsx! onlyeric.reg
 Login Succeeded
 (登录成功)
Push测试
# docker tag busybox:latest onlyeric.reg/onlyeric/busybox:latest
 (Tag测试所需镜像,REGISTRY_NAME/USERNAME/IMAGE_NAME/IMAGE_TAG)# docker push onlyeric.reg/onlyeric/busybox:latest
 The push refers to a repository [onlyeric.reg/onlyeric/busybox]
 5f70bf18a086: Pushed
 8ac8bfaff55a: Pushed
 latest: digest: sha256:507bc9f5e7844d90c630f141a93b073473e24bd0b27daef574ffa93f97d01181 size: 733
 (镜像上传成功)
稍等片刻之后Portus的Web界面也可以看到上传成功的镜像

Docker

Pull测试

# docker rmi onlyeric.reg/onlyeric/busybox:latest
Untagged: onlyeric.reg/onlyeric/busybox:latest
(删除原有镜像)# docker pull onlyeric.reg/onlyeric/busybox:latest
latest: Pulling from onlyeric/busybox
Digest: sha256:507bc9f5e7844d90c630f141a93b073473e24bd0b27daef574ffa93f97d01181
Status: Downloaded newer image for onlyeric.reg/onlyeric/busybox:latest
(镜像下载成功)
基本权限管理
创建用户

Admin–>Users–>Create new user

Docker

创建用户组

Teams–>Create new team–>”users”

Docker

添加用户到组

“users”–>Add members–>Role(Viewer)–>”test”

Docker

修改Namespace所属组

Namespaces–>”onlyeric”–>Edit namespace–>Team–>”users”

Docker

异机测试

测试前提

  • 添加hosts文件记录”192.168.2.14 onlyeric.reg”
  • 将参数”–insecure-registry onlyeric.reg”配置到异机的Docker并重启服务
# docker login -u test -p zaq12wsx! onlyeric.reg
Login Succeeded
(登陆成功)# docker pull onlyeric.reg/onlyeric/busybox:latest
latest: Pulling from onlyeric/busybox
8ddc19f16526: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:507bc9f5e7844d90c630f141a93b073473e24bd0b27daef574ffa93f97d01181
Status: Downloaded newer image for onlyeric.reg/onlyeric/busybox:latest# docker images|grep busybox
onlyeric.reg/onlyeric/busybox   latest              332de81782ef        3 weeks ago         1.093 MB
(下载镜像成功)

至此整个Nginx+Portus+Registry的部署过程及基本配置已经完成。由于此次配置的环境没有SSL相关安全的配置,建议有兴趣的朋友可开发测试环境尝试此环境。

分享到:更多 ()