三种方案回顾
轻量缓存同步(reposync /apt-mirror + Nginx)
rsync 全量镜像站(同步清华 / 阿里完整源目录)
专业一体化管理平台(Pulp3 / Mirrorbits)
一、核心维度对比表
表格
二、通俗拆解各自优缺点、使用场景
1)轻量缓存 reposync /apt-mirror(最简自用)
优点
上手零门槛,CentOS/Ubuntu 自带工具,不用装复杂平台
磁盘省:只同步你服务器在用的系统版本,比如只同步 Ubuntu22.04,不会下 16.04、20.04 等旧版
同步速度快,几小时就能完成首次同步
缺点
只能单独做 YUM 或者 APT,不能统一管理容器镜像
没有版本快照,一旦同步删除旧包,内网老机器无法安装旧软件
全部手动脚本维护,多系统并存时脚本会变得杂乱
适合场景
小型公司、几十台服务器,只用一种 Linux 发行版(全 CentOS 或全 Ubuntu)
不想维护复杂平台,追求简单快速搭建内网源
2)rsync 全量镜像站(完整复刻公网镜像)
优点
复刻清华 / 阿里完整开源仓库,包含所有发行版、所有衍生源(EPEL、RPMFusion、Ubuntu 各版本)
无需手动生成仓库元数据,上游已经做好,直接 rsync 复制文件即可
客户端配置和公网镜像格式完全一致,替换域名就能用
缺点
磁盘开销恐怖:完整镜像至少 2~5TB,长期存放会持续膨胀
包含大量废弃旧系统版本,90% 文件永远不会用到,纯浪费空间
无管理能力:不能做快照、权限控制、版本锁定,只能静态浏览文件
适合场景
高校、大型 IDC 机房,内网存在多种 Linux 版本(CentOS7/8/9、Ubuntu18/20/22)
完全物理隔离离线机房,需要随时能安装任意历史系统版本
3)Pulp3 / Mirrorbits 专业平台(企业级一体化)
优点
统一管理:一个平台同时管理 YUM、APT、Docker 镜像、文件仓库、Helm 仓库
版本快照:可冻结仓库版本,固定软件版本不自动更新,生产环境稳定
API + 可视化后台,支持权限、黑白名单、定时同步策略
Mirrorbits 面向公共镜像站,支持多节点负载均衡、全球分发、断点续传
缺点
部署复杂,依赖容器集群,学习成本高
资源占用高于前两种轻量方案
适合场景
中大型企业,同时跑 CentOS、Ubuntu、容器业务,需要统一私有仓库
对外提供公共镜像站点(高校开源镜像站)
生产环境严格管控软件版本,禁止随意更新包
三、快速选型建议
几十台机器、单一系统、简单内网源 → 选 轻量缓存 reposync/apt-mirror
多系统、完全离线、需要完整全版本系统包、磁盘充足 → 选 rsync 全量镜像
企业生产、容器 + Linux 系统混合、需要版本管控 / API / 多仓库统一管理 → 选 Pulp3
一、reposync(RPM 系:CentOS Stream、RockyLinux、AlmaLinux、RHEL)
1. 安装依赖
bash
运行
# CentOS Stream 8/9 / Rocky
dnf install -y reposync createrepo_c nginx
# CentOS7
yum install -y reposync createrepo nginx
reposync:下载仓库 rpm 包
createrepo_c:生成仓库元数据(客户端 yum 识别仓库必备)
nginx:提供 HTTP 静态访问
2. 目录规划
bash
运行
mkdir -p /data/mirror/centos9
mkdir -p /data/mirror/epel9
3. 同步仓库示例(CentOS Stream9 BaseOS + AppStream)
先把上游 repo 配置到本地,或者直接指定 repoid 同步清华源
方式 1:直接同步官方 / 清华源
bash
运行
# 同步BaseOS
reposync \
--repo=BaseOS \
--download_path=/data/mirror/centos9 \
--gpgcheck \
--delete \
--downloadcomps \
--download-metadata
# 同步AppStream
reposync \
--repo=AppStream \
--download_path=/data/mirror/centos9 \
--gpgcheck \
--delete \
--downloadcomps \
--download-metadata
参数说明:
--delete:本地不存在的上游旧包自动删除,保持和上游一致--download-metadata:同步上游元数据,不用每次手动 createrepo--downloadcomps:同步分组信息(yum groupinstall 可用)
方式 2:同步 EPEL 源
bash
运行
reposync --repo=epel --download_path=/data/mirror/epel9 --delete
4. 更新仓库元数据(定时执行)
即使同步了 metadata,新增包后仍需重建索引:
bash
运行
createrepo_c /data/mirror/centos9/BaseOS
createrepo_c /data/mirror/centos9/AppStream
createrepo_c /data/mirror/epel9
5. Nginx 发布镜像
/etc/nginx/conf.d/mirror.conf
nginx
server {
listen 80;
root /data/mirror;
autoindex on;
autoindex_localtime on;
autoindex_exact_size off;
}
bash
运行
systemctl enable --now nginx
6. 定时同步脚本 / 定时任务
/opt/mirror_sync_centos.sh
bash
运行
#!/bin/bash
LOG=/var/log/mirror_centos.log
echo "====== $(date) 开始同步 ======" >> $LOG
reposync --repo=BaseOS --download_path=/data/mirror/centos9 --delete >> $LOG
reposync --repo=AppStream --download_path=/data/mirror/centos9 --delete >> $LOG
reposync --repo=epel --download_path=/data/mirror/epel9 --delete >> $LOG
createrepo_c /data/mirror/centos9/BaseOS
createrepo_c /data/mirror/centos9/AppStream
createrepo_c /data/mirror/epel9
echo "====== $(date) 同步完成 ======\n" >> $LOG
授权 + 定时凌晨 2 点执行:
bash
运行
chmod +x /opt/mirror_sync_centos.sh
crontab -e
0 2 * * * /opt/mirror_sync_centos.sh
7. 客户端本地 repo 配置
ini
[Local-BaseOS]
name=Local CentOS9 BaseOS
baseurl=http://你的镜像IP/centos9/BaseOS
gpgcheck=0
enabled=1
[Local-AppStream]
name=Local CentOS9 AppStream
baseurl=http://你的镜像IP/centos9/AppStream
gpgcheck=0
enabled=1
[Local-EPEL]
name=Local EPEL9
baseurl=http://你的镜像IP/epel9
gpgcheck=0
enabled=1
我这边的操作
sudo tee /etc/apt/mirror.list <<'EOF'
set base_path /data/apt-mirror
set mirror_path $base_path/mirror
set skel_path $base_path/skel
set var_path $base_path/var
set cleanscript $var_path/clean.sh
set nthreads 16
set defaultarch amd64
set _tilde 0
# Ubuntu 24.04 noble 二进制包
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-backports main restricted universe multiverse
# 源码包禁用,节省磁盘
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble main restricted univEOFan https://mirrors.tuna.tsinghua.edu.cn/ubuntuntu/ noble-backports main restr
set base_path /data/apt-mirror
set mirror_path $base_path/mirror
set skel_path $base_path/skel
set var_path $base_path/var
set cleanscript $var_path/clean.sh
set nthreads 16
set defaultarch amd64
set _tilde 0
# Ubuntu 24.04 noble 二进制包
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-backports main restricted universe multiverse
# 源码包禁用,节省磁盘
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble main restricted universe multiverse
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-updates main restricted universe multiverse
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-security main restricted universe multiverse
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-backports main restricted universe multiverse
clean https://mirrors.tuna.tsinghua.edu.cn/ubuntu
shitou@shitou:~$ sudo mkdir -p /data/apt-mirror
shitou@shitou:~$ sudo chown apt-mirror:apt-mirror /data/apt-mirror查看了一下docker 服务,dockers 的镜像仓库密码忘记了,重新修改了一下
sudo docker exec -it harbor-db /bin/bash
postgres [ / ]$ psql -U postgres -d postgres -h 127.0.0.1 -p 5432
psql (15.12)
Type "help" for help.
postgres=# \c registry
You are now connected to database "registry" as user "postgres".
registry=# update harbor_user set password='', salt='' where username='admin';
UPDATE 1
registry=# select username, password, salt from harbor_user where username='admin';
username | password | salt
----------+----------+------
admin | |
(1 row)
registry=# \q
postgres [ / ]$ exit 退出
exit
shitou@shitou:~$ sudo docker restart harbor-core harbor-jobservice harbor-portal nginx
harbor-core
harbor-jobservice
harbor-portal
nginx
一、操作链路总逻辑
Harbor 底层使用 PostgreSQL 数据库存储账号、项目、镜像仓库权限等数据;
这段命令是直接进数据库把 admin 账号密码、盐值清空,重启相关服务后,Harbor 默认内置初始密码登录逻辑会生效,就能用默认密码登录。
1. sudo docker exec -it harbor-db /bin/bash
docker exec:进入正在运行的容器
-it:交互式终端,能输入命令、看输出
harbor-db:Harbor 配套 PostgreSQL 数据库容器名称
作用:登录存放 Harbor 账号数据的数据库容器内部。
2. psql -U postgres -d postgres -h 127.0.0.1 -p 5432
进入容器后连接 Postgres 数据库:
-U postgres:使用超级用户 postgres 登录数据库
-d postgres:默认系统库
-h 127.0.0.1:本地数据库地址
-p 5432:postgres 默认端口
3. \c registry
psql 内置元命令,切换数据库到 registry
Harbor 所有业务表(用户、项目、镜像、日志)全部存在 registry 库,不是默认 postgres 库。
4. update harbor_user set password='', salt='' where username='admin';
关键表说明
harbor_user:存储所有 Harbor 用户信息的数据表
字段:
username:账号名
password:加密后的密码(不是明文,是加盐哈希值)
salt:随机盐,加密密码时用,盐不同,相同明文加密结果不同
这条 SQL 执行动作:
把 admin 用户的加密密码、盐值全部清空,执行返回 UPDATE 1 代表成功修改 1 条数据。
5. select username, password, salt from harbor_user where username='admin';
查询验证:确认 admin 的 password 和 salt 字段已经是空字符串,确认修改生效。
6. \q
退出 psql 数据库命令行。
7. exit
退出 harbor-db 数据库容器,回到宿主机 shell。
8. sudo docker restart harbor-core harbor-jobservice harbor-portal nginx
重启 Harbor 核心相关容器,让数据库修改生效:
harbor-core:Harbor 核心业务服务,鉴权、登录、权限校验核心模块(必须重启,读取用户配置)
harbor-jobservice:后台任务服务(镜像扫描、垃圾清理、同步任务)
harbor-portal:前端 Web 页面容器
nginx:反向代理入口,所有网页 / 镜像推拉流量入口
重置后的登录规则
密码 + 盐清空后,Harbor 识别 admin 无自定义密码,使用默认初始密码登录:
默认初始密码(新版 Harbor):Harbor12345
风险 & 补充说明
不推荐生产环境直接改库
直接操作数据库跳过 Harbor 自带 API 校验,可能出现数据不一致;官方推荐使用 harborctl 重置密码。
安全隐患
admin 密码置空后任何人都能用默认密码登录,操作完成务必立刻登录后台修改密码。
原理补充
Harbor 不存储明文密码,前端输入密码后,用 salt 做哈希运算,和数据库内 password 字段比对;清空 salt+password 后,登录逻辑会走默认密码分支。
如果重启后依旧无法登录
检查容器是否正常启动:docker ps | grep harbor,查看日志 docker logs harbor-core。 sudo cat /etc/apt/mirror.list
set base_path /data/apt-mirror
set mirror_path $base_path/mirror
set skel_path $base_path/skel
set var_path $base_path/var
set cleanscript $var_path/clean.sh
set nthreads 16
set defaultarch amd64
set _tilde 0
# Ubuntu 24.04 noble 二进制包
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-backports main restricted universe multiverse
# 源码包禁用,节省磁盘
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble main restricted universe multiverse
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-updates main restricted universe multiverse
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-security main restricted universe multiverse
#deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-backports main restricted universe multiverse
clean https://mirrors.tuna.tsinghua.edu.cn/ubuntu
shitou@shitou:~$ set nthreads 6
shitou@shitou:~$ history
/etc/apt/mirror.list 完整解析 + 优化后可用配置
一、文件作用
apt-mirror 的唯一配置文件,控制:存储路径、下载并发、同步哪些 Ubuntu 仓库、清理规则、CPU 架构、是否同步源码包。
二、每行配置字段详解
conf
# 本地所有镜像文件存放根目录
set base_path /data/apt-mirror
# 软件包实际存放子目录 $base_path/mirror
set mirror_path $base_path/mirror
# 临时缓存目录
set skel_path $base_path/skel
# 日志、清理脚本存放目录
set var_path $base_path/var
# 自动清理脚本路径,同步后可执行删除上游已废弃旧包
set cleanscript $var_path/clean.sh
# 同时下载并发线程,服务器带宽一般设6-10,低配机器别开太大
set nthreads 6
# 只同步amd64 x86服务器架构,不下载arm/riscv节省磁盘
set defaultarch amd64
# 关闭~波浪号兼容,默认0即可
set _tilde 0
# 同步4类Ubuntu 24.04 noble官方二进制仓库
# 主仓库
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble main restricted universe multiverse
# 常规功能更新
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates main restricted universe multiverse
# 安全漏洞补丁(必须同步)
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-security main restricted universe multiverse
# 高版本软件向后移植
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-backports main restricted universe multiverse
# deb-src 源码包全部注释,不同步,减少近一半磁盘占用
#deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble main restricted universe multiverse
#deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates main restricted universe multiverse
#deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-security main restricted universe multiverse
#deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-backports main restricted universe multiverse
# 清理规则,匹配上游镜像地址,clean脚本会对比删除本地多余包
clean http://mirrors.tuna.tsinghua.edu.cn/ubuntuset nthreads 6
查看存储,空间是否足够
shitou@shitou:~$ lsblk -e7
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 1.8T 0 disk
└─sda1 8:1 0 1.8T 0 part /home
sdb 8:16 0 59.6G 0 disk
├─sdb1 8:17 0 1M 0 part
├─sdb2 8:18 0 2G 0 part /boot
└─sdb3 8:19 0 57.6G 0 part
├─ubuntu--vg-lv--0 252:0 0 55G 0 lvm /
└─ubuntu--vg-lv--1 252:1 0 2G 0 lvm
shitou@shitou:~$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 791M 3.2M 788M 1% /run
/dev/mapper/ubuntu--vg-lv--0 54G 27G 25G 53% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 3.9G 0 3.9G 0% /run/qemu
/dev/sdb2 2.0G 200M 1.6G 11% /boot
/dev/sda1 1.8T 5.4G 1.7T 1% /home
tmpfs 791M 16K 791M 1% /run/user/1000
shitou@shitou:~$ mount | grep apt-mirror
临时挂载
sudo mount --bind /home/mirror/apt-mirror /data/apt-mirror
验证
mount | grep apt-mirror
操作、写配置全部用
/data/apt-mirror真实文件全部存在
/home/mirror/apt-mirror(1.8T 大盘)看剩余空间看
/home,不要看/data重启后如果找不到,执行
mount -a重新加载挂载规则。
这里我选择挂载,还有软连接,或者直接修改配置文件,到容量高的/home 目录下,
ISO 的目录也是一样,要挂载
shitou@shitou:~$ sudo mount -a
shitou@shitou:~$ sudo mkdir -p /home/mirror/iso
shitou@shitou:~$ sudo chown shitou:shitou /home/mirror/iso
shitou@shitou:~$ sudo mkdir /data/iso
mkdir: cannot create directory ‘/data/iso’: File exists
shitou@shitou:~$ sudo mount --bind /home/mirror/iso /data/iso
mount: (hint) your fstab has been modified, but systemd still uses
the old version; use 'systemctl daemon-reload' to reload.
shitou@shitou:~$ sudo echo '/home/mirror/iso /data/iso none bind 0 0' | sudo tee -a /etc/fstab
/home/mirror/iso /data/iso none bind 0 0
shitou@shitou:~$ mount | grep -E "apt-mirror|iso"
/dev/sda1 on /var/harbor_data/apt-mirror type ext4 (rw,relatime)
/dev/sda1 on /var/harbor_data/iso type ext4 (rw,relatime)
软链接、挂载、改配置路径 三者核心区别(结合你 apt-mirror 场景举例)
一、先一句话总结本质
改配置地址:改程序代码里写死的路径,程序直接去新目录读写,无中间层;
软链接(ln -s):系统级 “快捷方式”,程序访问 A,系统自动跳转到 B,逻辑中转;
挂载(mount):把一块独立磁盘分区,绑定到某个目录,目录直接变成分区入口,底层存储彻底切换。
二、分别详细拆解,结合你的机器场景
你的现有资源:
独立分区 /dev/sda1 挂载在 /var/harbor_data/apt-mirror
空目录:/home/mirror/apt-mirror、/data/apt-mirror
1. 修改配置文件路径(最优推荐,apt-mirror 标准做法)
操作:编辑 /etc/apt/mirror.list,把 set base_path 改成目标目录
示例:
plaintext
set base_path /var/harbor_data/apt-mirror
特点
无任何中间跳转,apt-mirror 程序原生识别目标目录,读写直接走目标路径;
日志、清理脚本、缓存路径全部统一,不会出现路径错乱;
排查问题最简单,不用考虑链接 / 挂载陷阱;
缺点:需要改配置,重启 / 重新执行 apt-mirror 才生效。
适用场景
长期固定存储目录、有独立分区,规范部署内网源。
2. 软链接 ln -s (临时过渡用,不建议长期 apt 镜像)
举例:想让程序读 /data/apt-mirror,实际数据在 /var/harbor_data/apt-mirror
bash
运行
sudo rm -rf /data/apt-mirror
sudo ln -s /var/harbor_data/apt-mirror /data/apt-mirror
此时访问 /data/apt-mirror = 访问挂载分区的数据
特点
只是路径映射,底层存储还是原来的 /dev/sda1 分区;
程序看到的是 /data/apt-mirror,系统底层跳转至真实目录;
坑点很多:
部分工具(rsync、打包、权限遍历)会跟随链接,容易出现路径混淆;
链接丢失、目录被误删会直接找不到数据;
apt-mirror 生成的 clean.sh 脚本内部会写死 base_path,软链接容易导致清理脚本路径错误,删错文件。
适用场景
临时兼容旧脚本、旧程序只能写死固定路径,临时过渡使用。
3. mount 挂载(底层存储绑定,物理级切换目录)
你现在的现状:/dev/sda1 挂载到 /var/harbor_data/apt-mirror
如果想把分区挂载到 /data/apt-mirror:
umount 旧挂载点
修改 /etc/fstab 挂载目录为 /data/apt-mirror
mount -a 重新挂载
特点
底层存储切换:这个目录下所有文件,全部存在独立磁盘分区,和系统盘隔离;
没有跳转层,目录本身就是分区入口,程序读写完全感知不到 “挂载” 存在;
数据隔离:系统盘满了不影响镜像分区,扩容只需要扩 /dev/sda1;
持久化:写入 fstab 开机自动挂载,稳定性最高;
缺点:操作比软链接麻烦,需要卸载、改 fstab,不能随意切换。
适用场景
大量镜像存储、需要独立磁盘分区、长期稳定存放大容量数据(你的 apt 镜像场景首选)。
三、三者横向对比表
表格
方式 底层存储 有无中间跳转 稳定性 apt-mirror 推荐度 核心用途
修改配置路径 目标目录对应存储 无,原生直读 极高 ⭐⭐⭐⭐⭐ 首选 标准部署、分区存储
软链接 ln -s 真实目录的存储 有一层跳转映射 一般,易出路径 bug ⭐ 仅临时过渡 兼容旧固定路径
mount 挂载 独立磁盘分区 无,目录 = 分区入口 极高 ⭐⭐⭐⭐ 配合改配置 大容量数据隔离存储
四、结合你的业务给出最优组合方案(工业标准)
修改 fstab,将 /dev/sda1 挂载到 /data/apt-mirror(挂载,底层磁盘绑定)
修改 /etc/apt/mirror.list 中 base_path = /data/apt-mirror(改配置,程序直读)
全程不用软链接,无任何跳转陷阱,数据独立分区,路径统一规范。
五、通俗生活化比喻更好理解
改配置:软件直接改地址,以后快递直接寄到新仓库;
软链接:门上贴一张纸条 “找仓库请去隔壁房间”,中间人跳转;
挂载:把一整间独立仓库,直接换个门牌号,房间本身不变,只是入口换了。