在 ubuntu 搭建需要签名认证的私有 docker registry 仓库
2018-02-23 19:03
996 查看
前言
在前面的一篇博客《在 ubuntu 搭建 docker registry 私有仓库》介绍了一种简单的搭建 docker 私有仓库了的方法。但是当时使用的是修改“--insecure-registry”参数的办法,这种办法在局域网中使用,还勉强合适。但如果要搭建一个生产环境的私有仓库服务器,就存在很大的安全风险了。所以,这里介绍一种使用签名认证的实现方式,主要通过nginx 的反向代理,将不受信任的客户端请求都拒绝,以达到安全的目的。实验环境
服务端系统: ubuntu 16.04 docker 17.12.0-ce 客户端系统: ubuntu 14.04 docker 17.12.0-ce
如果想升级自己系统中的docker 版本,请参考这篇文章:《Ubuntu Docker 版本的更新与安装》。
或者参考:《Docker ubuntu 16.04 安装稳定版本,社区版版本》。
开始实验
因为我们使用的是 nginx 服务作为安全认证的服务器,所以我们还需要安装 apache2-utils ,这个是用来生成用户和用户密码。我们这里使用 docker-compse,用来定义和运行多个docker 容器。我们还需要使用curl 工具,这个主要用于测试实验结果。开始做实验前,请确认已经安装好docker-ce 的版本了。
下面开始做实验。
1 安装必要的工具
apt-get install -y docker-compose apache2-utils curl
2 创建一些文件目录
mkdir /docker-registry mkdir /docker-registry/data mkdir /docker-registry/nginx chown root:root /docker-registry cd /docker-registry
3 创建 docker-compose.yml 文件(用于定义docker container properties)
root@ubuntu:/docker-registry# cat docker-compose.yml nginx: image: "nginx:1.9" ports: - 443:443 links: - registry:registry volumes: - /docker-registry/nginx/:/etc/nginx/conf.d registry: image: registry:2 ports: - 127.0.0.1:5000:5000 environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data volumes: - /docker-registry/data:/data
说明:
docker-compose.yml 文件首先会创建一个 registry 容器,它的5000端口和宿主机的5000端口映射。它存储镜像的目录是 /data 目录,与宿主机的 /docker-registry/data 绑定。
然后,nginx 容器也会被创建,nginx 容器通过 -link 参数,与 registry 容器连接,这样nginx 容器就知道怎么和 registry 容器通信了(其实,registry 容器的 IP 会被绑定在 nginx 容器的 /etc/hosts 文件)。
4 启动容器
docker-compose up
说明: 这条命令 docker-compose 会通过刚刚写好的 docker-compose.yml 脚本,生成两个容器,正常会是以下的输出
如果要停止,只能使用 (Ctrl + C )了。
如果想在后台运行,可以使用
docker-compose up -d
创建 docker-registry.service 文件
因为 ubuntu 在14.10 之前的版本都只支持upstart 的方式,所以,如果你想使用 systemd 的管理方式,则需要使用 ubuntu 15.04 以上的版本了。因此,我这里使用了 ubuntu 16.04的系统版本,自带了systemd 服务。vi /etc/systemd/system/docker-registry.service : [Unit] Description=Starting docker registry [Service] Environment= MY_ENVIRONMENT_VAR = /docker-registry/docker-compose.yml WorkingDirectory=/docker-registry ExecStart=/usr/bin/docker-compose up Restart=always [Install] WantedBy=multi-user.target
说明:现在,我们就能使用 service docker-registry start/stop/restart 的命令来管理 nginx 和 registry 容器了,非常方便。
测试:
说明一切正常。
好吧,从这里开始,我们就可以使用 service docker-registry restart 来重启容器了。
5 设置 nginx 服务的配置文件
vi /docker-registry/nginx/registry.confupstream docker-registry { server registry:5000; } server { listen 443; server_name myregistrydomain.com; # SSL # ssl on; # ssl_certificate /etc/nginx/conf.d/domain.crt; # ssl_certificate_key /etc/nginx/conf.d/domain.key; # 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; location /v2/ { # Do not allow connections from docker 1.5 and earlier # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { return 404; } # To add basic authentication to v2 use auth_basic setting plus add_header # auth_basic "registry.localhost"; # auth_basic_user_file /etc/nginx/conf.d/registry.password; # add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always; 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 900; } }
测试
service docker-registry restart curl http://localhost:5000/v2/[/code] 结果会是这样:
{}root@ubuntu:/docker-registry#6 设置安全权限认证,创建用户
cd /docker-registry/nginx htpasswd -c registry.password mydocker New password: Re-type new password: Adding password for user mydocker
说明:利用 apache2-utils 的 htpasswd 工具,创建一个包含用户名和用户密码的文件
再次打开 registry.conf 文件vi /docker-registry/nginx/registry.conf
将下面几行的注释去掉auth_basic "registry.localhost"; auth_basic_user_file /etc/nginx/conf.d/registry.password; add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
再测试service docker-registry restart curl http://localhost:443/v2/ root@ubuntu:~/docker-registry/nginx# curl http://localhost:5043/v2/401 Authorization Required 401 Authorization Required nginx/1.9.15
用用户名和用户密码再测试一次curl http://mydocker:123456@localhost:443/v2/ {}root@ubuntu:~/docker-registry/nginx#
说明:到这里,其实我们就完成了一个局域网的认证功能了,但是还不能作为一个服务器使用。因为,还需要设置ssl 安全认证。7 设置 SSL 安全认证
7.1 再次打开 registry.conf 文件vi /docker-registry/nginx/registry.conf
将下面的几行取消注释并且修 域名:upstream docker-registry { server registry:5000; } server { listen 443; server_name docker-server.com; # SSL ssl on; ssl_certificate /etc/nginx/conf.d/domain.crt; ssl_certificate_key /etc/nginx/conf.d/domain.key;
7.2 创建 Certification Authoritycd /docker-registry/nginx
创建新的 root key:openssl genrsa -out dockerCA.key 2048
创建 root certificate
在Common Name 里填入 docker-server.com 就可以了,其他内容随便填。openssl req -x509 -new -nodes -key dockerCA.key -days 10000 -out dockerCA.crt
创建 server key (这个是被nginx ssl_certificate_key 引用的)openssl genrsa -out domain.key 2048
再创建一个新的 certificate
Common Name 继续填 docker-server.com,不用设置密码。openssl req -new -key domain.key -out docker-registry.com.csr
最后,进行签名:openssl x509 -req -in docker-registry.com.csr -CA dockerCA.crt -CAkey dockerCA.key -CAcreateserial -out domain.crt -days 10000
复制 dockerCA.crtcd /docker-registry/nginx cp dockerCA.crt /usr/local/share/ca-certificates/
为了让服务器信任我们的 Certification Authority 认证,我们需要update-ca-certificates && service docker restart && service docker-registry restart
测试curl https://mydocker:123456@docker-server.com/v2/ #output should be {}root@ubuntu:/docker-registry/nginx#8 将 dockerCA.crt 复制到客户端
scp dockerCA.crt root@192.168.188.112:/usr/local/share/ca-certificates root@192.168.188.112's password: dockerCA.crt 100% 1302 1.3KB/s 00:00
如果客户端没有 /usr/local/share/ca-certificates 目录,则需要创建
8.1 补充:如果是CentOS 系统的客户端
由于CentOS 系统的CA 证书存放的位置和ubuntu 系统的不同,所以,如果你使用的客户端的系统是CentOS 的,
请把CA放到/etc/pki/ca-trust/source/anchors,在命令行运行/bin/update-ca-trust,这样证书就导入到系统中去了。
然后,重启docker daemon。9 客户端登录服务器仓库
update-ca-certificates && service docker restart #test login to fresh created repository: docker login https://docker-server.com Username: mydocker Password: Login Succeeded
需要在 /etc/hosts 文件中添加
192.168.188.113 docker-server.com #(这是我做实验的服务端的 IP 地址)
9.1 在客户端推送镜像docker pull ubuntu # 尝试在 docker hub 下载镜像 docker tag ubuntu docker-server.com/test-ubuntu # 将镜像打标签,作为区别 docker push docker-server.com/test-ubuntu # 推送到 私有 docker registry 仓库
确认测试在客户端将 docker-server.com/test-ubunt 镜像删除: docker image rm -f docker-server.com/test-ubunt 从 docker-server.com 仓库下载 test-ubnutn 镜像: docker pull docker-server.com/test-ubuntu
过程截图:
ok,成功了。
如果在实验的过程中遇到什么问题,请查找docker 的日志文件
journalctl -u docker # for docker logs in the systemd journal
journalctl | grep docker # for system logs that mention docker总结
主要利用里nginx 的反向代理服务器的功能,实现了安全认证管理,加强了访问私有仓库的安全权限管理。
参考文章:
《Private Docker Registry in Ubuntu Server 16.04》
相关文章推荐
- Docker Registry Server 搭建,配置免费HTTPS证书,及拥有权限认证、TLS 的私有仓库
- Ubuntu Docker Registry 搭建私有仓库
- 在 ubuntu 搭建 docker registry 私有仓库
- Docker Registry Server 搭建,配置免费HTTPS证书,及拥有权限认证的私有仓库
- Docker Registry Server 搭建,配置免费HTTPS证书,及拥有权限认证、TLS 的私有仓库
- Docker私有仓库Registry及Auth-server认证搭建
- Docker私有仓库Registry 搭建
- Docker--------Harbor registry私有仓库搭建 [ Http ]
- ubuntu下部署带认证的私有docker registry(原创请注明出处)
- docker registry-v2 搭建私有仓库
- docker | 学习教程 docker 搭建无认证私有仓库
- Docker搭建带有访问认证的私有仓库
- Docker--------registry私有仓库搭建 [ Http ]
- Docker私有仓库Registry搭建(localhost 可行但跨主机有问题)
- Docker私有仓库Registry的搭建验证
- Docker私有仓库Registry的搭建验证
- docker:用registry快速搭建私有镜像仓库
- Docker私有仓库Registry的搭建验证
- docker 如何搭建私有仓库(ubuntu 14.04,Docker版本1.6.4)详细介绍
- docker私有仓库registry的本地搭建