使用SSL验证和Nginx做代理搭建生产环境的Docker仓库
使用私有仓库有许多优点:
节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可;提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。
我的环境:CentOS-7-x86_64-Everything-1511
Docker版本:Version: 1.10.3,API version: 1.22,Go version: go1.5.3
在下载Linux发行版的时候需要下载较新的版本,Docker所支持的Linux kernel版本过低会出现问题。
一、安装Docker
CentOS中更新源后安装docker
官网https://docs.docker.com/engine/installation/linux/centos/
安装完成Docker环境之后不要去关闭CentOS的防火墙和Selinux,因为Docker的安全机制是基于iptables的,关闭selinux会是的Docker的安装出错。
docker: Error response from daemon: failed to create endpoint registry on network bridge: iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 5000 -j DNAT --to-destination 172.17.0.2:5000 ! -i docker0: iptables: No chain/target/match by that name.
(exit status 1).
二、安装Docker Registry
目前Docker Registry已经升级到了v2,最新版的Docker已不再支持v1。Registry v2使用Go语言编写,在性能和安全性上做了很多优化,重新设计了镜像的存储格式。
1.官网安装 registry
https://docs.docker.com/registry/
2.使用Docker-compose安装(推荐)
Docker-compose是一个非常有用的Docker运行,管理的工具。你可以通过定义compose文件,使用简单的一条命令同时起多个Docker Container运行不同的服务。Docker-compose对于开发,测试,环境保存以及CI都提供了非常大的便利。
Docker-compose是用Python开发的一个工具,所以可以用pip直接安装。
$ pip install docker-compose
需要注意的是,docker-compose可能对requests module的版本有限制,而本机上可能安装了更高版本的requests模块,造成运行时报错。可以使用pip-conflict-checker检查版本冲突,卸载不合适的版本,重新安装一个合适的版本。
$ pip install pip-conflict-checker
$ pipconflictchecker
$ pip uninstall requests
$ pip install requests==2.7.0
实际使用操作中使用pip安装的docker-compose可能在执行时还会报代码有bug。
所以推荐直接从github中下载稳定的release版本安装。
$ 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
$ ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
安装htpasswd
因为需要使用nginx提供安全验证的功能,需要一个地方放置用户名和密码对。
使用由httpd-tools提供的htpasswd工具生成用户名密码对。
安装httpd-tools.
$ yum install httpd-tools
三、运行Registry Container并使用Nginx做代理
运行nginx和registry容器
创建一个工作目录,例如/data/programs/docker,并在该目录下创建docker-compose.yml文件,将以下docker-compose.yml内容复制粘贴到你的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目录。
$ mkdir /data/programs/docker -p
$ cd /data/programs/docker
$ mkdir data && mkdir nginx
$ cat /data/programs/docker/docker-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
配置nginx
在nginx目录中创建registry.conf文件配置nginx。配置nginx与registry的关系,转发端口,以及其他nginx的配置选项。复制,粘贴如下内容到你的registry.conf文件中:
$ cat /data/programs/docker/nginx/registry.conf
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_