docker搭建私有仓库registry及harbor
# 简介
在 Docker 中,当我们执行 docker pull xxx 的时候 ,它实际上是从 registry.hub.docker.com 这个地址去查找,这就是Docker公司为我们提供的公共仓库。在工作中,我们不可能把企业项目push到公有仓库进行管理。所以为了更好的管理镜像,Docker不仅提供了一个中央仓库,同时也允许我们搭建本地私有仓库。
- 本地镜像:在把java程序打包成镜像,输出的镜像的位置就是本地镜像
- 公有仓库:一个叫docker hub的网站,类似于github,所有人都可以把自己的镜像上传上去,也可以使用别人的镜像
- 私有仓库:相当于自己建的docker hub,常用于不可公开的(例如公司),或者追求网速(镜像不像代码文件那么小)
# 基础环境安装(docker)
yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
配置yum源
将docker的源配置成阿里的;
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum makecache fast
2
yum repolist #刷新yum源
安装docker-ce与docker-compose
yum install docker-ce -y #默认安装最新版本的docker-ce,需要使用指定版本可以使用yum install docker-ce -版本号安装
yum install docker-compose -y #安装docker-compose
2
启动docker
systemctl start docker #启动docker服务
systemctl enable docker #设置docker服务开机启动
2
# 部署registry
# 安装启动
# 普通默认方式
docker run -d -p 5000:5000 /opt/registry:/var/lib/registry --restart always --name wdp-hub registry:2.7.1
- -d : 让容器可以后台运行;
- -p :指定映射端口(前者是宿主机的端口号,后者是容器的端口号);
- -v :数据挂载(前者是宿主机的目录,后者是容器的目录);
- --name : 为运行的容器命名;
- Docker容器的重启策略如下:
- no:默认策略,在容器退出时不重启容器
- on- failure:在容器非正常退出时(退出状态非0),才会重启容器
- on- failure:3 :在容器非正常退出时重启容器,最多重启3次
- always:在容器退出时总是重启容器
- unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
默认情况下,仓库会被创建在容器的/var/lib/registry
目录下,可以通过-v
参数挂载本地的路径;
脚本封装
register服务的docker启动脚本;
restartRegistry.sh
docker stop registry
docker rm registry
docker run -d -p 5000:5000 --name=registry --restart=always \
--privileged=true \
--log-driver=none \
-v /root/registry/registrydata:/var/lib/registry \
registry:2
2
3
4
5
6
7
# 其他参数方式【推荐】
docker run -d -v /data/registory:/var/lib/registry -p 5000:5000 --restart=always --privileged=true --name registry registry:latest
# docker run -itd -v /data/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:latest
sudo mkdir -p /home/wdp-docker-bak/registry && sudo chown -R 1000:1000 /home/wdp-docker-bak/registry
docker run -d -p 5000:5000 /home/wdp-docker-bak/registry:/var/lib/registry --restart always --name wdp-hub registry:2.7.1
2
3
4
5
- -itd:在容器中打开一个伪终端进行交互操作,并在后台运行;
- -v:把宿主机的/data/registry目录绑定到容器/var/lib/registry目录(这个目录是registry容器中存放镜像文件的目录),来实现数据的持久化;
- -p:映射端口;访问宿主机的5000端口就访问到registry容器的服务;
- --restart=always: 这是重启的策略,在容器退出时总是重启容器;
- --name registry: 创建容器命名为registry
为什么是 /var/lib/registry/ 目录?
仓库默认存放镜像等信息在容器的 /var/lib/registry/docker
目录下,可以进入该目录查看已上传镜像信息,即使私有仓库的容器被误删,再次创建此容器,之前的镜像依然存在。
docker ps 可以看到仓库容器正在运行。进入到/data下,可以看到registory文件夹;
docker exec -it f94d2c317477 /bin/bash
# 检查push及pull
# 以操作
hello-world
为例子
# 创建镜像及推送
#拉取公共的
docker pull hello-world
#重命名本地镜像名字
docker tag hello-world:latest 10.45.xxx.116:5000/hello-world:latest
#推送本地镜像到私库
docker push 10.45.xxx.116:5000/hello-world:latest
#可能会报错;
2
3
4
5
6
7
# http访问权限
原因是docker私有仓库服务器,默认是https协议,所以我们需要进行修改不使用https;
vi /etc/docker/daemon.json #如果没有此文件,请创建
添加下面这段代码; 注意这里要个json文件格式,如果报错后面会重启docker失败;
"insecure-registries":["10.45.xxx.116:5000"]
{
"registry-mirrors": ["http://hub-mirror.c.163.com"],
"insecure-registries": ["10.45.xx.xx:5000","https://host116:4433"]
}
2
3
4
重启docker服务
systemctl daemon-reload
systemctl restart docker
2
再次将镜像推送到私有仓库,即可推送成功
docker push 10.45.xxx.116:5000/hello-world:latest
# get验证pull部分
- 查看私有仓库执行此命令:
curl -XGET http://ip:端口/v2/_catalog
; - 获取某个镜像的标签列表:
curl -XGEThttp://127.0.0.1:5000/v2/私有仓库镜像名称/tags/list
; - 也可通浏览器直接访问;
- http://10.45.xxx.116:5000/v2/_catalog
- http://10.45.xxx.116:5000/v2/xxx/tags/list
curl -XGET http://10.45.xxx.116:5000/v2/_catalog
# 若成功会返回以下值
#{"repositories":["hello-world","nginxtest"]}
curl http://10.45.xx.116:5000/v2/hello-world/tags/list
#{"name":"hello-world","tags":["latest"]}
# 删除本地重命名的镜像
# docker rmi -f 8652b9f0cb4c
docker rmi 10.45.xxx.116:5000/hello-world:latest
# 检查镜像
sudo docker images
# 拉取私有库中的镜像
docker pull 10.45.xxx.116:5000/hello-world:latest
# 检查镜像
sudo docker images
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 部署harbor【推荐】
包含registry库;
docker 官方提供的私有仓库 registry,用起来虽然简单 ,但在管理的功能上存在不足。 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。harbor在docker distribution的基础上增加了一些安全、访问控制、管理的功能以满足企业对于镜像仓库的需求。
Harbor (opens new window) 是一个开源镜像仓库,可通过基于角色的访问控制来保护镜像,新版本的Harbor还增加了扫描镜像中的漏洞并将镜像签名为受信任。
Docker官方也提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署我们私有环境的Registry也是非常必要的。 所以Harbor孕育而生,Harbor是由VMware公司开源的企业级的Docker Registry管理项目,它包括权限管理(RBAC)、LDAP、日志审核、管理界面、自我注册、镜像复制和中文支持等功能。
Harbor组件均以Docker容器方式启动,因此,你可以将其部署在任何支持Docker的Linux发行版上。
# 特性
- **☆ 易于部署:**可通过Docker compose或Helm Chart 部署 Harbor。
- ***☆* 云原生注册表:**Harbor 支持容器镜像和Helm图表,可作为容器原生运行时和编排平台等云原生环境的注册表。
- ***☆* 基于角色控制:**用户通过项目访问不同的存储库,并且用户可以对项目下的镜像或Helm图表具有不同的权限。
- ***☆* 基于策略的复制:**可以使用过滤器基于策略在多个注册表实例之间复制(同步)镜像和图表。
- ***☆* 镜像删除和垃圾收集:**系统管理员可以运行垃圾收集作业,以便可以删除镜像,并可以定期释放其空间。
- ***☆* 漏洞扫描:**Harbor会定期扫描映像中的漏洞,并进行策略检查以防止部署易受攻击的映像。
- ***☆* 公证人:**支持对容器镜像进行签名,以确保真实性和出处。
- ***☆* 审核:**通过日志跟踪对存储库的所有操作。
- ***☆* 图形门户:**用户可以轻松浏览,搜索存储库和管理项目。
- ***☆* 外部集成:**提供RESTful API有助于管理操作,并且易于与外部系统集成。
# 安装compose
部署harbor要依赖; yum install docker-compose
compose 基本命令
# 启动Harbor容器
docker-compose start
# 停止Harbor容器
docker-compose stop
# 重启Harbor容器
docker-compose restart
# 停止并删除Harbor容器,加上-v参数可以同时移除挂载在容器上的目录
docker-compose down
# 创建并启动Harbo容器,参数“-d”表示后台运行命令
docker-compose up -d
2
3
4
5
6
7
8
9
10
# 下载harbor安装包并进行解压
# 使用在线安装程序
#wget -P /usr/local wget https://github.com/goharbor/harbor/releases/download/v2.3.2/harbor-online-installer-v2.3.2.tgz
wget https://github.com/goharbor/harbor/releases/download/v2.4.1/harbor-offline-installer-v2.4.1.tgz
tar zxf harbor-offline-installer-v2.4.1.tgz -C /usr/local/
cd /usr/local
mv harbor/ wdp-harbor/
2
3
4
5
6
harbor安装位置 | /usr/local/wdp-harbor | 暂无 |
---|---|---|
harbor数据目录 | /home/wdp-docker-bak/harbor | 暂无 |
# 编写harbor配置文件
配置参数位于安装目录的 harbor.yml 文件中。
# 重命名
cd /usr/local
# 修改配置文件,根据自己的需求进行修改
cd wdp-harbor
cp harbor.yml.tmpl harbor.yml
# harbor.yml中按需修改或添加如下内容
## 修改hostname
hostname: harbor.test.com #如果是ip的话,直接设置ip;
## 修改admin密码
harbor_admin_password: xxxxxxx
## 暂时关闭https
#https:
# https port for harbor, default is 443
# port: 443
# The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
## 添加禁止用户自注册
self_registration: off
## 设置只有管理员可以创建项目(可选)
# project_creation_restriction: adminonly
## 指定数据目录,若无则手动创建该目录
data_volume: /home/wdp-docker-bak/harbor
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# harbor.yml
修改以下内容:
hostname = 192.168.xxx.204 #修改harbor的启动ip,这里需要依据系统ip设置
port: 5000 #harbor的端口,有两个端口,http协议(80)和https协议(443)
harbor_admin_password = xxxx #修改harbor的admin用户的密码
data_volume: /home/wdp-docker-bak/harbor #修改harbor存储位置
2
3
4
一般情况下,我们最少需要配置的内容如下:
- hostname 需要配置为 127.0.0.1 之外的内容,以提供外部访问,本例中我配置为: docker.soulteary.com
- https 的配置需要同时配置证书,生产环境中,如果使用 SLB 或者使用其他应用统一提供 SSL 接入,则可以删除。
- harbor_admin_password 默认密码即可,但是初次使用登陆后台后需要修改密码。
- data_volume 根据自己实际情况修改宿主机的文件储存地址。
# 必须参数
- hostname: 目标主机的主机名。它应该是目标计算机的 IP 地址或完全限定的域名(FQDN),例如:172.16.1.30 或 reg.yourdomain.com。不要使用 localhost 或 127.0.0.1 作为主机名。
- data_volume: Harbor 数据的存储位置
- harbor_admin_password: 管理员的初始密码。此密码仅在 Harbor 首次启动时生效。请注意,默认用户 名/密码为 admin / Harbor12345
- database: 与本地数据库相关的配置。
- password: 默认数据库密码为 root123,应该改为一个安全的生产环境密码。
# 可选参数
- http: port: 你的 http 的端口号。
- https: 启用 https 协议。如果启用了秘钥,则必须设置为 https。
- port: https 的端口号。
- certificate: SSL 证书的路径,仅在协议设置为 https 时应用。
- private_key: SSL 密钥的路径,仅在协议设置为 https 时应用。
# 网络端口
# 修改docker配置文件
修改docker配置文件,使docker支持harbor
编辑客户机/etc/docker/daemon.json文件
{"insecure-registries":["192.168.100.204:80"]}
重启客户机docker服务
systemctl restart docker #或者(service docker restart)
# 设置Harbor开机启动【要点】
使用vim编辑器编辑配置文件vim /lib/systemd/system/harbor.service并向文件中写入
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor
[Service]
Type=simple
Restart=on-failure
RestartSec=5
#需要注意harbor的安装位置
ExecStart=/usr/bin/docker-compose -f /usr/local/wdp-harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f /usr/local/wdp-harbor/docker-compose.yml down
[Install]
WantedBy=multi-user.target
#或者修改.yml 中每个的:restart: always;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
systemctl enable harbor #设置harbor开机自启
systemctl start harbor #启动harbor
#临时脚本
cd /usr/local/wdp-harbor
docker-compose up -d
docker-compose down
#查看
docker-compose ps -a
2
3
4
5
6
7
8
9
10
# 启动Harbor
# 执行安装脚本
bash ./install.sh
2
最终目录结构:
root@harbor:/usr/local/harbor# ll
total 60
drwxr-xr-x 3 root root 4096 Aug 31 06:41 ./
drwxr-xr-x 11 root root 4096 Aug 31 03:27 ../
drwxr-xr-x 3 root root 4096 Aug 31 03:27 common/
-rw-r--r-- 1 root root 3361 Aug 18 08:53 common.sh
-rw-r--r-- 1 root root 6066 Aug 31 03:34 docker-compose.yml
-rw-r--r-- 1 root root 7919 Aug 31 03:34 harbor.yml
-rw-r--r-- 1 root root 7840 Aug 18 08:53 harbor.yml.tmpl
-rwxr-xr-x 1 root root 2500 Aug 18 08:53 install.sh*
-rw-r--r-- 1 root root 11347 Aug 18 08:53 LICENSE
-rwxr-xr-x 1 root root 1881 Aug 18 08:53 prepare*
2
3
4
5
6
7
8
9
10
11
12
# 查看容器的运行状态
root@harbor:/usr/local/harbor# docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------------
harbor-core /harbor/entrypoint.sh Up (healthy)
harbor-db /docker-entrypoint.sh 96 13 Up (healthy)
harbor-jobservice /harbor/entrypoint.sh Up (healthy)
harbor-log /bin/sh -c /usr/local/bin/ ... Up (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal nginx -g daemon off; Up (healthy)
nginx nginx -g daemon off; Up (healthy) 0.0.0.0:80->8080/tcp,:::80->8080/tcp
redis redis-server /etc/redis.conf Up (healthy)
registry /home/harbor/entrypoint.sh Up (healthy)
registryctl /home/harbor/start.sh Up (healthy)
2
3
4
5
6
7
8
9
10
11
12
# 启动注意事项
如果修改harbor.yml
,一定要通过install.sh
脚本启动;
当修改 harbor.yml
后,我们需要执行 bash prepare
,让配置能够得到更新。当然,历史存在的容器 container 也需要清理,除了使用 docker rm
进行清理外,还可以使用 docker system prune
进行清理。
# 注册和创建仓库
访问登录界面了。(用户admin,密码:x x x(在harbor配置文件中可以查看到),新建个项目设置为wdp-test;设置项目仓库为公开模式;
修改tag,及推送;注意要多一次文档目录;
#docker login 10.45.46.xxx:5000 #记得要登录后推送设置;
docker tag SOURCE_IMAGE[:TAG] 10.45.46.xxx:5000/wdp/REPOSITORY[:TAG]
docker push 10.45.xxx.116:5000/wdp/REPOSITORY[:TAG]
docker pull 10.45.xxx.116:5000/wdp/REPOSITORY[:TAG]
2
3
4
# 配置https TODO
# 把这三个证书文件复制到docker相应的目录下,注意最后的路径名,要跟上面的保持一致
mkdir -p /etc/docker/certs.d/www.harbor.mobi/
cp www.harbor.mobi.cert /etc/docker/certs.d/www.harbor.mobi/
cp www.harbor.mobi.key /etc/docker/certs.d/ywww.harbor.mobi/
cp ca.crt /etc/docker/certs.d/www.harbor.mobi/
最终docker目录结构:
/etc/docker/certs.d/
└── www.harbor.mobi
├── www.harbor.mobi.cert <-- Server certificate signed by CA
├── www.harbor.mobi.key <-- Server key signed by CA
└── ca.crt <-- Certificate authority that signed the registry certificate
# 先停止harbor
cd /usr/local/harbor
docker-compose down -v
# 重启docker
systemctl restart docker.service
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 配置定时垃圾清理
一定要记得设置这个定时清理功能,要不然随着不断推送tag会原来越大,导致磁盘空间不够,最终导致Harbor启动运行不正常;
检查各磁盘空间的命令:
#全局查看
df -h
#依次查看各个目录的磁盘大小
du -ah --max-depth=1
2
3
4
管理后台查看打下:
# 迁移Docker仓库
# 采用registry部署的迁移方法
大概流程就是导出registry镜像,在新的机器导入,然后把镜像文件放到相同的目录下,启动就可以了。
采用Harbor部署的迁移方法
编写脚本把镜像重新上传到Harbor;
# 切换镜像仓库【推荐】
不管以上如何实现,但切换镜像仓库的方法大致相同。在测试没问题的前提下,执行以下流程:
如果选择registry,则只需要把原来registry仓库的镜像文件,直接复制到新的registry仓库的目录下。如过选用Harbor,则需要编写脚本把原来镜像仓库的镜像同步过去。
编写shell脚本通过ansible更新所有要与Registry交互的Docker主机。如果选择Insecure Registry需要更改所有 Docker主机的Docker Daemon。如果选择Secure Registry则是颁发证书。
通知新镜像仓库的地址,避免push、pull失败。
sudo docker run -d -p 5000:5000 --restart=always --name registry -v /app_data/registry/:/var/lib/registry registry:2
# 参考相关
- Harbor仓库配置https访问 (opens new window)
- [离线安装 Harbor v2](https://blog.atompi.com/2020/08/03/离线安装 Harbor v2/)