Docker Registry作为Docker的核心组件之一负责镜像内容的存储与分发。客户端的docker pull以及push命令都将直接与registry进行交互,最初版本的registry 由Python实现,由于设计初期在安全性,性能以及API的设计上有着诸多的缺陷,该版本在0.9之后停止了开发,由新的项目distribution(新的docker register被称为Distribution)来重新设计并开发下一代registry。
新的项目由go语言开发,所有的API,底层存储方式,系统架构都进行了全面的重新设计已解决上一代registry中存在的问题,2016年4月份rgistry 2.0正式发布,docker 1.6版本开始支持registry 2.0,而八月份随着docker 1.8 发布,docker hub正式启用2.1版本registry全面替代之前版本registry,新版registry对镜像存储格式进行了重新设计并和旧版不兼容,docker 1.5和之前的版本无法读取2.0的镜像。
另外,Registry2.4版本之后支持了回收站机制,也就是可以删除镜像了,在2.4版本之前是无法支持删除镜像的,所以如果你要使用最好是大于Registry2.4版本的,目前最新版本为2.7.x。
官方文档地址:https://docs.docker.com/registry/
官方github地址:https://github.com/docker/distribution
搭建单机版仓库(https)
创建凭据存储目录
[root@mysql ~]# mkdir auth certs
## 创建生成证书索引数据库文件
[root@mysql ~]# touch /etc/pki/CA/index.txt
## 指定第一个颁发证书的序列号
[root@mysql ~]# echo 01 > /etc/pki/CA/serial
## 生成私钥
# (umask 066; openssl genrsa -out /etc/pki/tls/private/dker-registry.key 4096)
## 申请证书文件
# openssl req -new -key /etc/pki/tls/private/dker-registry.key -days 365 -out /etc/pki/tls/dker-registry.csr
## 签署证书
# openssl ca -in /etc/pki/tls/dker-registry.csr -out /etc/pki/CA/certs/docker-reg.crt -days 365
注意:默认国家,省,公司名称三项必须和CA一致,Common Name就是证书签发的地址(即:仓库地址,如果是域名,需要添加DNS解析的)
# mv /etc/pki/CA/certs/docker-reg.crt certs/
# mv /etc/pki/tls/private/dker-registry.key ~/certs/
创建用户和凭据
[root@mysql ~]# docker run --entrypoint htpasswd httpd:2 -Bbn testuser testpassword > auth/htpasswd
启动registery
查看证书目录
[root@mysql ~]# ll auth/ certs/
auth/:
total 4
-rw------- 1 root root 67 Jul 5 14:06 htpasswd
certs/:
total 12
-rw------- 1 root root 3243 Jul 7 21:28 dker-registry.key
-rw-r--r-- 1 root root 7294 Jul 7 21:36 docker-reg.crt
启动容器
[root@mysql ~]# docker run -d \
> -p 5000:5000 \
> --restart=always \
> --name registry \
> -v "$(pwd)"/auth:/auth \
> -e "REGISTRY_AUTH=htpasswd" \
> -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
> -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
> -v "$(pwd)"/certs:/certs \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/docker-reg.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/dker-registry.key \
> registry:2
查看启动的容器
[root@mysql ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d75e6dc66de4 registry:2 "/entrypoint.sh /etc…" 5 minutes ago Up 5 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
[root@mysql ~]# ss -lntp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:* users:(("sshd",pid=858,fd=3))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=1010,fd=13))
LISTEN 0 4096 *:5000 *:* users:(("docker-proxy",pid=2192,fd=4))
LISTEN 0 128 :::22 :::* users:(("sshd",pid=858,fd=4))
LISTEN 0 100 ::1:25 :::* users:(("master",pid=1010,fd=14))
LISTEN 0 4096 :::5000 :::* users:(("docker-proxy",pid=2196,fd=4))
添加信任仓库
[root@mysql ~]# vim /lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket containerd.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=zhanghao:443
或者在/etc/docker/daemon.json文件中添加
[root@apache ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://05eotbde.mirror.aliyuncs.com"],
"insecure-registries": ["zhanghao:443"]
}
重启docker
[root@mysql ~]# systemctl daemon-reload
[root@mysql ~]# systemctl restart docker
上传镜像到镜像仓库
# 从官方镜像仓库拉取镜像
[root@mysql ~]# docker pull ubuntu:16.04
# 给镜像打标
[root@mysql ~]# docker tag ubuntu:16.04 zhanghao:443/my-ubuntu
# 登录仓库
[root@mysql ~]# docker login -u test zhanghao:443
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
# 上传镜像到镜像仓库
[root@mysql ~]# docker push zhanghao:443/my-ubuntu
Using default tag: latest
注意:镜像仓库登录的时候,加密的密码信息写在了如下文件
[root@docker01 src]# cat /root/.docker/config.json
{
"auths": {
"mytest.harbor.com": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
},
"mytest.harbor.com:80": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/18.09.9 (linux)"
}
另一台服务器拉取镜像仓库中的镜像
[root@apache ~]# docker pull zhanghao:443/my-ubuntu
Using default tag: latest
latest: Pulling from my-ubuntu
61e03ba1d414: Pull complete
4afb39f216bd: Pull complete
e489abdc9f90: Pull complete
999fff7bcc24: Pull complete
Digest: sha256:114bbce1997fa476da56c3958cb3ca13269a54b0a97dfd3667543c7778287bf2
Status: Downloaded newer image for zhanghao:443/my-ubuntu:latest
在客户端查看仓库中的所有镜像
[root@apache ~]# curl -u test -k https://zhanghao:443/v2/_catalog
Enter host password for user 'test':
{"repositories":["my-ubuntu"]}
网页中访问
注意
[root@docker01 src]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://05eotbde.mirror.aliyuncs.com"],
"insecure-registries": ["zhanghao:443","mytest.harbor.com"]
}
如果镜像仓库配置的时候写了端口,那么登录和打标记的时候也要加上端口,否则找不到仓库和镜像
[root@docker01 src]# systemctl restart docker
[root@docker01 src]# docker login -u admin http://mytest.harbor.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
登录加端口的情况
[root@docker01 src]# docker login -u admin http://mytest.harbor.com:80
Password:
Error response from daemon: Get https://mytest.harbor.com:80/v2/: http: server gave HTTP response to HTTPS client
测试打标和推送镜像
[root@docker01 src]# docker tag nginx:1.16.1-alpine mytest.harbor.com/test/nginx:1.16.1-alpine
[root@docker01 src]# docker push mytest.harbor.com/test/nginx:1.16.1-alpine
The push refers to repository [mytest.harbor.com/test/nginx]
08065237b498: Layer already exists
531743b7098c: Layer already exists
1.16.1-alpine: digest: sha256:0dfc8450deb8c7f06fbaac27e453ac3262df7d3a93639c4e2f48ee39434ec017 size: 739
加端口的情况
[root@docker01 src]# docker push mytest.harbor.com:80/test/nginx:test
The push refers to repository [mytest.harbor.com:80/test/nginx]
Get https://mytest.harbor.com:80/v2/: http: server gave HTTP response to HTTPS client