Registry是一个无状态的,高可扩展的服务器端应用程序,用于存储和分发Docker Image。为什么要使用Registry,主要有以下几点原因:
1)严格控制image的存储位置;
2)完全中控image的分发路径;
3)在内部开发流程中更紧密的集成image的存储和分发。
要使用Docker Registry,当然首先要安装Docker。假设你已经安装好Docker。没有安装好可以参考官方文档。
Docker-compose是一个非常有用的Docker运行,管理的工具。你可以通过定义compose文件,使用简单的一条命令同时起多个Docker Container运行不同的服务。Docker-compose对于开发,测试,环境保存以及CI都提供非常大的便利。鉴于本文所有的搭建方法,跟随digitalocean使用了nginx和Registry两个容器,所以也使用Docker-compose来运行Docker容器。
Docker-compose是用Python开发的一个工具,所以可以用pip直接安装。
sudo pip install docker-compose需要注意的是,docker-compose可能对requests module的版本有限制,而本机上可能安装了更高版本的requests模块,造成运行时报错。可以使用pip-conflict-checker检查版本冲突,卸载不合适的版本,重新安装一个合适的版本。
sudo pip install pip-conflict-checker sudo pipconflictchecker sudo pip uninstall requests sudo pip install requests==2.7.0实际使用操作中使用pip安装的docker-compose可能在执行时还会报代码有bug,也可以直接从github中下载稳定的release版本安装。需要root权限。
curl -L https://github.com/docker/compose/releases/download/1.5.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
因为需要使用nginx提供安全验证的功能,需要一个地方放置用户名和密码对,使用htpasswd工具生成用户名密码对。在debian系中,htpasswd工具有Apache提供,但是在CentOS中由httpd-tools提供。如果不确定,可以使用yum provides查看.
安装httpd-tools.sudo yum install httpd-tools
创建一个工作目录,并在该目录下创建docker-compose.yml文件,将以下内容复制粘贴到文件中。内容大致意思为,基于“nginx:1.9” image运行nginx容器,暴露容器443端口到host 443端口。并挂载当前目录下的nginx/目录为容器的/etc/nginx/config.d目录。nginx link到registry容器。基于registry:2 image创建registry容器,将容器5000端口暴露到host 5000端口,使用环境变量指明使用/data为根目录,并将当前目录下data/文件夹挂载到容器的/data目录。所有还需要在当前目录下创建nginx和data文件夹:
mkdir data && mkdir nginxdocker-compose.yml 内容:
nginx: image: "nginx:1.9" ports: - 443:443 links: - registry:registry volumes: - ./nginx/:/etc/nginx/conf.d registry: image: registry:2 ports: - 127.0.0.1:5000:5000 environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data volumes: - ./data:/data
upstream docker-registry { server registry:5000; } server { listen 443; server_name myregistrydomain.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; } }配置文件创建完成后,回到工作目录执行docker-compose up运行registry和nginx容器,并使用curl命令验证结果。
docker-compose up执行docker-compose up后,终端输出信息如下。注意是否有容器启动失败的消息,如果容器启动失败的消息,需要检查网络,是否能从dockerhub上pull image(需代理,或使用使用国内镜像,使用国内镜像需更改docker-compose.yml文件中image项)。也由可能粘贴配置文件错误,需仔细检查。
启动后也可以使用docker ps命令查看是否两个容器都正常运行。
确定docker容器都正常运行后,只用curl 命令验证功能是否正常运行。可以访问localhost:5000直接访问registry,或使用localhost:443端口都应该返回{}.
curl http://localhost:5000/v2/ curl http://localhost:443/v2/使用ctrl-c退出容器执行,继续后面的步骤。
htpasswd -c registry.password USERNAME然后修改Registry.conf文件,取消下面三行的注释。
auth_basic "registry.localhost"; auth_basic_user_file /etc/nginx/conf.d/registry.password; add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;再次执行docker-compose up运行registry,这时使用localhost:5000端口访问任然得到的结果为”{}”,但是使用localhost:5043访问将得到”401 Authorisation Required“的提示。加入用户名和密码验证才能得到与直接访问registry 5000端口相同的结果。
curl http://USERNAME:PASSWORD@localhost:5043/v2/
openssl genrsa -out devdockerCA.key 2048(2)生成根证书(一路回车即可)
openssl req -x509 -new -nodes -key devdockerCA.key -days 10000 -out devdockerCA.crt(3) 为server创建一个key。(这个key将被nginx配置文件registry.con中ssl_certificate_key域引用)
openssl genrsa -out domain.key 2048<span style="white-space:pre"> </span>
openssl req -new -key domain.key -out dev-docker-registry.com.csr(5) 签署认证请求
openssl x509 -req -in dev-docker-registry.com.csr -CA devdockerCA.crt -CAkey devdockerCA.key -CAcreateserial -out domain.crt -days 10000<span style="font-family: monospace, monospace; background-color: rgb(255, 255, 255);"> </span>
ssl on; ssl_certificate /etc/nginx/conf.d/domain.crt; ssl_certificate_key /etc/nginx/conf.d/domain.key;</span>
curl https://test:test@localhost:443/v2/</span>由于是使用的未经任何认证结构认证的证书,并且还没有在本地应用自己生成的证书。所以此时会提示使用的是未经认证的证书,可以使用“-k"选项不进行验证。
sudo yum install ca-certificates</span>2)使能动态CA配置功能
sudo update-ca-trust force-enable</span>3)将key拷贝到/etc/pki/ca-trust/source/anchors/
sudo cp devdockerCA.crt /etc/pki/ca-trust/source/anchors/</span>4)使新拷贝的证书生效
sudo update-ca-trust extract</span>证书拷贝后,需要重启docker以保证docker能使用新的证书。
docker login xingwangc.docker.rg使用pull/push image。下图所示,我的域名为xingwangc.docker.rg的Registry host中,有从另外一个registry(xingwangc.docker.com)中pull的images。然后将test-hello打tag为localhost:5000/hello并push到本地registry。由于本地主机并没有加key到认证目录,所以使用域名的方式pull另一个tag image失败。
Digitalocean:How To Set Up a Private Docker Registry on Ubuntu 14.04