本节内容:
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和V2Docker 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.04 172.16.7.151:5000/ubuntu:v1[root@node2 docker]# docker push 172.16.7.151:5000/ubuntu:v1The push refers to a repository [172.16.7.151:5000/ubuntu]
Get https://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_registrywisedu_registry
五、搭建外部可访问的Registry官⽅⽂档:https://docs.docker.com/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/certs/domain.crtGenerating 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]:wiseduOrganizational Unit Name (eg, section) []:edu
Common Name (eg, your name or your server's hostname) []:registry.docker.comEmail Address []:01115004@wisedu.com
2.创建带有TLS认证的registry容器
[root@spark32 ~]# docker run -d --name registry2 -p 5000:5000 -v /opt/docker/registry/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry:2
3.在每⼀个docker客户端宿主机上配置/etc/hosts,以使客户端宿主机可以解析域名”registry.docker.com”。并创建与这个registry服务器域名⼀致的⽬录(因为我这⾥的域名是假的)
# vim /etc/hosts
172.16.206.32 registry.docker.com
[root@node1 ~]# cd /etc/docker/certs.d/
[root@node1 certs.d]# mkdir registry.docker.com:5000
4.将证书 domain.crt 复制到每⼀个docker客户端宿主机/etc/docker/certs.d/registry.docker.com:5000/ca.crt,不需要重启docker
[root@spark32 ~]# scp -p /opt/docker/registry/certs/domain.crt root@172.16.7.151:/etc/docker/certs.d/registry.docker.com\\:5000/ca.crt
5.push镜像到registry
另找⼀个客户机node1,push镜像到registry。
[root@node1 certs.d]# docker tag ubuntu:16.04 registry.docker.com:5000/my-ubuntu:v1[root@node1 certs.d]# docker push registry.docker.com:5000/my-ubuntu:v1The push refers to a repository [registry.docker.com:5000/my-ubuntu]a09947e71dc0: Pushed 9c42c2077cde: Pushed 625c7a2a783b: Pushed 25e0901a71b8: Pushed 8aa4fcad5eeb: Pushed
v1: digest: sha256:634a341aa83f32b449ef428db8fefcd7dbacfdac26f044b60c14d1b5e972 size: 1357
6.列出私有仓库中的所有镜像
[root@node1 certs.d]# curl -X GET https://registry.docker.com: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等。可以在配置⽂件中进⾏配置:https://github.com/docker/distribution/blob/master/docs/configuration.md#storage
【补充】:
⼀般情况下,证书只⽀持域名访问,要使其⽀持IP地址访问,需要修改配置⽂件openssl.cnf。
在Redhat7系统中,⽂件所在位置是/etc/pki/tls/openssl.cnf。在其中的[ 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 authThe simplest way to achieve access restriction is through basic authentication (this is very similar to other web servers’ basic authentication mechanism). This example usesnative 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.com:5000/my-ubuntu:v1
Error response from daemon: Get https://registry.docker.com:5000/v2/my-ubuntu/manifests/v1: no basic auth credentials
4.登录registry,push镜像
[root@node1 ~]# docker login registry.docker.com:5000Username: testuserPassword:
Login Succeeded
[root@node1 ~]# docker tag ubuntu:16.04 registry.docker.com:5000/my-ubuntu:v1[root@node1 ~]# docker push registry.docker.com:5000/my-ubuntu:v1
七、更⾼级的认证更好的⽅式是在registry前使⽤代理,利⽤代理提供https的ssl的认证和basic authentication。https://docs.docker.com/registry/recipes/
1. 配置Nginx作为认证代理
https://docs.docker.com/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.com;
# SSL
ssl_certificate /etc/nginx/conf.d/domain.crt;
ssl_certificate_key /etc/nginx/conf.d/domain.key;
# Recommendations from https://raymii.org/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 413 for large image uploads client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/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 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; } }}
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/certs/domain.crt /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
- ./auth/nginx.conf:/etc/nginx/nginx.conf:roregistry:
image: registry:2 ports:
- 127.0.0.1:5000:5000 volumes:
- ./data:/var/lib/registry
docker-compose.yml
(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.com:5043
把 domain.crt 传到上⼀步⽣成的⽬录⾥:
[root@spark32 ~]# scp -p /opt/nginx_proxy_registry/auth/domain.crt root@172.16.7.151:/etc/docker/certs.d/registry.docker.com:5043/ca.crt
登录进⾏测试:
[root@node1 ~]# docker login -u=testuser -p=testpassword registry.docker.com:5043Login Succeeded
[root@node1 ~]# docker tag ubuntu:16.04 registry.docker.com:5043/ubuntu-test:v1[root@node1 ~]# docker push registry.docker.com: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
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 https://github.com/docker/compose/releases/download/$dockerComposeVersion/docker-compose-`uname -m` -o /usr/local/bin/docker-compose
⽐如下载安装1.15.0版本:
[root@spark32 ~]# curl -L https://github.com/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 --versiondocker-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的搭建会在后⾯的⽂章中介绍。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igat.cn 版权所有 赣ICP备2024042791号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务