Docker Registry V2 问世后,简单实用的确不错,不过等将端口5000更改成其他后,或者使用域名绑定后就错误百出。这里详细的将自己的经历过程做一个记录。


一、Docker Registry V2(distribution) 的安装。

这里我选择了使用官方提供的镜像去进行安装,也许你会感觉这很EASY,不屑一顾。不过,对一个运维人员来说,注重的是应用,注重的是registry中的镜像。而不是注重花哨的搭建过程。而我们注重的,registry 镜像都能满足我们的需求。


# docke pull registry:2
# docker run -d -p 5000:5000 --restart=always --name registry -v /data/:/var/lib/registry -v /etc/registry/config.yml:/etc/docker/registry/config.yml registry:2

以上两个注重点:

(1)、确保所管理的镜像文件的安全,若使用本地磁盘存储镜像,则一定将其挂在到宿主机中。

(2)、registry 的配置文件管理,若你想有自己的定制效果,请不要使用registry的默认配置,请将其    进行覆盖。

以下是我使用的配置文件:

# cat /etc/registry/config.yml 
version: 0.1
log:
    level: debug
    formatter: text
    fields:
        service: registry
        environment: staging
storage:
    delete:
        enabled: true
    cache:
        layerinfo: inmemory
    filesystem:
        rootdirectory: /var/lib/registry
http:
    addr: :5000
    secret: admin

配置文件为YAML 格式。其中指定了镜像的存储位置、缓存类型、监听端口等。

其中 secret: admin 这个要额外注意。这回在下一步的安全认证中使用到。


基于以上的东西,registry 能做些什么呢? 


它能做这些:

Example:

# docker pull ubuntu && docker tag ubuntu localhost:5000/ubuntu

then....

# docker push localhost:5000/ubuntu


当然,你可能不会满足这些,你想对你的registry 起一个响亮的名字。假如叫:registry.test.com

暂时做上本地DNS绑定,再重复一下上面的步骤,看看效果如何。

# docker pull ubuntu && docker tag ubuntu registry.test.com:5000/ubuntu

then....

# docker push registry.test.com:5000/ubuntu

你会发现并不理想,甚至连一个友好的错误提示都没有在终端上看到。但当你使用 docker logs 命令

去查看registry 里面的日志时,会发现有关认证的错误提示。


此时,我们有可能按照官方的文档:

https://github.com/docker/distribution/blob/master/docs/insecure.md


去做一些配置.............


再次重新PUSH

# docker push registry.test.com:5000/ubuntu

如果你真是按照官方文档配置,你会发现你成功了。


后来,你更贪心,打算将5000端口去掉。换成默认的80端口,registry服务,毕竟是HTTP服务。我们没有必要那么矫形。将registry 的 config.yml 的 监听端口更改为80

http:
    addr: :80
    secret: admin

重启后,发现根本就不是那么一回事。 细心的同学会发现,还是认证问题。


那要解决这个问题,怎么破?

用代理试试吧。毕竟docker registry v1 的时候,前面就可以设置代理的。呵呵

且上一步还遗留这证书的问题,所有这个代理恐怕要配置成https 了。那就配置代理吧。


二、配置Docker Registry 的代理服务器

(1)、先生成证书吧(模仿docker 官方更改了一下路径。呵呵)。

mkdir -p /etc/nginx/ssl && openssl req \
  -newkey rsa:4096 -nodes -sha256 -keyout ssl/domain.key \
  -x509 -days 365 -out ssl/domain.crt

这里要注意CN 的名字,必须是你的registry 的域名,否则你的事情就大了。

Example:

Country Name (2 letter code) [AU]:China
string is too long, it needs to be less than  2 bytes long
Country Name (2 letter code) [AU]:CH
State or Province Name (full name) [Some-State]:BeiJing
Locality Name (eg, city) []:BeiJing      
Organization Name (eg, company) [Internet Widgits Pty Ltd]:BeiJing
Organizational Unit Name (eg, section) []:BeiJing  
Common Name (e.g. server FQDN or YOUR name) []:registry.test.com
Email Address []:BeiJing@beijing.com

(2)、安装NGINX 及调整配置。

1.7.5 这个版本或以      上(这个命令中使用了 always 这个东西,只有在1.7.5 及以上才OK的)。

   另外,nginx 配置文件的详细细节,最本文最后贴出。

(3)、设置registry 的登录用户名和密码

# htpasswd -cb /opt/nginx/conf/.htpasswd admin admin

想想,当初我们的registry 中也设置了一个admin 的东西。两个必须都存在的。。否则会有问题的。


(4)、去掉当初直接对registry 设置的认证。比如如下的设置:

docker run -d -p 5000:5000 --restart=always --name registry \
  -v `pwd`/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  registry:2

请去掉 认证相关的东西吧。回到本文最开始启动registry的形式上。所有一切的认证。我们将在nginx 去处理的....


(5)、最后,列举出nginx 的配置文件,一切全部了然:

user  www www;
worker_processes  auto;

error_log   /var/log/nginx/error.log error;
pid        logs/nginx.pid;

worker_rlimit_nofile 51200;

events {
    use epoll;
    worker_connections  51200;
    multi_accept on;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$http_host $remote_user [$time_local] $request '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" $remote_addr $request_time $upstream_response_time';

    access_log  /var/log/nginx/access.log  main;

    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;

    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    upstream registry {
        server 127.0.0.1:5000;
    }    

    server {
        listen       443;
        server_name  registry.chanjet.com;

        ssl          on;
        ssl_certificate /etc/nginx/ssl/domain.crt;
        ssl_certificate_key /etc/nginx/ssl/domain.key;

        client_max_body_size 0;

        chunked_transfer_encoding on;

        location /v2/ {
	  auth_basic "Registry realm";
          auth_basic_user_file /opt/nginx/conf/.htpasswd;
          add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

          proxy_pass                          http://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;
        }
    }
}


三、最后验证:

配置是否好用,还需要通过适当的方法进行验证。

(1)、连通性验证:



# curl -i -k -v https://admin:admin@registry.test.com/v2/



(2)、身份验证(最好登录另外一台服务器)。

# docker login registry.chanjet.com # 会提示你输入用户名、密码、邮箱等.验证通过后,你就可以往这上面push东西了。如果没有这一步操作,你会发现验证失败的相关提示
# docker pull busybox && docker tag busybox registry.chanjet.com/test/busybox
# docker push registry.chanjet.com/test/busybox

(3)、查看上传的镜像信息:

# curl -i -k -v https://admin:admin@registry.test.com/v2/_catalog

参考文档:


https://github.com/docker/distribution/blob/master/docs/configuration.md

https://github.com/docker/distribution/blob/master/docs/insecure.md

http://www.dockone.io/article/684

https://docs.docker.com/registry/nginx/


转载于:https://blog.51cto.com/unixman/1707423