封尘网

让学习成为一种习惯!

Centos7 搭建Docker V2 支持SSL认证

系统环境:
版本:CentOS Linux release 7.2.1511 (Core) 64位
PIP:pip 8.1.2
Docker版本:1.11.2
Docker-compose 版本:1.7.0rc1

实验机器:
主机名 IP地址 用途
test.registry.com 192.168.18.54 Docker 仓库
docker 192.168.18.51 Docker客户端

备注:
仓库主机名配置为域名方便下面创建SSL认证,如果没有DNS解析就直接在/etc/hosts文件添加解析即可。

1、添加Docker官方源;

cat /etc/yum.repos.d/docker.repo<<-EOF
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

2、yum方式安装Docker

yum install docker-engine -y

配置开机启动:

systemctl enable docker

3、安装Docker-compose
Docker-compose是一个非常有用的Docker运行,管理的工具。你可以通过定义compose文件,使用简单的一条命令同时起多个Docker Container运行不同的服务。Docker-compose对于开发,测试,环境保存以及CI都提供了非常大的便利。

Docker-compose是用Python开发的一个工具,所以可以用pip直接安装。

由于Centos7 自带的pip版本有点低,所以要升级一下,不然会报错或无法安装上docker-compose。

pip install --upgrade pip
pip install docker-compose

4、创建一个工作目录用来存放相关配置:

mkdir -p /data/docker/{nginx,data}

进入目录:cd /data/docker

cat >docker-compose.yml<<-EOF
nginx:
  image: "nginx:1.9"                    #使用nginx:1.9的镜像
  ports:
    - 443:443
  links:
    - registry:registry                     #连接一个容器
  volumes:
    - /data/docker/nginx:/etc/nginx/conf.d
registry:
  image: registry:2.2                   #使用registry:2.2镜像
  ports:
    - 127.0.0.1:5000:5000               #此处如果加上了127.0.0.1只允许本地连接5000端口;
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - /opt/docker/data:/data

EOF

说明:

  • 此配置文件定义了两个Container
  • 一个名为nginx使用镜像为:nginx:1.9;映射了443端口到宿主机上,同时连接了另一个容器registry;
  • 并挂载了一个数据卷目录为:/data/docker/nginx挂载到容器中的/etc/nginx/conf.d 目录;
  • 另一个名为registry使用的镜像为:registry:2.2;映射了端口5000到宿主机,并定义了镜像的存储位置:/data

  • 【此目录为容器内的目录】;挂载一个数据卷:/data/docker/data到容器的/data目录;

5、进入nginx目录添加nginx的配置文件:【最终配置】

cat >registry.conf <<-EOF

upstream docker-registry {
  server registry:5000;
}

server {
  listen 443;
  server_name localhost;

  # SSL
   ssl on;
   ssl_certificate /etc/nginx/conf.d/domain.crt;
   ssl_certificate_key /etc/nginx/conf.d/domain.key;

  client_max_body_size 0;

  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.2' 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                  600;
  }
}
EOF

完成上面后可以直接测试一下:

cd /data/docker 【在docker-compose.yml配置文件目录下】

启动容器:

docker-compose up

docker ps -a 可以看到两个容器已经在运行了,如果你没有配置文件中的镜像就会自动下载,很慢的。

如果执行下面命令都是返回{},说明正常;但是此时未没有启动SSL认证;

curl http://localhost:5000/v2/
curl http://localhost:443/v2/

添加用户名和密码,用于SSL登陆认证时使用;
默认系统没有安装:htpasswd

yum install httpd-tools -y

在/data/docker/nginx目录下执行下面命令创建用户名和密码;-c选项只创建一个用户。

htpasswd -c registry.password docker

然后修改Registry.conf文件,取消下面三行的注释。【分解步骤】

auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
add_header 'Docker-Distribution-Api-Version' 'registry/2.2' always;

加入SSL验证

如果你有经过认证机构认证的证书,则直接使用将证书放入nginx目录下即可。如果没有,则使用openssl创建自己的证书。

进行/opt/docker/nginx目录

设置环境变量:localdomain=test.registry.com

生成根证书:

openssl req -nodes -subj "/C=CN/ST=GuangDong/L=DongGuan/CN=$localdomain" -newkey rsa:2048 -keyout $localdomain.key -out $localdomain.csr

openssl x509 -req -days 3650 -in $localdomain.csr -signkey $localdomain.key -out $localdomain.crt

运行Registry

执行docker-compose up -d 在后台运行Registry,并使用curl验证结果。

客户端测试上传镜像:
安装ca-certificates包:

[root@docker ~]# yum install ca-certificates -y

使能动态CA配置功能

update-ca-trust force-enable

将key拷贝到/etc/pki/ca-trust/source/anchors/

【此步在Registry上把文件传过来】

scp test.registry.com.crt 192.168.18.51:/etc/pki/ca-trust/source/anchors/

使新拷贝的证书生效

update-ca-trust extract

证书拷贝后,需要重启docker以保证docker能使用新的证书

service docker restart

需要在/etc/hosts文件中添加域名解析:

echo "test.registry.com   192.168.18.54" >>/etc/hosts

客户端SSL登陆到仓库:

客户端上传镜像:

查看仓库上java镜像列表:【会要求输入用户名和密码】

命令行下查看方法:

查看仓库中保存的镜像:
方法一:【5000端口】

[root@test nginx]# curl test.registry.com:5000/v2/_catalog
{"repositories":["java","registry"]}

WEB查看:

http://test.registry.com:5000/v2/_catalog

方法二:【SSL认证】

[root@test nginx]# curl -k https://docker:123456@test.registry.com:443/v2/_catalog

{"repositories":["java","registry"]}

说明仓库中保存了两个镜像:java和registry

查看仓库中镜像有哪几个版本:

http://test.registry.com:5000/v2/registry/tags/list
[root@test nginx]# curl test.registry.com:5000/v2/registry/tags/list
{"name":"registry","tags":["latest","v3"]}

[root@test nginx]# curl -k https://docker:123456@test.registry.com:443/v2/registry/tags/list
{"name":"registry","tags":["latest","v3"]}

查看仓库中镜像的详细信息:

curl http://test.registry.com:5000/v2/registry/manifests/v3

registry:为镜像名
v3:为该镜像的版本号