【云原生 | 44】Docker搭建Registry私有仓库之管理访问权限

博主简介
        云计算领域优质创作者
        2022年CSDN新星计划python赛道第一名

        2022年CSDN原力计划优质作者
        阿里云ACE认证高级工程师
        阿里云开发者社区专家博主

交流社区:CSDN云计算交流社区欢迎您的加入!

目录

1. Docker Registry v2的认证模式

2.配置Nginx代理 

3.添加用户认证 

4.用Compose启动Registry 

 结束语


Docker搭建Registry私有仓库请看上一篇文章 《【云原生 | 43】快速搭建Docker Registry私有仓库》
通常在生产场景中,对私有仓库还需要进行访问代理,以及提供认证和用户管理。

1. Docker Registry v2的认证模式

Docker Registry v2的认证模式和v1有了较大的变化,降低了系统的复杂度、减少了服务之间的交互次数,其基本工作模式如图

【云原生 | 44】Docker搭建Registry私有仓库之管理访问权限_第1张图片

具体交互过程包括如下步骤:
1)Docker Daemon或者其他客户端尝试访问Registry服务器,比如pull、push或者访问manifiest文件;
2)在Registry服务器开启了认证服务模式时,就会直接返回401Unauthorized错误,并通知调用方如何获得授权;
3)调用方按照要求,向Authorization Service发送请求,并携带Authorization Service需要的信息,比如用户名、密码;
4)如果授权成功,则可以拿到合法的Bearer token,来标识该请求方可以获得的权限;
5)请求方将拿到Bearer token加到请求的Authorization header中,再次尝试步骤1中的请求;
6)Registry服务通过验证Bearer token以及JWT格式的授权数据,来决定用户是否有权限进行请求的操作。

当启用认证服务时,需要注意以下两个地方:

·对于Authentication Service,Docker官方目前并没有放出对应的实现方案,需要自行实现对应的服务接口;
·Registry服务和Authentication服务之间通过证书进行Bearer token的生成和认证,所以要保证两个服务之间证书的匹配。
除了使用第三方实现的认证服务(如docker_auth、SUSE Portus等)外,还可以通过Nginx代理方式来配置基于用户名密码的认证。

2.配置Nginx代理 

使用Nginx来代理Registry服务的原理十分简单,在上一节中,我们让 Registry服务监听在127.0.0.1:5000,这意味着只允许本机才能通过5000端口访问到,其他主机是无法访问到的。
为了让其他主机访问到,可以通过Nginx监听在对外地址的15000端口,当外部访问请求到达15000端口时,内部再将请求转发到本地的5000端口。

首先,安装Nginx:

$ sudo apt-get -y install nginx
在/etc/nginx/sites-available/目录下,创建新的站点配置文 件/etc/nginx/sites-available/docker-registry.conf,代理本地的15000端口转发到5000端口。

配置文件内容如下:

#本地的registry服务监听在15000端口
upstream docker-registry {
    server localhost:5000;
}

#代理服务器监听在15000端口
server {
listen 15000;
    server_name private-registry-server.com;
    add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
    # If you have SSL certification files, then can enable this section.
    ssl on;
    ssl_certificate /etc/ssl/certs/myrepo.crt;
    ssl_certificate_key /etc/ssl/private/myrepo.key;
    proxy_pass http://docker-registry;
    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 600;
    client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
    # required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
    chunked_transfer_encoding on;
    location /v2/ {
        #禁止旧版本Docker访问
        if (\$http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*\$" ) {
            return 404;
        }
        #配置转发访问请求到registry服务
        proxy_pass http://docker-registry;
    }
}
建立配置文件软连接,放到/etc/nginx/sites-enabled/下面,让Nginx启用它,最后重启Nginx服务:
$ sudo ln -s /etc/nginx/sites-available/docker-registry.conf /etc/nginx/sitesenabled/docker-registry.conf
$ service nginx restart
之后,可以通过上传镜像来测试服务是否正常。测试上传本地的ubuntu:latest镜像:
$ docker tag ubuntu:14.04 127.0.0.1:15000/ubuntu:latest
$ docker push 127.0.0.1:15000/ubuntu:latest

3.添加用户认证 

公共仓库Docker Hub是通过注册索引(index)服务来实现的。由于Index服务并没有完善的开源实现,在这里介绍基于Nginx代理的用户访问管理方案。
Nginx支持基于用户名和密码的访问管理。
首先,在配置文件的location/字段中添加两行:
...
location / {
    # let Nginx know about our auth file
    auth_basic "Please Input username/password";
    auth_basic_user_file docker-registry-htpasswd;
    proxy_pass http://docker-registry;
}
...

其中,auth_basic行说明启用认证服务,不通过的请求将无法转发。auth_basic_user_file行则指定了验证的用户名密码存储文件为本地(/etc/nginx/下)的docker-registry-htpasswd文件。

docker-registry-htpasswd文件中存储用户名密码的格式为每行放一个用户名、密码对。例如:
...
user1:password1
user2:password2
...
需要注意的是,密码字段存储的并不是明文,而是使用crypt函数加密过的字符串。
要生成加密后的字符串,可以使用htpasswd工具,首先安装apache2-utils:
$ sudo aptitude install apache2-utils -y
创建用户user1,并添加密码。
例如,如下的操作会创建/etc/nginx/docker-registry-htpasswd文件来
保存用户名和加密后的密码信息,并创建user1和对应的密码:
$ sudo htpasswd -c /etc/nginx/docker-registry-htpasswd user1
$ New password:
$ Re-type new password:
$ Adding password for user user1
添加更多用户,可以重复上面的命令(密码文件存在后,不需要再使用-c选项来新创建)。

最后,重新启动Nginx服务:

$ sudo service nginx restart
此时,通过浏览器访问本地的服务 http://127.0.0.1:15000/v2/ ,会弹出对话框,提示需要输入用户名和密码。

通过命令行访问,需要在地址前面带上用户名和密码才能正常返回:

$ curl USERNAME:[email protected]:15000/v2/
除了使用Nginx作为反向代理外,Registry自身也支持简单的基于用户名和密码的认证和基于token的认证,可以通过如下环境变量来指定:
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: basic

4.用Compose启动Registry 

一般情况下,用户使用Registry需要的配置包括存储路径、TLS证书和用户认证。这里提供一个基于Docker Compose的快速启动Registry的模板:
registry:
    restart: always
    image: registry:2.1
    ports:
        - 5000:5000
    environment:
        REGISTRY_HTTP_TLS_CERTIFICATE: /certs/myrepo.crt
        REGISTRY_HTTP_TLS_KEY: /certs/myrepo.key
        REGISTRY_AUTH: htpasswd
        REGISTRY_AUTH_HTPASSWD_PATH: /auth/docker-registry-htpasswd
        REGISTRY_AUTH_HTPASSWD_REALM: basic
    volumes:
        - /path/to/data:/var/lib/registry
        - /path/to/certs:/certs
        - /path/to/auth:/auth

 结束语

你可能感兴趣的:(云原生,docker,容器)