私有仓库
1、私有仓库
简介:
Docker私有仓库是由个人或企业搭建的Docker仓库,供其自身使用,是非公开的。它与公有仓库如Docker Hub相对,后者供所有Docker用户使用。
在生产环境中,公司通常会构建一些符合自身业务需求的镜像。由于这些镜像可能包含商业机密,因此不能上传到Docker Hub,而只能供公司内部人员使用。此时,公司会在内网搭建一个Docker私有仓库,用于存储公司内部的镜像,并确保内部人员可以不受网络限制,快速地拉取或上传镜像。
私有仓库的架构拓扑可能包括Webhook、回调函数、令牌服务以及数据库等组件。Webhook用于在数据产生时立即发送数据给已注册的应用,实现实时数据获取。回调函数可以在特定阶段被调用,用于观察训练过程中网络内部的状态和统计信息。令牌服务提供身份验证服务,确保仓库的安全性。而数据库则记录镜像的元信息及用户的身份信息。
私有仓库的应用场景广泛,特别是在需要保护内部资源保密性的情况下。例如,当公共镜像仓库的网速太慢或需要额外费用时,机构可能会选择创建基于内部项目镜像的本地私人仓库,供给团队使用。Docker提供了Docker Registry工具,可以用于构建这样的私有镜像仓库。
2、搭建私有仓库
2-1 环境部署
私有仓库在企业中有较高的使用,本节用两台服务器搭建私有仓库,一台为私有镜像仓库,另一台为私有镜像仓库的Docker客户机
服务器 | IP | 功能 |
---|---|---|
docker01 | 192.168.10.149 | Docker私有仓库 |
docker02 | 192.168.10.148 | 使用私有仓库 |
2-2 自建仓库
- 使用Docker Hub 的仓库镜像运行私有仓库
[root@wangliukun /]# docker pull registry
Using default tag: latest
Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:40410->[::1]:53: read: connection refused
报错:
Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:40410->[::1]:53: read: connection refused
发现网络不通
[root@wangliukun /]# ping www.baidu.com
ping: www.baidu.com: 未知的名称或服务
修改网络配置
[root@wangliukun network-scripts]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="28ebfaa8-8cb1-4dda-b2e3-cd86f25ab0b4"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=192.168.10.149
NETMASK=255.255.255.0
GATEWAY=192.168.10.2
DNS1=8.8.8.8
DNS2=114.114.114.114##添加了一个电信的DNS
[root@wangliukun network-scripts]#
##type:网络模式
##bootproto:启动协议,有 none static dhcp 三个启动模式,none相当于不使用dhcp,static要手写ip地址
##name:网卡名
##uuid:这个是设备的uuid,配置的时候可以不写,会自动识别
##device:系统逻辑设备名,name和device最好是一样的
##onboot:开机是否自启
##ipaddr:添加ip地址
##netmask:子网掩码
##gateway:网关
##dns1:电信的114.114.114.114,谷歌的8.8.8.8
重新拉取
[root@wangliukun network-scripts]# docker pull registry
Using default tag: latest
latest: Pulling from library/registry
79e9f2f55bf5: Pull complete
0d96da54f60b: Pull complete
5b27040df4a2: Pull complete
e2ead8259a04: Pull complete
3790aef225b9: Pull complete
Digest: sha256:169211e20e2f2d5d115674681eb79d21a217b296b43374b8e39f97fcf866b375
Status: Downloaded newer image for registry:latest
docker.io/library/registry:latest
[root@wangliukun network-scripts]#
- 查看
[root@wangliukun ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest b8604a3fe854 2 years ago 26.2MB
- 将仓库镜像运行成容器
[root@wangliukun ~]# docker run -it -d -p 5000:5000 --restart=always --name registry registry
89e672169cd89376dee1ef1d3e5da3a6dc0e0bd55fdcf7ff50499b0bf4ffe387
[root@wangliukun ~]#
以上开启仓库容器,映射宿主机500端口,供Docker 镜像的上传与下载,其中 --restart=always
表示容器停止时自动重启,这条参数用于生产环境
- 将镜像上传至刚创建的镜像仓库
##下载一个busybox镜像用作测试
[root@wangliukun ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Status: Image is up to date for busybox:latest
docker.io/library/busybox:latest
##修改镜像tag 使其指向私有仓库
[root@wangliukun ~]# docker tag busybox 192.168.10.149:5000/busybox:latest
##上传至私有仓库
[root@wangliukun ~]# docker push 192.168.10.149:5000/busybox:latest
The push refers to repository [192.168.10.149:500/busybox]
Get "https://192.168.10.149:5000/v2/": dial tcp 192.168.10.149:5000: connect: connection refused
[root@wangliukun ~]#
报错:
Get "https://192.168.10.149:5000/v2/": dial tcp 192.168.10.149:5000: connect: connection refused
原因:
Docker 默认支持HTTPS,命令行中使用的时HTTP。
解决:
修改Docker启动参数,使之允许HTTPS
[root@wangliukun system]# cat /usr/lib/systemd/system/docker.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
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
...
[root@wangliukun system]#
##修改ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
##添加--insecure-registry 192.168.10.149:5000
##ExecStart=/usr/bin/dockerd--insecure-registry 192.168.10.149:5000
[root@wangliukun system]# systemctl daemon-reload
[root@wangliukun system]# systemctl restart docker
[root@wangliukun system]#
以上成功修改docker参数·
- 上传镜像
[root@wangliukun containers]# docker push 192.168.10.149:5000/busybox:latest
The push refers to repository [192.168.10.149:5000/busybox]
01fd6df81c8e: Pushed
latest: digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee size: 527
[root@wangliukun containers]#
- 拉取私有仓库中的镜像
##查看镜像仓库
[root@wangliukun ~]# curl -X GET http://192.168.10.149:5000/v2/_catalog
{"repositories":["busybox"]}
[root@wangliukun ~]#
##删除本地busybox,测试从仓库中拉取
[root@wangliukun ~]# docker rmi 192.168.10.149:5000/busybox
Untagged: 192.168.10.149:5000/busybox:latest
Untagged: 192.168.10.149:5000/busybox@sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee
Deleted: sha256:beae173ccac6ad749f76713cf4440fe3d21d1043fe616dfbe30775815d1d0f6a
Deleted: sha256:01fd6df81c8ec7dd24bbbd72342671f41813f992999a3471b9d9cbc44ad88374
[root@wangliukun ~]#
##测试拉取
[root@wangliukun ~]# docker pull 192.168.10.149:5000/busybox
Using default tag: latest
latest: Pulling from busybox
5cc84ad355aa: Pull complete
Digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee
Status: Downloaded newer image for 192.168.10.149:5000/busybox:latest
192.168.10.149:5000/busybox:latest
以上删除了原有镜像,并从私有仓库中拉取了之前上传的镜像
如何从其他服务器获取仓库里的镜像?
(以下为第二台服务器)
- 修改配置文件
[root@wangliukun ~]# cat /usr/lib/systemd/system/docker.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
##添加--insecure-registrIP:5000
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.10.149:5000
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
...
[root@wangliukun ~]# 、
##重启
[root@wangliukun ~]# systemctl daemon-reload
[root@wangliukun ~]# systemctl restart docker
- 拉取镜像
[root@wangliukun ~]# docker pull 192.168.10.149:5000/busybox
Using default tag: latest
latest: Pulling from busybox
Digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee
Status: Downloaded newer image for 192.168.10.149:5000/busybox:latest
192.168.10.149:5000/busybox:latest
3、使用TLS证书
3-1 生成证书
想让仓库对外提供服务,需要配置用户认可的TLS证书
[root@wangliukun ~]# mkdir -p /opt/docker/registry/certs
[root@wangliukun ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout /opt/docker/registry/certs/domain.key -x509 -days 365 -out /opt/docker/registry/certs/domain.crt
Generating a 4096 bit RSA private key
.........................................................................................................................................................++
..............................................................................++
writing new private key to '/opt/docker/registry/certs/domain.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) []:xj ##输入省份
Locality Name (eg, city) [Default City]:cj ##输入城市
Organization Name (eg, company) [Default Company Ltd]:cjxy ##输入公司
Organizational Unit Name (eg, section) []:B2101 ##输入部门
Common Name (eg, your name or your server's hostname) []:registry.docker.com ##证书名字
Email Address []:2669299139@qq.com ##输入邮箱
[root@wangliukun ~]#
- 创建带有TSL证书的仓库容器
[root@wangliukun ~]# docker run -it -d -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 --restart=always --name registry-TLS registry
eccb3130933b06c98834bc71fdd315d1ce4ba7f7d731015a579c5f6a75a3c53c
[root@wangliukun ~]#
以上创建了一个名为registry-TLS
的容器,通过 REGISTRY_HTTP_TLS_CERTIFICATE
和REGISTRY_HTTP_TLS_KEY
两个参数启动仓库的证书支持
- docker客户端配置域名解析
##这里为了方便区分,分别设置两台宿主机的主机名
[root@wangliukun ~]# hostnamectl set-hostname docker01
[root@wangliukun ~]# reboot
[root@wangliukun ~]# hostnamectl set-hostname docker02
[root@wangliukun ~]# reboot
[root@docker01 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.149 registry.docker.com
[root@docker02 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.149 registry.docker.com
##两台机器均已做好解析
##在宿主机中创建名称与域名相同的目录
[root@docker02 ~]# mkdir /etc/docker/certs.d
[root@docker02 ~]# cd /etc/docker/certs.d
[root@docker02 certs.d]# mkdir registry.docker.com:5000
[root@docker02 certs.d]# ll
总用量 0
drwxr-xr-x. 2 root root 6 4月 19 17:11 registry.docker.com:5000
[root@docker02 certs.d]#
将证书damain.crt复制到要使用的仓库的Docker宿主机,并放在/etc/docker/certs.d/registry.docker.com:5000
中
[root@docker01 certs]# scp -r -p /opt/docker/registry/certs/domain.crt 192.168.10.148:/etc/docker/certs.d/registry.docker.com:5000/ca.crt
root@192.168.10.148's password:
domain.crt 100% 2098 1.3MB/s 00:00
[root@docker02 registry.docker.com:5000]# ll
总用量 4
-rw-r--r--. 1 root root 2098 4月 19 16:18 ca.crt
[root@docker02 registry.docker.com:5000]#
- docker01是仓库的宿主机,下面是用docker02推送镜像给私有仓库
[root@docker02 /]# docker tag busybox:latest registry.docker.com:5000/busybox:latest
[root@docker02 /]#
[root@wangliukun etc]# docker push registry.docker.com:5000/busybox:latestdocker
3-2 基本身份验证
- 创建用户密码文件
#mkdir /opt/docker/registry/auth
#docker run --entrypoint htpasswd registry -Bbn testuser testpassword /opt/docker/registry/auth/htpasswd
设置用户名:testuser
密码:testpassword
如果以上设置用户步骤失效,可用httpd命令
##安装命令
[root@docker01 certs]# yum -y install httpd
#执行设置用户
[root@docker01 certs]# htpasswd -Bb -c /opt/docker/registry/auth/htpasswd testuser testpassword
Adding password for user testuser
- 运行仓库
[root@docker01 certs]# docker run -d \
> -p 5000:5000 \
> -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 \
> --restart=always \
> --name registry-TLS registry
- 尝试推送镜像
[root@docker02 ~]# docker push 192.168.10.149:5000/busybox
Using default tag: latest
The push refers to repository [192.168.10.149:5000/busybox]
01fd6df81c8e: Preparing
no basic auth credentials
[root@docker02 ~]#
推送失败:没有基本身份验证凭证
- 通过用户名密码登录
[root@docker02 ~]# docker login registry.docker.com:5000
Username: testuser
Password:
Login Succeeded
- 再次拉取
[root@docker02 /]# docker push 192.168.10.149:5000/busybox:latest
The push refers to repository [192.168.10.149:5000/busybox]
01fd6df81c8e: Pushed
latest: digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee size: 527