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.crt
和domain.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。
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
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文件配置
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证书私钥 # 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/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仍然在使用身份验证时证书验证不通过?
在/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