查看原文: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