使用nginx的原因
自从Docker 1.3.x之后,与docker registry交互默认使用的是https,而使用registry:2镜像直接搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报错。为了解决这个问题可以使用nginx生成https正式实现交互。
docker私有仓库创建过程
操作环境:ubuntu14.04 + docker:1.12.1
1、在安装完docker,docker-compose之后安装apache2-utils (其中的htpasswd生成的哈希密码可以被nginx理解)
sudo apt-get -y install apache2-utils
2、新建并进入 docker-registry目录,然后新建data目录
mkdir ~/docker-registry && cd $_
mkdir data
3、创建docker-compose.yml文件,写入以下内容
registry:
# restart: always
image: registry:2
ports:
- 127.0.0.1:5000:5000
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
volumes:
- ./data:/data
4、新开一个Terminal(暂且称为Terminal2,原先的为Terminal为1)并切换到docker-registry目录,方便测试。
在Terminal2中启动容器:
sudo docker-compose up
Terminal2中输入CTRL-C关闭registry 容器
5、Terminal1创建并进入nginx目录
mkdir ~/docker-registry/nginx
cd nginx
6、修改docker-compose.yml
nginx:
# restart: always
image: "nginx:1.9"
ports:
- 5043:443
links:
- registry:registry
volumes:
- ./nginx/:/etc/nginx/conf.d
registry:
# restart: always
image: registry:2
ports:
- 127.0.0.1:5000:5000
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
volumes:
- ./data:/data
7、在Terminal2中启动容器
sudo docker-compose up
8、在Terminal1中创建registry.conf文件
touch~/docker-registry/nginx/registry.conf
upstream docker-registry {
server registry:5000;
}
server {
listen 443;
server_name registry.xxx.com;
# SSL
# ssl on;
# ssl_certificate /etc/nginx/conf.d/domain.crt;
# ssl_certificate_key /etc/nginx/conf.d/domain.key;
# 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 plus add_header
# auth_basic "registry.localhost";
# auth_basic_user_file /etc/nginx/conf.d/registry.password;
# add_header 'Docker-Distribution-Api-Version' 'registry/2.0' 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;
}
}
9、在Terminal2中启动重新生成容器并在Terminal1中测试
测试1:curl http://localhost:5000/v2/
返回一个空的json对象 {}
测试2:curl http://localhost:5043/v2/
同样返回一个空的json对象 {}
Terminal2中输入CTRL-C关闭registry 容器
10、在Terminal1中创建一个认证文件(nginx可以识别)
htpasswd -c registry.password xxxx,根据提示输入密码
11、去掉registry.conf中的注释
server {
listen 443;
server_name registry.xxxx.com;
# SSL
ssl on;
ssl_certificate /etc/nginx/conf.d/domain.crt;
ssl_certificate_key /etc/nginx/conf.d/domain.key;
# 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 plus add_header
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' 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;
}
}
12、在Terminal1中创建自己的证书
openssl genrsa -out devdockerCA.key 2048 #生成一个key
openssl req -x509 -new -nodes -key devdockerCA.key -days 10000 -out devdockerCA.crt # 根据提示输入,可以只写Common Name
openssl genrsa -out domain.key 2048
openssl req -new -key domain.key -out dev-docker-registry.com.csr #其中A challenge password []:可以不用填
openssl x509 -req -in dev-docker-registry.com.csr -CA devdockerCA.crt -CAkey devdockerCA.key -CAcreateserial -out domain.crt -days 10000
13、告诉客户端这是一个合法的证书,可以使用这个证书
sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert
sudo cp devdockerCA.crt /usr/local/share/ca-certificates/docker-dev-cert
sudo update-ca-certificates
14、sudo service docker restart
15、在/etc/hosts文件中加入registry.xxxx.com域名。
16、在Terminal2中重新生成容器,并在Terminal1中输入curl https://name:password@registry.xxxx.com:5043/v2/ 进行测试
如果出现了这个错误,可以运行curl -k https://name:password@registry.xxxx.com:5043/v2/;结果返回一个空的json对象 {} 就是正确的
17、 修改docker-compose.yml 文件
nginx:
# restart: always
image: "nginx:1.9"
ports:
- 443:443
links:
- registry:registry
volumes:
- ./nginx/:/etc/nginx/conf.d
registry:
# restart: always
image: registry:2
ports:
- 127.0.0.1:5000:5000
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
volumes:
- ./data:/data
在Terminal2中重新生成容器
18、运行sudo cat /docker-registry/nginx/devdockerCA.crt并将证书记录下来供客户端使用。(不同的主机生成的证书不同)
19、在服务器端测试
sudo docker login https://registry.xxxx.com 并根据提示输入username和密码。
可以在ubuntu服务器中的data目录下查看镜像的信息
客户端的配置
1、创建目录docker-dev-cert并创建devdockerCA.crt文件
sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert
sudo touch /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt
2、在devdockerCA.crt文件中输入服务器生成的CA证书。
3、运行sudo update-ca-certificates更新证书
4、sudo service docker restart
5、在/etc/hosts文件中加入服务器的IP和 registry.xxxx.com .
6、sudo docker login https://registry.xxxx.com 并根据提示输入username和密码。
7、测试
sudo docker tag ubuntu registry.xxxx.com/ubuntu(tag)
sudo docker push registry.xxxx.com/ubuntu(tag)
“`