docker搭建带证书的Docker私有仓库

in docker with 0 comment

<span style="color: #ff0000;">本文基于centos6.8系统为例</span>
<h3>安装docker</h3>
Docker requires a 64-bit installation regardless of your CentOS version. Also, your kernel must be 3.10 at minimum, which CentOS 7 runs.

//docker需要安装在64位系统且内核版本大于3.10
<h4 id="第一步先看目前的内核版本">第一步,先看目前的内核版本(serverIP 10.0.1.63)</h4>

#uname -r
2.6.32-431.el6.centos.plus.x86_64

<h4 id="第二步导入public-key">第二步,导入public key</h4>

#rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
<h4 id="第三步安装elrepo">第三步,安装ELRepo</h4>
#rpm -Uvh http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm
<h4 id="第四步安装内核">第四步,安装内核</h4> 在yum的ELRepo源中,有mainline(4.6)、long-term(3.10)这2个内核版本,考虑到long-term更稳定,会长期更新,所以选择这个版本。
查看ELRepo源中内核:http://elrepo.org/linux/kernel/el6/x86_64/RPMS/
#yum --enablerepo=elrepo-kernel install kernel-lt -y
<h4 id="第五步编辑grubconf修改grub引导顺序">第五步,编辑grub.conf,修改Grub引导顺序</h4>
#vim /etc/grub.conf 
      "确认刚安装好的内核在哪个位置,然后设置default值(从0开始),一般新安装的内核在第一个位置,所以设置default=0。"

<h4 id="第六步重启查看内核版本号">第六步,重启,查看内核版本号</h4>

#uname -r
<h4 id="第六步重启查看内核版本号">第七步,安装docker</h4>
#yum update
#yum install -y epel-release 
#yum install -y docker-io 
#service docker start #docker --version 
#chkconfig --add docker //设置开机启动 
#chkconfig docker on

<h3>创建仓库证书</h3>
Docker安装完成之后,需要为Docker私有仓库创建两个目录。

docker_registry_certs用于存放Docker私有仓库的证书,docker_registry_images用于存放Docker私有仓库中存放的镜像,建议镜像目录空间预留大一些。

#mkdir -p /docker/docker_registry_certs
#mkdir -p /docker/docker_registry_images

通过openssl生成私钥,文件名为registry.key

#cd/docker/docker_registry_certs
#openssl genrsa -out registry.key 2048
#chmod 600 registry.key

得到私钥文件之后,下面用这个私钥来生成证书,首先为证书配置一些基本的注册信息。

# SRV_Country="CN"
# SRV_State="Shanghai"
# SRV_Location="Shanghai"
# SRV_Organization="youxun"
# SRV_OrganizationalUnit="Docker"
# SRV_CommonName="10.0.1.63"                //仓库IP地址

SRV_CommonName这个配置项,如果公司有自己的域名,可以指定域名,这样会便利一些,如果没有的话,就直接用Docker私有仓库的ip地址。对于使用ip地址作为SRV_CommonName的情况,还需要编辑一下openssl的配置文件,本例就是用的ip地址,所以往下看,只用域名的话,可以跳过下面这段。

编辑/etc/pki/tls/openssl.cnf文件,<span style="color: #ff6600;">[ v3_ca ]下添加subjectAltName=IP:10.0.1.63</span>

# vi /etc/pki/tls/openssl.cnf

[ v3_ca ]

subjectAltName=IP:10.0.1.63

注意  SRV_CommonName使用的是ip,openssl的配置文件没有更改,Docker客户端之后使用生成的证书时候会报错:Get https://xxx:xxx/v1/_ping: x509: cannot validate certificate forxxx because it doesn't contain any IP SANs

准备工作完成之后,下面就来生成证书,命名为registry.crt

#openssl req -new -x 509 -days 7300 -key registry.key -out registry.crt -subj \
"/C=$SRV_Country/ST=$SRV_StATE/L=$SRV_Location/O=$SRV_Organization/OU=$SRV_OrganizationalUnit/CN=$SRV_CommonName" -config /etc/pki/tls/openssl.cnf
# ls
-rw-r--r-- 1 root root 1249 Aug 26 10:20 registry.crt
-rw------- 1 root root 1679 Aug 26 10:07 registry.key

至此,证书已经生成完毕了。
<h4>2.1启动Docker私有仓库容器</h4>

#docker run -d -p 5000:5000 --restart=always --name docker_registry \
-v /docker/docker_registry_images:/var/lib/registry/docker/registry/v2 \
-v /docker/docker_registry_certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key -u root registry:2

说明一下参数的意义:

-v /docker/docker_registry_images:/var/lib/registry/docker/registry/v2

指定Docker镜像存储的路径,将容器宿主机的本地目录/docker/docker_registry_images映射进容器

-v /docker/docker_registry_certs:/certs 将证书存放的目录映射进容器

-eREGISTRY_HTTP_TLS_CERTIFICATE和 -e REGISTRY_HTTP_TLS_KEY 指定的是证书的路径,指的是容器内的路径,在/certs目录下

-e后面跟的一些参数也可用直接通过config.yml,定义完config.yml之后,可以通过以下命令启动Docker私有仓库容器。

# docker run -d -p 5000:5000 --restart=always --name=registry  -v
pwd /config.yml:/etc/docker/registry/config.yml  registry:2

关于config.yml提供了非常多的自定义配置项,详细可以参考以下链接,非常详细:

https://docs.docker.com/configuration
仓库启动之后,在容器所在宿主机,测试Docker私有仓库是否可用
#docker images
#docker tag registry:2 localhost:5000/registry:2
#docker push localhost:5000/registry:2
#curl -X GET https://localhost:5000/v2/_catalog -k   //使用docker提供的API,查看私有仓库中的镜像列表
  {"repositories":["registry"]}
#curl -X GET https://localhost:5000/v2/registry/tags/list -k   //查看镜像详细信息
  {"name":"registry","tags":["2"]}

至此,Docker私有仓库的容器启动完成了。
<h4>2.2客户端如何使用Docker私有仓库容器(client IP:10.0.1.60)</h4>
在客户端容器的宿主机上,创建一个以先前创建证书是CN所赋的值命名的目录

#mkdir -p /etc/docker/certs.d/10.0.1.63:5000/
将先前生成的证书文件registry.crt,拷贝到客户端容器宿主机上/etc/docker/certs.d/10.0.1.63目录下,并更名为ca.crt
#cd /etc/docker/certs.d/10.0.1.63
#mv registry.crt ca.crt

<span style="color: #ff9900;">注意  添加完证书之后,需要重启Docker服务:service docker restart</span>

查看私有仓库中的镜像列表信息:

[root@localhost ~]# curl -X GET https://localhost:5000/v2/_catalog -k 
     {"repositories":["registry"]}
[root@localhost ~]# curl -X GET https://localhost:5000/v2/registry/tags/list -k //查看镜像详细信息 
     {"name":"registry","tags":["2"]}

从Docker私有仓库拉镜像

[root@localhost ~]# docker pull 10.0.1.63:5000/registry:2
上传镜像到Docker私有仓库
[root@localhost ~]# docker push 10.0.1.63:5000/test:1
The push refers to a repository [10.0.1.63:5000/test] (len: 1)
3690474eb5b4: Image already exists 
Digest: sha256:f351eaebb303b698acecbb599cc0ea832762ca7b0de408c27079c54ad19ae726

<h3>搭建需证书加用户名密码认证的Docker私有仓库</h3>
在2的基础上,在加上用户名和密码认证,首先需要创建一个包含用户和密码的文件(10.0.1.63)

#mkdir -p /docker/docker_registry_auth
#cd /docker/docker_registry_auth
#docker run --entrypoint htpasswd registry:2 -Bbn zhangsan 123456 > htpasswd
  //创建了包含用户'zhangsan',密码'123456'

清除之前的docker registry容器,重新启动一个新的

[root@docker01 docker_registry_auth]# docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                    NAMES
478aaa6c2563        registry:2          "/entrypoint.sh /etc   3 hours ago         Up 3 hours          0.0.0.0:5000->5000/tcp   docker_registry     
[root@docker01 docker_registry_auth]# docker stop 478a
478a
[root@docker01 docker_registry_auth]#docker run -d -p 5000:5000 --restart=always --name=docker_registry_user_pass \
> -v /docker/docker_registry_images:/var/lib/registry/docker/registry/v2 \
> -v /docker/docker_registry_auth:/auth \
> -e "REGISTRY_AUTH=htpasswd" \
> -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
> -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
> -v /docker/docker_registry_certs:/certs \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \
> -u root registry:2
e9c71a2eb4a4adfce20aed0ed276d58858729bbb2e3fad50d92a6003a713b63c

此时在客户端,push镜像之前就需要先登录(10.0.1.60)

[root@localhost ~]# docker login 10.0.1.63:5000    //登陆仓库
Username: zhangsan
Password: 
Email: 
WARNING: login credentials saved in /root/.docker/config.json
Login Succeeded
[root@localhost ~]# docker pull 10.0.1.63:5000/test:1
1: Pulling from 10.0.1.63:5000/test
3690474eb5b4: Already exists 
Digest: sha256:f351eaebb303b698acecbb599cc0ea832762ca7b0de408c27079c54ad19ae726
Status: Image is up to date for 10.0.1.63:5000/test:1
[root@localhost ~]# docker logout 10.0.1.63:5000             //退出登陆
Remove login credentials for 10.0.1.63:5000
[root@localhost ~]# docker pull 10.0.1.63:5000/registry:2    //再执行pull失败
Pulling repository 10.0.1.63:5000/registry
Error: image registry:2 not found

使用curl 获取镜像列表是需要添加用户名和密码否则会报错

[root@localhost ~]# curl -u zhangsan:123456 -X GET https://10.0.1.63:5000/v2/_catalog -k
{"repositories":["registry","test"]}
[root@localhost ~]# curl -X GET https://10.0.1.63:5000/v2/_catalog -k
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Name":"catalog","Action":"*"}]}]}

文章参考:https://mp.weixin.qq.com/s?__biz=MzAxOTAzMDEwMA==&;mid=2652500554&idx=1&sn=03d5a0b2b178b3160489487c586e271f&scene=0#rd

Responses