文章目录
- 部署拓扑
- 准备宿主机
- 创建SSL证书和用户认证文件
- 安装Docker环境
- 打开防火墙
- 安装Docker Registry
- 基于容器安装运行Docker Registry
- 基于软件包安装运行Docker Registry
- 容器操作
- 连通性验证
- 本地宿主机验证
- 远程宿主机验证
- 镜像推拉验证
- Docker Registry操作
- 查看Docker Registry保存的镜像
- 从Docker Registry中删除镜像
- 停止Docker Registry
- 一些常见问题
- 参考
部署拓扑
为了运行Registry并进行验证,建议在以下两个宿主机分别运行Docker客户端和包含Registry的容器(或运行Docker-Distribution软件)。
准备宿主机
创建SSL证书和用户认证文件
在运行Registry的宿主机上完成本节的操作。
- 确定环境变量。其中REGISTRY_DOMAIN的是运行Registry服务的宿主机的有效域名(假设宿主机域名是registry.domain.com)。
$ REGISTRY_PATH=/data/registry
$ DOMAIN=domain.com
$ REGISTRY_DOMAIN=registry.${DOMAIN}
- 创建Registry使用目录,其中auth是用来存放校验用户名/密码的文件目录、certs是用来存放TLS所需证书/秘钥的目录、data是用来存放容器镜像的目录。
$ mkdir -p ${REGISTRY_PATH}/{auth,certs,data}
- 执行命令创建证书(包括公钥和私钥文件),以支持Registry运行在HTTPs上。其中CN必须是运行Registry服务的宿主机的有效域名。
$ openssl req -newkey rsa:4096 -nodes -sha256 -keyout ${REGISTRY_PATH}/certs/registry.key -x509 -days 365 \
-out ${REGISTRY_PATH}/certs/registry.crt \
-subj "/C=CN/ST=BEIJING/L=BJ/O=REDHAT/OU=IT/CN=${REGISTRY_DOMAIN}/emailAddress=admin@${DOMAIN}"
- 查看证书。
$ openssl x509 -in ${REGISTRY_PATH}/certs/registry.crt -text | head -n 14
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
c2:02:34:f6:e0:55:14:8f
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=CN, ST=BEIJING, L=BJ, O=REDHAT, OU=IT, CN=registry.domain.com/emailAddress=admin@domain.com
Validity
Not Before: Jun 28 04:37:54 2020 GMT
Not After : Jun 28 04:37:54 2021 GMT
Subject: C=CN, ST=BEIJING, L=BJ, O=REDHAT, OU=IT, CN=registry.domain.com/emailAddress=admin@domain.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
- 创建基于httppasswd的用户认证文件,其中的user1/password1是登录用户和密码。
$ yum -y install httpd-tools
$ htpasswd -bBc ${REGISTRY_PATH}/auth/htpasswd user1 password1
$ cat ${REGISTRY_PATH}/auth/htpasswd
user1:$2y$05$i5UFQBVopBbZsXJ6sG0SoOw1krIa9YU/5IjAPjKAsSUd5dssU5yTe
安装Docker环境
安装Docker客户端,然后启动它。
$ yum -y install docker
$ systemctl start docker
打开防火墙
为了能在其它节点远程访问registry.domain.com节点运行的Container Registry服务,要确保关闭Registry宿主机节点的防火墙,或执行以下命令打开节点防火墙的5000端口。
$ firewall-cmd --permanent --add-port=5000/tcp
$ firewall-cmd --reload
$ firewall-cmd --query-port=5000/tcp
安装Docker Registry
基于容器安装运行Docker Registry
- 运行Registry镜像,并将容器中/var/lib/registry目录挂到宿主机的/data/registry/data目录上。同时配置跟随Docker服务启动自动Registry容器。
$ docker run --name registry -p 5000:5000 \
-v ${REGISTRY_PATH}/data:/var/lib/registry:z \
-v ${REGISTRY_PATH}/auth:/auth:z \
-v ${REGISTRY_PATH}/certs:/certs:z \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \
-d docker.io/library/registry:2
Unable to find image 'registry:2' locally
Trying to pull repository registry.access.redhat.com/registry ...
Pulling repository registry.access.redhat.com/registry
Trying to pull repository registry.fedoraproject.org/registry ...
Pulling repository registry.fedoraproject.org/registry
Trying to pull repository registry.centos.org/registry ...
Pulling repository registry.centos.org/registry
Trying to pull repository docker.io/library/registry ...
2: Pulling from docker.io/library/registry
cbdbe7a5bc2a: Pull complete
47112e65547d: Pull complete
46bcb632e506: Pull complete
c1cc712bcecd: Pull complete
3db6272dcbfa: Pull complete
Digest: sha256:8be26f81ffea54106bae012c6f349df70f4d5e7e2ec01b143c46e2c03b9e551d
Status: Downloaded newer image for docker.io/registry:2
8940dc961afeeb5d8a9ffa52915fca038f2c1156b1b59f2ae81aad064134b93b
- 查看运行Registry的容器。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
79906ce6b19b docker.io/library/registry:2 "/entrypoint.sh /e..." 2 hours ago Up 2 hours 0.0.0.0:5000->5000/tcp registry
注意:如果还想在相同的宿主机上完成“基于软件包安装运行”章节操作,需要先运行以下命令停掉Registry容器以释放5000端口。
$ docker stop registry
$ docker rm registry
基于软件包安装运行Docker Registry
- 如果是RHEL,需要先用“subscription-manager repos --enable=rhel-7-server-extras-rpms”命令打开名为rhel-7-server-extras-rpms的Yum Reop。也可以执行以下命令,使用CentOS的YUM源创建Repo配置文件。
$ cat > /etc/yum.repos.d/docker.repo << EOF
[extras]
name=CentOS 7 - Extras
baseurl=http://mirrors.163.com/centos/7/extras/x86_64
gpgcheck=0
EOF
- 在配置完docker-distribution用到的Yum后,就可以执行以下操作安装docker-distribution和httpd-tools。注意:要确保“/data/registry”目录存在,并且“registry.domain.com”文本机域名或主机名。
$ sudo -i
$ yum -y install docker-distribution
- 修改/etc/docker-distribution/registry/config.yml文件。为了允许该删除镜像,可将“storage.delete.enabled”设为true。
version: 0.1
log:
fields:
service: registry
storage:
cache:
layerinfo: inmemory
filesystem:
rootdirectory: /data/registry/data
delete:
enabled: true
auth:
htpasswd:
realm: basic-realm
path: /data/registry/auth/htpasswd
http:
addr: 0.0.0.0:5000
host: https://registry.domain.com:5000
tls:
certificate: /data/registry/certs/registry.crt
key: /data/registry/certs/registry.key
- 启动docker-distribution服务,然后查看其服务启动状态。
$ systemctl restart docker-distribution
$ systemctl status docker-distribution
● docker-distribution.service - v2 Registry server for Docker
Loaded: loaded (/usr/lib/systemd/system/docker-distribution.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2020-07-07 01:13:06 EDT; 37s ago
Main PID: 10252 (registry)
CGroup: /system.slice/docker-distribution.service
└─10252 /usr/bin/registry serve /etc/docker-distribution/registry/config.yml
Jul 07 01:13:06 registry systemd[1]: Stopped v2 Registry server for Docker.
Jul 07 01:13:06 registry systemd[1]: Started v2 Registry server for Docker.
Jul 07 01:13:06 registry registry[10252]: time="2020-07-07T01:13:06-04:00" level=info msg="Starting upload purge in 5m0s" go.version=go1.9.2 instance....+unknown"
Jul 07 01:13:06 registry registry[10252]: time="2020-07-07T01:13:06-04:00" level=warning msg="No HTTP secret provided - generated random secret. This may cause...
Jul 07 01:13:06 registry registry[10252]: time="2020-07-07T01:13:06-04:00" level=info msg="redis not configured" go.version=go1.9.2 instance.id=b07fc7...+unknown"
Jul 07 01:13:06 registry registry[10252]: time="2020-07-07T01:13:06-04:00" level=info msg="using inmemory blob descriptor cache" go.version=go1.9.2 in...+unknown"
Jul 07 01:13:06 registry registry[10252]: time="2020-07-07T01:13:06-04:00" level=info msg="listening on [::]:5000, tls" go.version=go1.9.2 instance.id...+unknown"
Hint: Some lines were ellipsized, use -l to show in full.
容器操作
连通性验证
本地宿主机验证
- 在安装docker-registry的本地宿主机执行命令,将公钥证书保存到系统缺省目录。
$ cp ${REGISTRY_PATH}/certs/registry.crt /etc/pki/ca-trust/source/anchors/
$ update-ca-trust
- 在运行Registry的宿主机上执行命令,从本地访问docker-distribution,查看其上的repositories。
$ curl -u user1:password1 https://${REGISTRY_DOMAIN}:5000/v2/_catalog
{"repositories":[]}
- 在运行Registry的宿主机上执行命令登录Registry。
$ docker login ${REGISTRY_DOMAIN}:5000 -u user1 -p password1
远程宿主机验证
- 为了能通过SSL访问Registry服务,需将公钥证书到复制客户端宿主机。在远程客户宿主机上执行以下命令:
$ REGISTRY_PATH=/data/registry
$ DOMAIN=domain.com
$ REGISTRY_DOMAIN=registry.${DOMAIN}
$ scp root@${REGISTRY_DOMAIN}:${REGISTRY_PATH}/certs/registry.crt /etc/pki/ca-trust/source/anchors/
$ update-ca-trust
- 在远程客户宿主机上安装Docker,然后启动它。
$ yum -y install docker
$ systemctl start docker
- 在远程客户宿主机上执行以下命令,查看远程节点上的镜像repositories。
$ curl -u user1:password1 https://${REGISTRY_DOMAIN}:5000/v2/_catalog
{"repositories":[]}
- 在远程客户宿主机上执行命令登录Registry。
$ docker login ${REGISTRY_DOMAIN}:5000 -u user1 -p password1
镜像推拉验证
以下操作在Registry服务的本地节点或远程节点均可执行。
- 查看docker的配置文件,确认其中在‘[registries.search]’区域中包括‘docker.io’。
$ more /etc/containers/registries.conf | grep registries.search -A1
[registries.search]
registries = ['docker.io', 'registry.fedoraproject.org', 'quay.io', 'registry.access.redhat.com', 'registry.centos.org']
- 将busybox镜像从docker.io拉到本地缓存。
$ docker pull busybox
Using default tag: latest
Trying to pull repository docker.io/library/busybox ...
latest: Pulling from docker.io/library/busybox
76df9210b28c: Pull complete
Digest: sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209
Status: Downloaded newer image for docker.io/busybox:latest
- 查看本地缓存镜像。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/busybox latest 1c35c4412082 3 weeks ago 1.22 MB
- 对本地busybox镜像重新打标签。
$ docker tag docker.io/busybox ${REGISTRY_DOMAIN}:5000/busybox
- 再次查看本地缓存镜像。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/busybox latest 1c35c4412082 3 weeks ago 1.22 MB
registry.domain.com:5000/busybox latest 1c35c4412082 3 weeks ago 1.22 MB
- 将本地缓存中的registry.domain.com:5000/busybox镜像推至Registry上。
$ docker push ${REGISTRY_DOMAIN}:5000/busybox
The push refers to a repository [registry.domain.com:5000/busybox]
- 执行命令,确认registry.domain.com:5000上已经有busybox的Repository。
$ curl -u user1:password1 https://${REGISTRY_DOMAIN}:5000/v2/_catalog
{"repositories":["busybox"]}
$ curl -XGET -u user1:password1 https://${REGISTRY_DOMAIN}:5000/v2/busybox/tags/list
{"name":"busybox","tags":["latest"]}
- 从本地缓存中删除所有busybox镜像。
$ docker image remove docker.io/busybox:latest
Untagged: docker.io/busybox:latest
Untagged: docker.io/busybox@sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209
$ docker image remove ${REGISTRY_DOMAIN}:5000/busybox:latest
Untagged: registry.domain.com:5000/busybox:latest
Untagged: registry.domain.com:5000/busybox@sha256:fd4a8673d0344c3a7f427fe4440d4b8dfd4fa59cfabbd9098f9eb0cb4ba905d0
Deleted: sha256:1c35c441208254cb7c3844ba95a96485388cef9ccc0646d562c7fc026e04c807
Deleted: sha256:1be74353c3d0fd55fb5638a52953e6f1bc441e5b1710921db9ec2aa202725569
- 执行命令,确认本地缓存中已经没有镜像了
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
- 从本地Docker Registry上拉取busybox镜像。
$ docker pull ${REGISTRY_DOMAIN}:5000/busybox:latest
Trying to pull repository registry.domain.com:5000/busybox ...
latest: Pulling from registry.domain.com:5000/busybox
76df9210b28c: Pull complete
Digest: sha256:fd4a8673d0344c3a7f427fe4440d4b8dfd4fa59cfabbd9098f9eb0cb4ba905d0
Status: Downloaded newer image for registry.domain.com:5000/busybox:latest
- 确认本地缓存中有了registry.domain.com:5000/busybox镜像。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.domain.com:5000/busybox latest 1c35c4412082 3 weeks ago 1.22 MB
Docker Registry操作
本节操作都在Registry宿主机上完成。
查看Docker Registry保存的镜像
- 查看docker-distribution在本地保存的镜像。
$ export REGISTRY_DATA_DIR=${REGISTRY_PATH}/data/docker/registry/v2
$ ll ${REGISTRY_DATA_DIR}/repositories
drwxr-xr-x. 5 root root 55 Jun 28 12:44 busybox
从Docker Registry中删除镜像
- 下载删除Registry中镜像的脚本。
$ curl -L https://raw.githubusercontent.com/burnettk/delete-docker-registry-image/master/delete_docker_registry_image.py -o /usr/local/bin/delete_docker_registry_image
$ chmod +x /usr/local/bin/delete_docker_registry_image
- 确认Docker镜像保存的目录。
$ echo ${REGISTRY_DATA_DIR}
/data/registry/data/docker/registry/v2/
- 执行命令,删除busybox镜像。
$ delete_docker_registry_image --image busybox
- 验证镜像已经从Docker Registry上被删除
$ curl -u user1:password1 https://${REGISTRY_DOMAIN}:5000/v2/_catalog
{"repositories":[]}
- 验证在本地存储中已经没有了保存busybox镜像用到的目录。
$ ll ${REGISTRY_DATA_DIR}/repositories
total 0
停止Docker Registry
- 如果是以容器方式运行Registry,可执行以下命令停掉Registry容器运行。
$ docker container stop registry
$ docker container rm -v registry
- 如果Docker Registry是在宿主机上直接运行,执行以下命令停掉该服务运行。
$ systemctl stop docker-distribution
一些常见问题
- 证书不匹配错误。例如当Container Registry所运行的宿主机有多个域名的时候(例如域名分别为registry,domain.com、registry.com),此时如果没有使用Docker-Distribution所用证书中的域名(即证书中使用的registry,domain.com域名)访问它,那么会出现以下错误:
$ curl -u user1:password1 https://registry.com:5000/v2/_catalog
curl: (51) Unable to communicate securely with peer: requested domain name does not match the server's certificate.
$ docker login registry.com:5000 -u user1 -p password1
Error response from daemon: Get https://registry.com:5000/v1/users/: x509: certificate is valid for registry.domain.com, not registry.com
Action:必须使用Docker-Distribution所用证书中的域名。
$ curl -u user1:password1 https://registry.domain.com:5000/v2/_catalog
{"repositories":[]}
$ docker login registry.domain.com:5000 -u user1 -p password1
Login Succeeded