干货|Nginx+Portus+Registry搭建私有镜像仓库

Portus介绍

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

Portus特性

安全
Portus实现私有Docker Registry中所有镜像的权限管理,针对不同的镜像设置不同用户或组的Push和Pull权限。

用户管理
Portus提供Web界面管理方式,可非常容易的进行用户和组的添加、修改、授权和删除等操作。

搜索
Portus提供了私有仓库内容的概览,但是也可以通过搜索功能更快找到需要的镜像。

Portus的功能还有很多,比如LDAP支持,操作审计等等。Portus权限管理的安全性和细粒度还算比较高,Repository层面设置不同用户和组的权限,用户层面又设置了不同的角色,通过多方面的授权实现镜像的安全性管理。个人觉得如果企业内部的开发测试环境需要一个私有的Registry的话,可以考虑采用Portus。

Registry v2验证过程

Docker Client通过Docker Daemon拉取镜像白话版:
\1.我要搬货
\2.没授权,去相关部门开单子(拿Token)
\3.我要搬货,这是我的申请单(提交用户名和密码申请Token)
\4.核实信息,单子盖章(拿到Token)
\5.我要搬货,这是授权单
\6.通过,搬走

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

环境介绍


私有”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数据库服务

  • Alias
    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的部署了。需要的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

1
2
3
4
# vi Gemfile
#source "https://rubygems.org"
source "http://rubygems.org"
(国外的服务器无需修改)

创建nginx配置目录
# mkdir nginx/conf.d

创建nginx配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# pwd
/root/Portus/nginx/conf.d

Portus反向代理配置文件
# 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;   # 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;
  }
}

(配置文件中使用到的registry和web是在容器层面做过link的)

修改compose文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 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配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 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端口去掉)

环境部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 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.html

The 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配置

登录Portus
http://portus.onlyeric.com

创建admin帐号

(帐号密码任意设置)

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

(Name任意,Hostname为onlyeric.reg)

(配置成功后会直接跳到如上界面)

基本验证

登陆测试

1
2
3
# docker login -u onlyeric -p zaq12wsx! onlyeric.reg
Login Succeeded  
(登录成功)

Push测试

1
2
3
4
5
6
7
8
9
# 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界面也可以看到上传成功的镜像

Pull测试

1
2
3
4
5
6
7
8
9
# 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

创建用户组
Teams–>Create new team–>users

添加用户到组
users–>Add members–>Role(Viewer)–>test

修改Namespace所属组
Namespaces–>onlyeric–>Edit namespace–>Team–>users

异机测试

测试前提

  • 添加hosts文件记录”192.168.2.14 onlyeric.reg”
  • 将参数配置”--insecure-registry onlyeric.reg”到异机的Docker并重启服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 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相关安全的配置,建议仅在开发测试环境使用该方案。

文末特别感谢Wilson@擎天柱和Iason@CMDT的无损交流和倾情指导。

PS:Portus本身是支持生产环境的安全部署的,关注”小张烤茄”并回复”portus”,会有惊喜呈上。(各位看官请原谅此等无耻求关注行为…)

猜你喜欢

转载自blog.csdn.net/fighterandknight/article/details/72522953