Docker官方并没有提供docker registry的用户界面,对权限的控制粒度也比较粗。SUSE的Portus很好地解决了这个问题。除了界面以外,它还提供了更细粒度的权限控制、用户认证等功能。本文尝试从零开始用容器搭建一个portus环境。
准备工作
我们需要先安装virtualBox和vagrant。通过vagrant来驱动virtualBox搭建一个虚拟测试环境。首先在本地任意路径新建一个空文件夹比如test,运行以下命令:
1 | mkdir test |
里面应该有一句config.vm.box = "minimum/ubuntu-trusty64-docker",在它的下面添加如下几行代码,相当于给它分配一台IP是192.168.33.18的虚拟机。Registry配上portus会比较耗内存,所以我们给它2G内存,默认是512M。
1 | config.vm.network "private_network", ip: "192.168.33.18" |
这个vagrant镜像已经在ubuntu的基础上帮我们安装了docker,用起来很方便。然后在终端运行以下命令启动并连接虚拟机。
1 | vagrant up |
搭建环境
我们将会把docker registry和portus都安装在同一台虚拟机上。一方面是比较方便,另一方面也避免了时钟同步问题。为了启动一个带认证的docker registry,首先要生成自签名证书:
1 | cat ssl.conf |
证书生成好了,但是由于这是自签名证书,客户端还需要配置证书文件:
1 | sudo mkdir -p /etc/docker/certs.d/192.168.33.18:5000 |
接下来生成一个registry的配置文件,里面指定刚才的证书和token方式的认证。认证服务器设置到一会儿要启动的portus去:
1 | cat config.yml |
然后就可以启动registry容器了:
1 | docker run -d \ |
Docker registry配置完成后,就该准备portus了。Portus需要一个数据库来存储信息,官方推荐MariaDB,当然mysql也是没问题的。我们把数据库启动起来:
1 | docker run -d \ |
等数据库启动完成,我们连接上去:
1 | docker exec -it mariadb mysql -uroot -p123456 |
为portus创建用户和数据库:
1 | create database portus; |
万事俱备,让我们来启动portus:
1 | docker run -it -d \ |
启动完成后,在浏览器打开https://192.168.33.18/,应该会看到证书不被浏览器所信任的提示。无视之,选择继续的话,应该就能看到注册页面啦:
权限管理
Portus现在只能管理一个私有库。它有一个团队的概念,每一个团队可以有多个命名空间,每个命名空间就是多个镜像的集合。每个团队有三种角色:
- 查看者(Viewer):只能pull镜像
- 贡献者(Contributor):除了pull,还可以push镜像
- 所有者(Owner):除了推拉镜像,还可以对团队成员进行管理
由于角色是定义在团队里的,所以命名空间就不需要再考虑权限问题了,它只是镜像的集合而已。命名空间也有三种类型:
- 全局(Global):只有管理员可以push,其他人只能pull
- 团队(Team):团队成员可以做自己角色支持的操作
- 个人(Personal):只有所有者和管理员可以推拉
命名空间还可以设置为public,这样不需要login也能pull。
说完一些基本概念,让我们来尝试一下。首先,portus需要配置一个用户,来调用docker registry的API,与其进行同步。同步有两种方式:一是在docker registry的配置文件里写的notifications,这样每当有人push一个新镜像上去,docker registry将会通知portus修改数据库。可是时间长了,有可能数据库偶尔挂掉或是网络不稳定啥的导致两边数据不一致。Portus针对这种情况也提供了一个crono的job,设置定时运行即可,一会儿我们会试验。现在先让我们来创建这个用户:
1 | docker exec portus bundle exec rake portus:create_api_account |
接下来就可以在注册页面自行注册啦,注册完毕后会跳转到登记registry页面:
照上图填入registry,点击Create按钮创建一个docker registry。接着创建一个新用户。点击左边的Admin,再点击中间的Users,然后点击右边的Create new user,填写用户信息:
点击Add按钮就可以创建一个新用户了。接下来创建一个团队。点击左边的Teams,再点击右边的Create new team,填写团队信息:
点击Add按钮就可以创建一个新团队了。点击刚刚创建好的团队,再点击右边的Add namespace,填写命名空间信息:
点击Add按钮就可以创建一个新命名空间了。接下来把用户添加到这个团队中。点击右边的Add members,填写刚才增加的用户信息:
点击Add按钮就可以把用户加进来了。回到控制台,搞一个镜像,push一下:
1 | docker pull microbox/etcd:2.1.1 |
出错了:unauthorized: authentication required,我们必须用docker先登录:
1 | docker login -u gggg -e gggg@123.com 192.168.33.18:5000 |
填上自己刚才设置的密码,登录成功之后,再试着push一下:
1 | docker push 192.168.33.18:5000/microbox/etcd:2.1.1 |
Bingo!换一个命名空间试试看:
1 | docker tag h0tbird/portus:v2.0.2-1 192.168.33.18:5000/h0tbird/portus:v2.0.2-1 |
出错了:unauthorized: authentication required,可见我们的权限控制确实起作用了。
镜像同步
接下来我们试试定时同步任务。首先需要在容器里信任我们的自签名证书:
1 | docker exec portus mkdir /usr/local/share/ca-certificates |
然后启动定时同步任务,设置为每10秒钟同步一次:
1 | docker exec -it portus bash |
等十秒钟,就会看到**[catalog] Created the tag ‘2.1.1’的提示。如果先前没有信任自签名证书,同步的时候会报certificate verify failed的错误。现在回到portus的界面,点击左边的Dashboard**,就能看到刚才push的microbox/etcd镜像已经显示在右边了:
最后一步就是自动同步了,先把刚才的crono给Ctrl+C掉,Ctrl+D退出portus容器。由于docker registry需要调用portus的API,所以我们需要在registry容器里也信任这个证书:
1 | docker cp /certs/server-crt.pem registry:/usr/local/share/ca-certificates/ca.crt |
然后再push一个镜像:
1 | docker tag registry:2.3.0 192.168.33.18:5000/microbox/registry:2.3.0 |
到portus的dashboard刷新一下,搞定!在中间的Recent activities还能看到是谁push的这个镜像,对审计、追踪来说很有帮助。