本教程使用操作系统 CentOS7 .
如果本机还未安装docker,可通过以下方式快捷安装(为了最大程度保证一致性,此处指定版本):
yum -y install docker-1.12.6-28.git1398f24.el7.centos.x86_64
#启动 docker
systemctl start docker
# 设置为开机启动
systemctl enable docker
查看docker版本,确认安装结果:
[root@localhost ~]#docker -v
Docker version 1.12.6, build 1398f24/1.12.6
无认证仓库且不使用安全链接非常简单,只需要在服务端拉取一个registry镜像,然后用docker run运行,客户端再进行简单配置即可。
拉取私有仓库镜像:
docker pull registry:2.5
启动一个registry仓库容器:
docker run -d --restart=always –privileged=true \
--name registry -p 5000:5000 \
-v /opt/data/registry:/var/lib/registry \
docker.io/registry:2
- –restart=always 此模式容器会跟 docker daemon会随着docker服务的重启而自动恢复
- -v /opt/data/registry:/var/lib/registry 把本地磁盘挂载到容器磁盘/var/lib/registry(默认情况下仓库存放镜像于容器内的/var/lib/registry目录下)
- –name myregistry 定义容器名
- -p 5000:5000 端口映射,本地端口5000映射到容器端口5000
- –-privileged=true :配置了-v /opt/data/registry:/var/lib/registry ,如果没有关闭安全模块selinux,容器将没有权限访问本地目录,设置此参数可以给容器加特权。如果没有关闭selinux以及没有加上此参数,上传传镜像时可能会报权限错误(OSError: [Errno 13] Permission denied: ‘/var/lib/registry/repositories/library’)或者(Received unexpected HTTP status: 500 Internal Server Error)错误
防火墙开放5000端口:
firewall-cmd --zone=public --add-port=5000/tcp --permanent
firewall-cmd --zone=public --add-port=5000/udp --permanent
firewall-cmd --reload
(ps:客户端可以是运行仓库的同一台机,以下全文皆是)
docker1.3.2版本开始,默认使用https连接,因为上面启动时并没有进行证书配置,在需要连接该私有仓库的每个客户端docker宿主机上都必须更改配置项,使客户端使用HTTP连接请求仓库。不同的系统配置方式可能存在差异,此处列举常见的系统配置,其余系统请自行搜索尝试。
步骤:
修改配置,CentOS配置文件路径: /etc/sysconfig/docker
# vim /etc/sysconfig/docker
增加启动选项(在后面追加),。
# OPTIONS='--insecure-registry 10.20.26.52:5000' #CentOS 7系统
# other_args='--insecure-registry 10.20.26.52:5000' #CentOS 6系统
添加后重启docker
Ubuntu下配置文件路径:/etc/init/docker.conf
Redhat7系统,需在文件/etc/systemd/system/docker.service.d/docker.conf(没有则新增),配置如下内容:
[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon -H fd:// --insecure-registry=10.20.26.52:5000
保存修改后,重启
[root@localhost /]# systemctl daemon-reload
[root@localhost /]# service docker restart
步骤:
使用 docker ssh 登陆到 boot2docker 虚拟机
# docker ssh
使用 命令修改配置文件,
# sudo vi /var/lib/boot2docker/profile
在文件最后增加一行:
# EXTRA_ARGS="--insecure-registry 10.20.26.52:5000"
退出该虚拟机并重启
# docker-machine restart
配置完成后,使用docker login 验证是否可以访问(因为没有配置用户,提示用户时任意输入都可以登录成功):
[root@server registry]# docker login 127.0.0.1:5000
Username: 2
Password:
Login Succeeded
如果没有进行以上配置,客户端登录或者连接将会有类似以下提示:
[root@server registry]# docker login 10.20.26.52:5000
Username: 2
Password:
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: http: server gave HTTP response to HTTPS client
此处需要说明的是,提示中虽然提示Get https://127.0.0.1:5005/v1/users/ ,似乎访问了registry v1仓库的链接地址。实际上,docker login 操作会依次访问 v2和v1的地址,最后在命令行显示的是最后失败的日志信息。
为了让大家清楚了解登录过程,以下贴出相关日志信息,供参考。
如果没有进行配置时的日志信息(日志来自系统CentOS7):
8月 02 14:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811035053+08:00" level=info msg="Error logging in to v2 endpoint, trying next endpoint: Get https://10.20.23.52:5000/v2/: http: server gave HTTP response to HTTPS client"
8月 02 14:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811306066+08:00" level=info msg="Error logging in to v1 endpoint, trying next endpoint: Get https://10.20.23.52:5000/v1/users/: http: server gave HTTP response to HTTPS client"
8月 02 14:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811320903+08:00" level=error msg="Handler for POST /v1.26/auth returned error: Get https://10.20.23.52:5000/v1/users/: http: server gave HTTP response to HTTPS client"
如果正常配置日志信息(日志来自系统 boot2docker):
time="2018-08-02T09:38:43.975291248Z" level=debug msg="Calling GET /_ping"
time="2018-08-02T09:38:43.975756760Z" level=debug msg="Calling GET /v1.28/info"
time="2018-08-02T09:38:45.603555104Z" level=debug msg="Calling POST /v1.28/auth"
time="2018-08-02T09:38:45.603621065Z" level=debug msg="form data: {\"password\":\"*****\",\"serveraddress\":\"10.20.26.52:5000\",\"username\":\"2\"}"
time="2018-08-02T09:38:45.603676682Z" level=debug msg="attempting v2 login to registry endpoint https://10.20.26.52:5000/v2/"
time="2018-08-02T09:38:45.640464885Z" level=info msg="Error logging in to v2 endpoint, trying next endpoint: Get https://10.20.26.52:5000/v2/: http: server gave HTTP response to HTTPS client"
time="2018-08-02T09:38:45.640546495Z" level=debug msg="attempting v2 login to registry endpoint http://10.20.26.52:5000/v2/"
docker1.3.2版本开始,使用registry时,默认使用TLS保证数据安全传输。下面将演示如何安装一个使用安全链接的registry。
第一步:生成证书
证书可以去认证机构购买签名证书,此处我们使用openssl生成证书。
一般情况下,证书只支持域名访问,要使其支持IP地址访问,需要修改配置文件openssl配置文件,再进行证书生成。
在CentOS7系统中,文件存储位置为/etc/pki/tls/openssl.cnf。在其中的[ v3_ca]部分,添加subjectAltName选项(填入操作机实际IP):
[ v3_ca ]
subjectAltName = IP:10.20.26.52
修改配置后,生成自签名的证书:
mkdir -p /opt/docker/registry/certs
openssl req -x509 -days 3650 -nodes -newkey rsa:2048 \
-keyout /opt/docker/registry/certs/domain.key \
-out /opt/docker/registry/certs/domain.crt
...
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:10.20.26.52:5000
Email Address []:
生成时,可以所有操作直接回车,不填写任何信息生成。或在Common Name 里填入仓库将使用IP和端口”10.20.26.52:5000”。
第二步:启动容器
此时的启动参数和上面有所不同,需要指定容器使用证书相关路径信息:
mkdir /opt/docker/registry/certs/data
docker run -d \
--name repo --restart=always \
-v /opt/docker/registry/data:/var/lib/registry \
-u root \
-p 5000:5000 \
-v /opt/docker/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2.5
此时客户端可以采取两种方式连接客户端,其一是跟上节中一样,配置使用不安全的HTTP连接;其二则是需要将上面第一步中生成的证书,拷贝到dokcer客户端宿主机上。
在没有进行任何配置之前,使用docker login ,将返回类似错误:
[root@server registry]# docker login 10.20.26.52:5000
Username: 33
Password:
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: http: server gave HTTP response to HTTPS client
现在我们在客户端中使用证书,将上面第一步中生成的证书domain.crt拷贝到docker客户端宿主机对应文件夹内。(docker使用的证书默认存储在 /etc/docker/cert.d目录中,按照域名存储匹配)
如果是本机测试,可以使用cp命令 ,如果是不同机器,可以使用scp命令。
cp /opt/docker/registry/certs/domain.crt /etc/docker/certs.d/10.20.26.52:5000/domain.crt
如果是不同机器,可以使用scp命令
sudo scp -r [email protected]:/opt/registry/certs/registry.crt /etc/docker/certs.d/xxx.com:5000/domain.crt
此时,我们就可以使用HTTPS的方式(默认方式)来使用仓库了,使用docker login验证 (再次提示,由于此时没有配置用户,正确反馈为输入任何字符都可以登录成功,如果返回错误信息应该是配置过程出错,请确保目录及配置字符都完全正确)
[root@server registry]docker login 10.20.26.230:5000
Username: 233
Password:
Login Succeeded
这里需要注意,此时用上节不使用安全链接的方式,客户端进行同样配置(–insecure-registry)后是客户端仍然可以对仓库进行任何操作的。此节只是在仓库端加了证书支持客户端使用安全链接,但并不强制客户端一定要使用安全链接(至少在目前版本是这样的)。所以这里这个只是添加证书的仓库,并不能作为权限控制,防止他人非法使用仓库。如果需要保证安全,必须在这个基础上加上其他安全手段。
上面我们安装的都是一个没有权限校验的私库,但很多时候基于安全考虑,都需要给仓库配置权限,下面将讲解如何配置带有权限控制的仓库。
Registry支持三种认证方式(只能同时使用一种):silly、token和htpasswd。
此处我们选择配置使用 htpasswd + TLS 方式
第一步 生成证书
第二步 生成密码凭证
mkdir /opt/docker/registry/certs/data
docker run --entrypoint htpasswd registry:2.5 -Bbn admin admin123 >> /opt/docker/registry/auth/htpasswd
第三步 启动容器
此时对比之前,需要指定鉴权方式的配置并在启动的时候挂载密码目录到容器内auth目录:
docker run -d --privileged=true \
-u root -p 5000:5000 \
--name repo --restart=always \
-v /opt/docker/registry/data:/var/lib/registry \
-v /opt/docker/registry/auth/:/auth/ \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
-v /opt/docker/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2.5
--restart=always 此模式容器会跟 docker daemon会随着docker服务的重启而自动恢复
-v /opt/registry/data:/var/lib/registry
把本地磁盘挂载到容器磁盘/var/lib/registry
(默认情况下仓库存放镜像于容器内的/var/lib/registry目录下)
-v /opt/registry/auth/:/auth/
将密码文件夹挂载到容器/auth文件夹
--name registry 2
定义容器名,方便启动
-p 5000:5000
端口映射,<本地端口>:<容器端口>,本地端口5000映射到容器端口5000
–-privileged=true
此参数容器添加特权,前面将本地目录挂载到容器,
如果本地没有关闭安全模块selinux,容器将没有权限访问本地目录,
如果没有关闭selinux以及没有加上此参数,上传传镜像时可能会报权限错误
OSError: [Errno 13] Permission denied: ‘/var/lib/registry/repositories/library’
或者
Received unexpected HTTP status: 500 Internal Server Error
-e "REGISTRY_AUTH=htpasswd"
配置认证方式为 htpasswd
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"
鉴权范围
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
配置htpasswd认证使用的密码文件路径
-v /opt/registry/certs:/certs
挂载目录
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt
指定证书crt地址
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key
指定证书key地址
到这里,仓库服务配置完成。
第一步 获取安全证书
将上面第一步中生成的证书domain.crt拷贝到docker客户端宿主机对应文件夹内。(docker使用的证书默认存储在 /etc/docker/cert.d目录中,按照域名存储匹配)
如果是本机测试,可以使用cp命令 ,如果是不同机器,可以使用scp命令。
cp /opt/docker/registry/certs/domain.crt /etc/docker/certs.d/10.20.26.52:5000/domain.crt
如果是不同机器,可以使用scp命令
sudo scp -r [email protected]:/opt/registry/certs/registry.crt /etc/docker/certs.d/xxx.com:5000/domain.crt
第二步 使用指定账号登录
此时,我们就可以使用HTTPS的方式(默认方式)来使用仓库。现在我们进行 docker login验证配置,因为在仓库配置的时候,指定了鉴权方式并生成了账户密码。这时候进行 docker login 时,使用非配置的用户将无法登录(返回 401 Unauthorized),只能通过上述配置中 的admin用户和正确的密码进行登录。
[root@server registry]# docker login 10.20.26.52:5000
Username (admin): 3
Password:
Error response from daemon: login attempt to https://10.20.26.230:5000/v2/ failed with status: 401 Unauthorized
[root@server registry]# docker login 10.20.26.52:5000
Username (admin): admin
Password:
Login Succeeded
需要注意的是:
此时仍然可以通过配置(–insecure-registry)不使用安全链接进行登录(当然这时需要使用配置的用户名和密码),不使用安全链接时,用户名和密码将使用明文传输,存在严重安全风险。日常使用应该使用安全链接方式。
异常一:如果客户端没有配置证书,将出现以下错误:
[root@server registry]# docker login 10.20.26.52:5000
Username (admin): admin
Password:
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: x509: certificate signed by unknown authority
异常二:如果证书不匹配或者使用ip证书没有按上述操作配置openssl.cnf,将出现以下错误信息:
[root@server registry]#docker login 10.20.26.52:5000
Username (admin): admin
Password:
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: x509: certificate signed by unknown authority
[root@server registry]#docker login 10.20.26.230:5000
Username (admin): admin
Password:
Error response from daemon: Get https://10.20.26.230:5000/v1/users/: x509: cannot validate certificate for 10.20.26.230 because it doesn't contain any IP SANs
异常三:
容器启动失败会导致无法登陆,表现为 connection refused等。
[root@d3xtserver registry]# docker login 10.20.26.52:5006
Username: admin
Password:
Error response from daemon: Get https://10.20.26.52:5006/v1/users/: dial tcp 10.20.26.52:5006: getsockopt: connection refused
如果出现异常情况,首先排除容器是否正常启动,使用docker ps,查看容器的情况:
[root@d3xtserver registry]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
40a6b1603c1d docker.io/registry:2.5 "/entrypoint.sh /e..." 7 seconds ago Restarting (2) Less than a second ago registry2
3b29b82a169a registry:2.5 "/entrypoint.sh /e..." 22 minutes ago Up 22 minutes 0.0.0.0:5000->5000/tcp repo
如果发现status 为 非正常情况(Restarting … ),则容器启动异常。
导致容器异常的原因有很多,比如 容器配置项错误(检查输入),挂载文件不存在(检查文件)等,请先逐项排查每个配置项及关联配置文件是否正确(存在且格式正确)。也可以通过 查看日志的方式确定问题范围
docker logs <容器名>
私有库搭建好了,我们可以进行一些操作体验一下。
从默认库获取hello-world镜像
docker pull hello-world
在客户机上tag需要上传的镜像
[root@server ~]# docker tag hello-world 10.20.26.52:5000/hello-world
提交(push)镜像
[root@server ~]# docker push 10.20.26.52:5000/hello-world
docker push 10.20.26.52:5000/hello-world
The push refers to a repository [10.20.26.64:5000/hello-world]
45761469c965: Pushed
latest: digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f size: 524
删除本地镜像
[root@server ~]# docker rmi 10.20.26.52:5000/hello-world
Untagged: 10.20.26.52:5000/hello-world:latest
Untagged: 10.20.26.52:5000/hello-world@sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Deleted: sha256:1815c82652c03bfd8644afda26fb184f2ed891d921b20a0703b46768f9755c57
Deleted: sha256:45761469c965421a92a69cc50e92c01e0cfa94fe026cdd1233445ea00e96289a
从私有仓库获取镜像
[root@server ~]# docker pull 10.20.26.52:5000/hello-world
Using default tag: latest
Trying to pull repository 10.20.26.64:5000/hello-world ...
sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f: Pulling from 10.20.26.64:5000/hello-world
b04784fba78d: Pull complete
Digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Status: Downloaded newer image for 10.20.26.64:5000/hello-world:latest
查询仓库镜像
tree /opt/docker/registry/data
访问http接口:
如:
curl http://10.20.26.52:5000/v2/_catalog
{"repositories":["hello-world"]}
curl http://10.20.26.52:5000/v2/image_name/tags/list
{"name":"hello-world","tags":["latest"]}
官方文档:
https://docs.docker.com/registry/
博客:
https://blog.csdn.net/gqtcgq/article/details/51163558