Registry私有仓库搭建及认证
本节内容:
Registry相关概念
Registry V1和V2
安装Docker
搭建本地registry v2
搭建外部可访问的Registry
添加认证
更⾼级的认证
registry web ui
⼀、Registry相关概念
前⾯的⽂章讲过Docker的组成部分,我们⼀般在使⽤Docker的过程中更为常⽤的是pull image、run image、build image和push image。主要是围绕image展开的。
image和Registry的关系可以想象成⾃⼰机器上的源码和远端SVN或者Git服务的关系。Registry是⼀个⼏种存放image并对外提供上传下载以及⼀系列API的服务。可以很容易和本地源代码以及远端Git服务的关系相对应。
Docker hub是Docker公司提供的⼀些存储镜像的空间,这部分空间是有限的。我们⼀般会⾃主建设Docker私有仓库Registry。
⼆、Registry V1和V2
Docker Registry 2.0版本在安全性和性能上做了诸多优化,并重新设计了镜像的存储的格式。Docker⽬前1.6之后⽀持V2。
三、安装Docker
见前⾯发布的⽂章《CentOS安装Docker CE》。
四、搭建本地registry v2
环境:172.16.7.151 CentOS 7.0 主机名:node1
[root@node1 ~]# docker run -d -p 5000:5000 --name wisedu_registry registry:2
本地push镜像到registry仓库:
[root@node1 ~]# docker pull ubuntu:16.04
[root@node1 ~]# docker tag ubuntu:16.04 localhost:5000/my-ubuntu
[root@node1 ~]# docker push localhost:5000/my-ubuntu
删除本地的ubuntu:16.04和localhost:5000/my-ubuntu镜像:
[root@node1 ~]# docker image remove ubuntu:16.04
[root@node1 ~]# docker image remove localhost:5000/my-ubuntu
从本地registry中拉取 localhost:5000/my-ubuntu 镜像:
[root@node1 ~]# docker pull localhost:5000/my-ubuntu
但是这种registry只是本地能使⽤,我们另外⼀台主机172.16.7.152往该registry中push镜像:
[root@node2 ~]# docker pull ubuntu:16.04
[root@node2 docker]# docker tag ubuntu:16.04172.16.7.151:5000/ubuntu:v1
[root@node2 docker]# docker push 172.16.7.151:5000/ubuntu:v1
The push refers to a repository [172.16.7.151:5000/ubuntu]
Get 172.16.7.151:5000/v2/: http: server gave HTTP response to HTTPS client
[root@node2 ~]# echo $?
1
这是因为从docker1.13.2版本开始,使⽤registry时,必须使⽤TLS保证其安全。
停⽌并删除本地registry:
[root@node1 ~]# docker stop wisedu_registry
wisedu_registry
[root@node1 ~]# docker rm -v wisedu_registry
wisedu_registry
五、搭建外部可访问的Registry
官⽅⽂档:docs.docker/registry/deploying/#run-an-externally-accessible-registry
Running a registry only accessible on localhost has limited usefulness. In order to make your registry accessible to external hosts, you must first secure it using TLS.
使⽤TLS认证registry容器时,必须有证书。⼀般情况下,是要去认证机构购买签名证书。这⾥使⽤openssl⽣成⾃签名的证书。
环境信息:172.16.206.32 CentOS 7.0 主机名:spark32
1.⽣成⾃签名证书
[root@spark32 ~]# mkdir -p /opt/docker/registry/certs
[root@spark32 ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout /opt/docker/registry/certs/domain.key -x509 -days 365 -out /opt/docker/registry/
Generating a 4096 bit RSA private key
...
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:JiangSu
Locality Name (eg, city) [Default City]:NanJing
Organization Name (eg, company) [Default Company Ltd]:wisedu
Organizational Unit Name (eg, section) []:edu
Common Name (eg, your name or your server's hostname) []:registry.docker
Email Address []:01115004@wisedu
2.创建带有TLS认证的registry容器
[root@spark32 ~]# docker run -d --name registry2 -p 5000:5000 -v /opt/docker/registry/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry:2
3.在每⼀个docker客户端宿主机上配置/etc/hosts,以使客户端宿主机可以解析域名”registry.docker”。并创建与这个registry服务器域名⼀致的⽬录(因为我这⾥的域名是假
的)
# vim /etc/hosts
172.16.206.32 registry.docker
[root@node1 ~]# cd /etc/docker/certs.d/
[root@node1 certs.d]# mkdir registry.docker:5000
4.将证书 复制到每⼀个docker客户端宿主机/etc/docker/certs.d/registry.docker:,不需要重启docker
[root@spark32 ~]# scp -p /opt/docker/registry/ root@172.16.7.151:/etc/docker/certs.d/registry.docker\:
5.push镜像到registry
另⼀个客户机node1,push镜像到registry。
[root@node1 certs.d]# docker tag ubuntu:16.04 registry.docker:5000/my-ubuntu:v1
[root@node1 certs.d]# docker push registry.docker:5000/my-ubuntu:v1
The push refers to a repository [registry.docker:5000/my-ubuntu]
a09947e71dc0: Pushed
9c42c2077cde: Pushed
625c7a2a783b: Pushed
25e0901a71b8: Pushed
8aa4fcad5eeb: Pushed
v1: digest: sha256:634a341aa83f32b48949ef428db8fefcd897dbacfdac26f044b60c14d1b5e972 size: 1357
6.列出私有仓库中的所有镜像
[root@node1 certs.d]# curl -X GET registry.docker:5000/v2/_catalog -k
{"repositories":["my-ubuntu"]}
7.查看存储在registry:2宿主机上的镜像
在registry:2创建的私有仓库中,上传的镜像保存在容器的/var/lib/registry⽬录下。创建registry:2的容器时,会⾃动创建⼀个数据卷(Data Volumes),数据卷对应的宿主机下的⽬录
⼀般为:/var/lib/docker/volumes/XXX/_data。
[root@spark32 ~]# ls /var/lib/docker/volumes/91a0091963fa6d107dc988a60b61790bba843a115573e331db967921d5e83372/_data/docker/registry/v2/repositories/my-ubuntu/
_layers _manifests _uploads
可以在创建registry:2的容器时,通过-v参数,修改这种数据卷关系:
–v /opt/docker/registry/data:/var/lib/registry
除了可以将数据保存在当前主机的⽂件系统上,registry也⽀持其他基于云的存储系统,⽐如S3,Microsoft Azure, Ceph Rados, OpenStack Swift and Aliyun OSS等。可以在配
置⽂件中进⾏配置:github/docker/distribution/blob/master/docs/configuration.md#storage
【补充】:
⼀般情况下,证书只⽀持域名访问,要使其⽀持IP地址访问,需要修改配置⽂件opensslf。
在Redhat7系统中,⽂件所在位置是/etc/pki/tls/opensslf。在其中的[ v3_ca]部分,添加subjectAltName选项:
[ v3_ca ]
subjectAltName = IP:192.168.1.104
⽣成证书:
...
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:172.16.206.32:5000
Email Address []:
六、添加认证:Native basic auth
The simplest way to achieve access restriction is through basic authentication (this is very similar to other web servers’ basic authentication mechanism). This example uses
native basic authentication using htpasswd to store the secrets.
1.创建⽤户密码⽂件,testuser,testpassword
[root@spark32 ~]# mkdir /opt/docker/registry/auth
[root@spark32 ~]# docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > /opt/docker/registry/auth/htpasswd
2.运⾏registry容器
[root@spark32 ~]# docker run -d --name registry_native_auth -p 5000:5000 -v /opt/docker/registry/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_P
3.现在尝试拉取镜像
[root@node1 ~]# docker pull registry.docker:5000/my-ubuntu:v1
Error response from daemon: Get registry.docker:5000/v2/my-ubuntu/manifests/v1: no basic auth credentials
4.登录registry,push镜像
[root@node1 ~]# docker login registry.docker:5000
Username: testuser
Password:
Login Succeeded
[root@node1 ~]# docker tag ubuntu:16.04 registry.docker:5000/my-ubuntu:v1
[root@node1 ~]# docker push registry.docker:5000/my-ubuntu:v1
七、更⾼级的认证
更好的⽅式是在registry前使⽤代理,利⽤代理提供https的ssl的认证和basic authentication。docs.docker/registry/recipes/ 1. 配置Nginx作为认证代理
docs.docker/registry/recipes/nginx/
(1)创建需要的⽬录
[root@spark32 ~]# mkdir -p /opt/nginx_proxy_registry/{auth,data}
(2)创建Nginx主配置⽂件
events {
worker_connections 1024;
}
http {
upstream docker-registry {
server registry:5000;
}
## Set a variable to help us decide if we need to add the
## 'Docker-Distribution-Api-Version' header.
## The registry always sets this header.
## In the case of nginx performing auth, the header will be unset
## since nginx is auth-ing before proxying.
map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
'''registry/2.0';
}
server {
listen 443 ssl;
server_name registry.docker;
# SSL
ssl_certificate /etc/nginx/conf.;
ssl_certificate_key /etc/nginx/conf.d/domain.key;
# Recommendations from /s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# disable any limits to avoid HTTP 413for large image uploads
client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (github/moby/moby/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.
auth_basic "Registry realm";
auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;
## If $docker_distribution_api_version is empty, the header will not be added.
## See the map directive above where this variable is defined.
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
proxy_pass 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;
}
}
}
Nginx配置
(3)创建密码认证⽂件
[root@spark32 ~]# docker run --rm --entrypoint htpasswd registry:2 -bn testuser testpassword > /opt/nginx_proxy_registry/auth/nginx.htpasswd
(4)拷贝之前⽣成的证书和key到auth⽬录下
[root@spark32 ~]# cp /opt/docker/registry/ /opt/nginx_proxy_registry/auth/
[root@spark32 ~]# cp /opt/docker/registry/certs/domain.key /opt/nginx_proxy_registry/auth/
(5)创建compose⽂件
nginx:
image: "nginx:1.9"
ports:
- 5043:443
links:
- registry:registry
volumes:
- ./auth:/etc/nginx/conf.d
- ./f:/etc/f:ro
registry:
image: registry:2
ports:
- 127.0.0.1:5000:5000
volumes:
- ./data:/var/lib/registry
(6)启动
[root@spark32 nginx_proxy_registry]# docker-compose up -d
(7)验证启动的服务
[root@spark32 nginx_proxy_registry]# docker-compose ps
[root@spark32 ~]# docker ps
⼀台docker客户端机器登录:
创建需要的⽬录:
[root@node1 ~]# mkdir /etc/docker/certs.d/registry.docker:5043
把 传到上⼀步⽣成的⽬录⾥:
[root@spark32 ~]# scp -p /opt/nginx_proxy_registry/ root@172.16.7.151:/etc/docker/certs.d/registry.docker:
登录进⾏测试:
[root@node1 ~]# docker login -u=testuser -p=testpassword registry.docker:5043
Login Succeeded
[root@node1 ~]# docker tag ubuntu:16.04 registry.docker:5043/ubuntu-test:v1
[root@node1 ~]# docker push registry.docker:5043/ubuntu-test:v1
(8)停⽌服务
[root@spark32 ~]# cd /opt/nginx_proxy_registry/
[root@spark32 nginx_proxy_registry]# docker-compose stop
(9)查看⽇志
[root@spark32 nginx_proxy_registry]# docker-compose logs
nginx ssl证书配置2. 补充Docker compose
(1)Docker compose是什么
Docker Compose是⼀个⽤来定义和运⾏复杂应⽤的Docker⼯具。使⽤Compose,你可以在⼀个⽂件中定义⼀个多容器应⽤,然后使⽤⼀条命令来启动你的应⽤,完成⼀切准备⼯作。
⼀个使⽤Docker容器的应⽤,通常由多个容器组成。使⽤Docker Compose,不再需要使⽤shell脚本来启动容器。
Docker Compose将所管理的容器分为三层,⼯程(project)、服务(service)以及容器(contaienr)。⼀个⼯程当中可包含多个服务,每个服务中定义了容器运⾏的镜像,参数,依赖。⼀个服务当中可包括多个容器实例,Docker Compose并没有解决负载均衡的问题,因此需要借助其他⼯具实现服务发现及负载均衡。
(2)安装docker compose
将变量 $dockerComposeVersion 换成指定的
[root@spark32 ~]# curl -L github/docker/compose/releases/download/$dockerComposeVersion/docker-compose-`uname -m` -o /usr/local/bin/docker-compose
⽐如下载安装1.15.0版本:
[root@spark32 ~]# curl -L github/docker/compose/releases/download/1.15.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
可能会下载失败,多试⼏次。实在不⾏就需要FQ去下载。
赋予执⾏权限:
[root@spark32 ~]# chmod +x /usr/local/bin/docker-compose
查看docker compose版本:
[root@spark32 ~]# docker-compose --version
docker-compose version 1.15.0, build e12f3b9
(3)卸载docker compose
如果docker compose是通过curl安装的:
rm /usr/local/bin/docker-compose
如果docker compose是通过pip安装的:
pip uninstall docker-compose
⼋、registry web ui
搭建完了docker registry,我们可以使⽤ docker 命令⾏⼯具对我们搭建的 registry 做各种操作了,如 push / pull。但是不够⽅便,⽐如不能直观的查看 registry 中的资源情况,如
果有⼀个 ui ⼯具,能够看到仓库中有哪些镜像、每个镜像的版本是多少。registry web ui主要有3个,⼀个是,⼀个是,还有⼀个是。
关于registry ui的搭建会在后⾯的⽂章中介绍。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论