Docker Registry 私有仓库

搭建私有仓库

拉取 Docker Registry:2 的镜像

docker pull registry:2

运行容器

docker run -d -p 5000:5000 --restart=always --name registry registry:2

修改镜像标签,并将容器上传至私有仓库

docker tag nginx:my <registry_ip>/nginx:my
docker push <registry_ip>:5000/nginx

若上传时出现下列提示,则需要进一步的配置

The push refers to repository [<registry_ip>:5000/nginx]
Get https://<registry_ip>:5000/v2/: http: server gave HTTP response to HTTPS client

修改/etc/docker/daemon.json文件,在文件中添加

{
  "insecure-registries": ["<registry_ip>:5000"]
}

重新加载配置文件,并重启 docker 服务

sudo systemctl daemon-reload
sudo systemctl restart docker

重新上传镜像即可,上传完毕后查看仓库

curl http://<registry_ip>:5000/v2/_catalog

可以查看到刚才上传的镜像

{"repositories":["nginx"]}

至此简单的私有仓库搭建完毕

私有仓库的 TLS 加密

首先删除之前运行的仓库容器

docker rm -f <container_id>

配置主机名解析,在/etc/hosts文件中新增下列配置

<ip> myregistry.com

创建存放加密证书的目录

mkdir -p /root/registry/certs
cd /root/registry

生成加密证书(注意,生成证书时 Common Name 项应与主机名解析中配置的相同)

openssl req -newkey rsa:4096 \
-nodes \
-sha256 \
-keyout certs/myregistry.com.key \
-x509 \
-days 365 \
-out certs/myregistry.com.crt
Generating a 4096 bit RSA private key
..........................................................................................................................................................................................................................................++
...++
writing new private key to 'certs/myregistry.com.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:shandong
Locality Name (eg, city) [Default City]:jinan
Organization Name (eg, company) [Default Company Ltd]:dalu
Organizational Unit Name (eg, section) []:nengguan
Common Name (eg, your name or your server's hostname) []:myregistry.com
Email Address []:myregistry@dalu.com

以加密方式运行 registry 镜像(服务器应开启 443 端口)

docker run -d \
--privileged=true \
--restart=always \
--name registry \
-v /root/registry/data:/var/lib/registry \
-v /root/registry/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/myregistry.com.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/myregistry.com.key \
-p 443:443 \
registry:2

创建 docker TSL 认证证书(注意,配置的文件夹名应与主机名解析中配置的相同),并重新启动 docker

cd /etc/docker/ 
mkdir -p certs.d/myregistry.com
cd certs.d/myregistry.com/
cp /root/registry/certs/myregistry.com.crt ca.crt
systemctl restart docker

测试上传镜像至加密仓库

docker push myregistry.com/nginx:my

至此通过 TSL 加密的私有仓库搭建完毕

配置仓库的用户认证

首先删除之前运行的仓库容器,以及宿主机挂载卷中的内容

docker rm -f <container_id>
rm -rf /root/registry/data/

创建存放用户认证信息的文件夹

mkdir -p /root/registry/auth

下载 httpd 工具包,用于生成用户认证信息

yum install httpd -y

下载完成后启动并检查 httpd 服务的运行状态,状态显示为active (running)即启动成功

systemctl start httpd
systemctl status httpd

使用 httpd 工具包生成用户认证信息,按提示输入密码以及确认密码

htpasswd -cB /root/registry/auth/htpasswd admin
New password:
Re-type new password:
Adding password for user admin

注意,在创建新的用户时,不需要再加参数 c,如下所示

htpasswd -B /root/registry/auth/htpasswd zqf

重新以加密和用户认证的方式运行容器

docker run -d \
--privileged=true \
--restart=always \
--name registry \
-v /root/registry/data:/var/lib/registry \
-v /root/registry/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/myregistry.com.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/myregistry.com.key \
-v /root/registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-p 443:443 \
registry:2

测试上传镜像,此时提示没有用户认证信息,因为还没有登录

docker push myregistry.com/nginx:my
The push refers to repository [myregistry.com/nginx]
4a34c3cd54c3: Preparing
d874fd2bc83b: Preparing
32ce5f6a5106: Preparing
f1db227348d0: Preparing
b8d6e692a25e: Preparing
e379e8aedd4d: Preparing
2edcec3590a4: Preparing
no basic auth credentials

执行用户登录,输入之前创建的用户名与密码,提示登陆成功

docker login myregistry.com
Username: admin
Password:
Login Succeeded

登陆成功后重新测试上传镜像,上传成功

docker push myregistry.com/nginx:my

可以通过之前创建的用户查看私有仓库

curl -k https://myregistry.com/v2/_catalog -u <username>:<password>

至此,完整的具有 TSL 加密与用户认证功能的私有仓库搭建完毕

远程主机拉取镜像

首先修改远程主机的/etc/hosts文件,配置主机名映射

<仓库ip> myregistry.com

此时尝试从私有仓库中拉取镜像

docker pull myregistry.com/nginx:my

此时提示没有相应的证书

Error response from daemon: Get https://myregistry.com/v2/: x509: certificate signed by unknown authority

在私有仓库为远程主机配置证书

scp -r /etc/docker/certs.d/ <remote_ip>:/etc/docker/

再次尝试从私有仓库中拉取镜像

docker pull myregistry.com/nginx:my

此时提示没有授权信息

Error response from daemon: Get https://myregistry.com/v2/nginx/manifests/my: no basic auth credentials

试用账号密码登录仓库

docker login myregistry.com

尝试拉取镜像,拉取镜像成功

docker pull myregistry.com/nginx:my
my: Pulling from nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
b8756700ce69: Pull complete
Digest: sha256:8a546c81dce54399153867314b0a99a4b99e76bf164b91ada0f3996a73650d81
Status: Downloaded newer image for myregistry.com/nginx:my

注意,上述的远程主机从私有仓库拉取镜像的过程是在本地的虚拟机进行测试的,各服务器处于同一内网环境。在后续使用两台云服务器进行测试时,存在网络问题,该问题还未解决,在此做记录。配置完成后,拉取镜像报错:

Error response from daemon: Get https://myregistry.com/v2/: read tcp 192.168.16.2:41398->47.92.146.85:443: read: connection reset by peer
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐