docker registry

 

查看原文:https://docs.docker.com/registry/ 

“The Registry is a stateless, highly scalable server side application that stores and lets you distribute Docker images.“

注册表是一个无状态,高度可扩展的服务器端应用程序,它存储并允许您分发Docker镜像。

为什么使用它

  • 严格控制Docker镜像存储的位置
  • 拥有完全属于您的Docker镜像发送渠道
  • 将Docker镜像存储和分发紧密集成到您的内部开发工作流程中

要求

registry与Docker v1.6.0或更高版本兼容。如果你真的需要使用旧的Docker版本,你应该查看 old python registry

你应该完全遵循基本的部署指南

如果你没有,请花时间这样做。

Docker引擎需要使用TLS来保护它,这在概念上非常类似于使用SSL配置Web服务器。

  • 您了解Docker安全要求,以及如何正确配置Docker。
  • 你已经安装了Docker Compose(可以不安装)。
  • 官方强烈建议您从已知CA获取证书,而不是自签名证书,关于什么是CA证书
  • 在当前目录内,您有一个X509 domain.crtdomain.key,common name是myregistrydomain.com(registry default url address),这个可以修改,后面会讲到。
  • 请确保您已停止并删除任何先前运行的registry(通常执行docker stop registry && docker rm -v registry

使用nginx验证代理


部署中会出现的问题

registry验证TLS从registry移动到nginx代理本身。

例如,”Amazon的Elastic Load Balancer(ELB)亚马逊的弹性负载均衡器“在HTTPS模式下已经设置了以下客户端request头:

X-Real-IP  
X-Forwarded-For  
X-Forwarded-Proto  

所以如果有一个nginx在它(ELB)后面,应该删除以下nginx.conf配置中的这些行:

X-Real-IP $remote_addr; # pass on real client's IP 
X-Forwarded-For $proxy_add_x_forwarded_for;  
X-Forwarded-Proto $scheme;  

否则nginx将重置(ELB)的值,并且请求将不会路由到正确地址。有关详细信息,请参阅 #970

 

在下列代码中的${request_host}需要替换为真实的外网请求地址

在下列代码中的${username}=
在下列代码中的$(password}=

username与password是登陆到registry+nginx私服的用户

1.生成CA证书

bash:

mkdir -p ~/docker-registry && openssl req \
-subj "/CN=${request_host}/" -newkey rsa:4096 -nodes -sha256 -keyout ~/docker-registry/domain.key \
-x509 -days 365 -out ~/docker-registry/domain.crt

2.生成密码文件

bash:

docker run --rm --entrypoint htpasswd registry:2.6.0 -bn ${username} ${password} > ~/docker-registry/nginx.htpasswd

3.配置registry的config.yml

config.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true #该设置为true才能在registry中删除image
http:
  addr: :5000
  host: http://${request_host}:5000 #自定义访问地址,不能是IP
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

4.运行regsitry

bash:

docker run -d -p 127.0.0.1:5000:5000 --restart=always --name registry \
-v ~/docker-registry/config.yml:/etc/docker/registry/config.yml \
registry:2.6.0

5.nginx.conf文件配置

nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
events {
    worker_connections  1024;
}
http {
  upstream docker-registry {
    server registry:5000;   #具体registry IP address
  }
  ## 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';  #这是默认配置,registry url api version
  }
  server {
    listen 443 ssl;
    server_name myregistrydomain.com;   #部署时确定url地址
    # SSL
    ssl_certificate /etc/nginx/conf.d/domain.crt;   #CA证书公钥
    ssl_certificate_key /etc/nginx/conf.d/domain.key;   #CA证书私钥
    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/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.
      auth_basic "Registry realm";
      auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;    #确定nginx能够获取到密码文件
      ## 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;   #upstream名称
      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;
    }
  }
}

 

6.运行nginx

bash:
docker run -d -p 5043:443 --link registry:registry --name nginx \
-v ~/docker-registry:/etc/nginx/conf.d \
-v ~/docker-registry/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx:1.11.10

 

7.地址映射到外网

把registry.com:5043这个url地址映射到公网,让外网可以访问。

如果不需要外网访问,改地址可以为docker容器的宿主机的IP地址。

 

其他docker程序如何访问到搭建的私服


Docker client仍然在使用身份验证时证书验证不通过?

domain.crt为服务器中生成的CA证书

在/etc/hosts文件中添加下面代码:

IP     registry.com #ip地址为docker registry服务地址


使用身份验证时,某些版本的Docker还需要您在操作系统级别信任证书。通常,在Ubuntu上,这是通过:

#ubuntu版本:

cp domain.crt /usr/local/share/ca-certificates/registry.com:5043.crt
update-ca-certificates

 

#红帽(及其衍生品)上:
cp domain.crt /etc/pki/ca-trust/source/anchors/zkpregistry.com:5043.crt
update-ca-trust

 

#在某些发行版(例如Oracle Linux 6)上,需要手动启用共享系统证书功能:
update-ca-trust enable


现在重新启动docker(service docker stop && service docker start或任何其他方式,你用来重新启动docker)

#登陆registry
docker login -u=zkp -p=zhongkejf -e=ci@zhongkejf.com zkpregistry.com:5043

 

#如果在登陆时报下列错误:

Handler for POST /auth returned error: invalid registry endpoint https://zkpregistry.com:5043/v0/: unable to ping registry endpoint https://zkpregistry.com:5043/v0/\nv2 ping attempt failed with error: Get https://zkpregistry.com:5043/v2/: dial tcp: lookup zkpregistry.com: no such host\n v1 ping attempt failed with error: Gethttps://zkpregistry.com:5043/v1/_ping: dial tcp: lookup zkpregistry.com: no such host. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry zkpregistry.com:5043` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/zkpregistry.com:5043/ca.crt

#请执行该语句解决:

mkdir -p /etc/docker/certs.d/registry.com:5043

cp domain.crt /etc/docker/certs.d/registry.com:5043/ca.crt

#重新启动docker并再次登陆

 

#下载测试image

docker pull registry.com:5043/alpine-linux:jdk-7

#运行image

docker run -it --name test registry.com:5043/alpine-linux:jdk-7 sh

#在container中测试是否能上网

ping www.baidu.com

 

posted @ 2017-05-10 13:52  Pomme_king  阅读(817)  评论(0编辑  收藏  举报