搭建私有 Linux 镜像仓库
为什么需要私有镜像仓库?
在企业环境中,搭建私有Linux镜像仓库具有以下优势:
• 网络优化:减少外网带宽消耗,提升下载速度
• 安全控制:内网环境下的安全软件分发
• 版本管理:统一管理软件包版本,确保环境一致性
• 离线部署:支持无外网环境的软件安装
• 成本节约:减少重复下载,节省带宽成本
架构设计
环境准备
硬件要求
组件 | 最低配置 | 推荐配置 | 生产环境 |
CPU | 2核 | 4核 | 8核+ |
内存 | 4GB | 8GB | 16GB+ |
存储 | 500GB | 2TB | 10TB+ |
网络 | 100Mbps | 1Gbps | 10Gbps |
软件环境
# 操作系统:Ubuntu 22.04 LTS 或 CentOS 8
# Web服务器:Nginx
# 同步工具:rsync, apt-mirror, reposync
# 监控:Prometheus + Grafana
目录规划
# 创建目录结构
sudomkdir -p /data/mirrors/{ubuntu,centos,docker,alpine}
sudomkdir -p /data/mirrors/logs
sudomkdir -p /data/mirrors/scripts
sudomkdir -p /etc/mirrors
搭建APT私有镜像源
安装apt-mirror
# Ubuntu/Debian系统
sudo apt update
sudo apt install -y apt-mirror nginx# 创建镜像用户
sudo useradd -r -s /bin/false -d /data/mirrors aptmirror
sudochown -R aptmirror:aptmirror /data/mirrors
配置apt-mirror
# 编辑配置文件
sudo nano /etc/apt/mirror.list
# /etc/apt/mirror.list
############# config ##################
set base_path /data/mirrors/ubuntu
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 defaultarch amd64
set postmirror_script $var_path/postmirror.sh
set run_postmirror 0
set nthreads 20
set _tilde 0############# end config ############### Ubuntu 22.04 LTS (Jammy)
deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu jammy-security main restricted universe multiverse# Ubuntu 20.04 LTS (Focal)
deb http://archive.ubuntu.com/ubuntu focal main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu focal-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu focal-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu focal-security main restricted universe multiverse# 源码包(可选)
# deb-src http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse# 清理脚本
clean http://archive.ubuntu.com/ubuntu
clean http://security.ubuntu.com/ubuntu
创建同步脚本
# 创建同步脚本
sudo nano /data/mirrors/scripts/sync-ubuntu.sh
#!/bin/bash
# Ubuntu镜像同步脚本set -eLOGFILE="/data/mirrors/logs/ubuntu-sync-$(date +%Y%m%d-%H%M%S).log"
LOCKFILE="/var/run/ubuntu-mirror.lock"# 检查锁文件
if [ -f "$LOCKFILE" ]; thenecho"同步进程已在运行,退出..."exit 1
fi# 创建锁文件
echo $$ > "$LOCKFILE"# 清理函数
cleanup() {rm -f "$LOCKFILE"
}
trap cleanup EXITecho"开始Ubuntu镜像同步: $(date)" | tee -a "$LOGFILE"# 执行同步
sudo -u aptmirror apt-mirror /etc/apt/mirror.list 2>&1 | tee -a "$LOGFILE"# 更新时间戳
echo"$(date)" > /data/mirrors/ubuntu/last_updateecho"Ubuntu镜像同步完成: $(date)" | tee -a "$LOGFILE"# 清理旧日志(保留30天)
find /data/mirrors/logs -name "ubuntu-sync-*.log" -mtime +30 -delete# 发送通知(可选)
# curl -X POST -H 'Content-type: application/json' \
# --data '{"text":"Ubuntu镜像同步完成"}' \
# YOUR_WEBHOOK_URL
# 设置执行权限
sudochmod +x /data/mirrors/scripts/sync-ubuntu.sh
配置Nginx
# 创建Nginx配置
sudo nano /etc/nginx/sites-available/ubuntu-mirror
server {listen80;server_name ubuntu-mirror.example.com;root /data/mirrors/ubuntu/mirror;index index.html;# 访问日志access_log /var/log/nginx/ubuntu-mirror.access.log;error_log /var/log/nginx/ubuntu-mirror.error.log;# 基本配置location / {autoindexon;autoindex_exact_sizeoff;autoindex_localtimeon;# 缓存配置expires1d;add_header Cache-Control "public, immutable";# 安全头add_header X-Frame-Options "SAMEORIGIN";add_header X-Content-Type-Options "nosniff";}# 包文件缓存location~* \.(deb|udeb|tar\.gz|tar\.xz|tar\.bz2)$ {expires7d;add_header Cache-Control "public, immutable";}# 元数据文件location~* (Release|Packages|Sources)$ {expires1h;add_header Cache-Control "public, must-revalidate";}# 状态页面location /status {alias /data/mirrors/ubuntu/;try_files /last_update =404;add_header Content-Type text/plain;}# 禁止访问隐藏文件location~ /\. {deny all;}
}
# 启用站点
sudoln -s /etc/nginx/sites-available/ubuntu-mirror /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
搭建YUM私有镜像源
安装reposync
# CentOS/RHEL系统
sudo yum install -y yum-utils createrepo nginx# 或者在Ubuntu上安装
sudo apt install -y yum-utils createrepo-c nginx
配置YUM仓库同步
# 创建CentOS 8同步脚本
sudo nano /data/mirrors/scripts/sync-centos.sh
#!/bin/bash
# CentOS镜像同步脚本set -eMIRROR_BASE="/data/mirrors/centos"
LOGFILE="/data/mirrors/logs/centos-sync-$(date +%Y%m%d-%H%M%S).log"
LOCKFILE="/var/run/centos-mirror.lock"# 检查锁文件
if [ -f "$LOCKFILE" ]; thenecho"同步进程已在运行,退出..."exit 1
fiecho $$ > "$LOCKFILE"cleanup() {rm -f "$LOCKFILE"
}
trap cleanup EXITecho"开始CentOS镜像同步: $(date)" | tee -a "$LOGFILE"# 同步CentOS 8 Stream
sync_centos_stream() {local version=$1local repo_dir="$MIRROR_BASE/$version"mkdir -p "$repo_dir"# 同步各个仓库for repo in baseos appstream extras powertools; doecho"同步 CentOS $version$repo..." | tee -a "$LOGFILE"reposync \--download-path="$repo_dir" \--repo="$repo" \--arch=x86_64 \--newest-only \--delete \2>&1 | tee -a "$LOGFILE"# 创建仓库元数据createrepo_c "$repo_dir/$repo/" 2>&1 | tee -a "$LOGFILE"done
}# 同步不同版本
sync_centos_stream "8-stream"
sync_centos_stream "9-stream"# 更新时间戳
echo"$(date)" > "$MIRROR_BASE/last_update"echo"CentOS镜像同步完成: $(date)" | tee -a "$LOGFILE"# 清理旧日志
find /data/mirrors/logs -name "centos-sync-*.log" -mtime +30 -delete
配置YUM仓库文件
# 创建仓库配置模板
sudo nano /data/mirrors/centos/centos8-stream.repo
[baseos]
name=CentOS Stream $releasever - BaseOS
baseurl=http://your-mirror.example.com/centos/8-stream/baseos/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial[appstream]
name=CentOS Stream $releasever - AppStream
baseurl=http://your-mirror.example.com/centos/8-stream/appstream/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial[extras]
name=CentOS Stream $releasever - Extras
baseurl=http://your-mirror.example.com/centos/8-stream/extras/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial[powertools]
name=CentOS Stream $releasever - PowerTools
baseurl=http://your-mirror.example.com/centos/8-stream/powertools/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Nginx配置(CentOS)
server {listen80;server_name centos-mirror.example.com;root /data/mirrors/centos;index index.html;access_log /var/log/nginx/centos-mirror.access.log;error_log /var/log/nginx/centos-mirror.error.log;location / {autoindexon;autoindex_exact_sizeoff;autoindex_localtimeon;expires1d;add_header Cache-Control "public, immutable";}# RPM包缓存location~* \.rpm$ {expires7d;add_header Cache-Control "public, immutable";}# 元数据缓存location~* (repomd\.xml|primary\.xml|filelists\.xml|other\.xml)$ {expires1h;add_header Cache-Control "public, must-revalidate";}# 仓库配置文件下载location /repo-files/ {alias /data/mirrors/centos/;try_files$uri$uri.repo =404;add_header Content-Type text/plain;}
}
搭建Docker私有镜像仓库
安装Docker Registry
# 安装Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER# 创建Registry目录
sudomkdir -p /data/mirrors/docker/{registry,auth,certs}
配置Registry
# 创建Registry配置文件
sudo nano /data/mirrors/docker/config.yml
version:0.1
log:
accesslog:disabled:false
level:info
formatter:text
fields:service:registrystorage:
cache:blobdescriptor:inmemory
filesystem:rootdirectory:/var/lib/registry
delete:enabled:truehttp:
addr::5000
headers:X-Content-Type-Options: [nosniff]Access-Control-Allow-Origin: ['*']Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']Access-Control-Allow-Headers: ['Authorization', 'Accept', 'Cache-Control']health:
storagedriver:enabled:trueinterval:10sthreshold:3proxy:
remoteurl:https://registry-1.docker.io
username:your-dockerhub-username
password:your-dockerhub-password
启动Registry服务
# 创建docker-compose文件
sudo nano /data/mirrors/docker/docker-compose.yml
version:'3.8'services:
registry:image:registry:2.8container_name:docker-registryrestart:unless-stoppedports:-"5000:5000"environment:REGISTRY_CONFIG_PATH:/etc/docker/registry/config.ymlREGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY:/var/lib/registryvolumes:-/data/mirrors/docker/registry:/var/lib/registry-/data/mirrors/docker/config.yml:/etc/docker/registry/config.yml:ronetworks:-registry-netregistry-ui:image:joxit/docker-registry-ui:latestcontainer_name:registry-uirestart:unless-stoppedports:-"8080:80"environment:REGISTRY_TITLE:"Private Docker Registry"REGISTRY_URL:http://registry:5000DELETE_IMAGES:"true"SHOW_CONTENT_DIGEST:"true"depends_on:-registrynetworks:-registry-netnetworks:
registry-net:driver:bridge
# 启动服务
cd /data/mirrors/docker
sudo docker-compose up -d
配置Registry代理
# Docker Registry Nginx配置
server {listen80;server_name docker-registry.example.com;client_max_body_size0;chunked_transfer_encodingon;location /v2/ {proxy_pass http://localhost:5000;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_read_timeout 900;}location / {proxy_pass http://localhost:8080;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}
自动化同步与更新
创建统一同步脚本
# 创建主同步脚本
sudo nano /data/mirrors/scripts/sync-all.sh
#!/bin/bash
# 统一镜像同步脚本set -eSCRIPT_DIR="/data/mirrors/scripts"
LOG_DIR="/data/mirrors/logs"
NOTIFICATION_URL="${WEBHOOK_URL:-}"# 日志函数
log() {echo"[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_DIR/sync-all.log"
}# 通知函数
notify() {local message="$1"local status="$2"log"$message"if [ -n "$NOTIFICATION_URL" ]; thencurl -X POST -H 'Content-type: application/json' \--data "{\"text\":\"$message\", \"status\":\"$status\"}" \"$NOTIFICATION_URL" || truefi
}# 执行同步任务
run_sync() {local script="$1"local name="$2"if [ -f "$script" ]; thenlog"开始同步 $name"if"$script"; thennotify "$name 同步成功""success"elsenotify "$name 同步失败""error"return 1fielselog"同步脚本不存在: $script"return 1fi
}# 主执行流程
main() {log"开始镜像同步任务"local failed=0# 同步Ubunturun_sync "$SCRIPT_DIR/sync-ubuntu.sh""Ubuntu" || ((failed++))# 同步CentOSrun_sync "$SCRIPT_DIR/sync-centos.sh""CentOS" || ((failed++))# 清理旧日志find "$LOG_DIR" -name "*.log" -mtime +30 -deleteif [ $failed -eq 0 ]; thennotify "所有镜像同步完成""success"elsenotify "有 $failed 个镜像同步失败""warning"filog"镜像同步任务结束"
}main "$@"
配置定时任务
# 编辑crontab
sudo crontab -e# 添加定时任务
# 每天凌晨2点同步
0 2 * * * /data/mirrors/scripts/sync-all.sh# 每周日凌晨1点清理Docker Registry
0 1 * * 0 /data/mirrors/scripts/cleanup-docker.sh# 每小时检查服务状态
0 * * * * /data/mirrors/scripts/health-check.sh
健康检查脚本
# 创建健康检查脚本
sudo nano /data/mirrors/scripts/health-check.sh
#!/bin/bash
# 服务健康检查脚本SERVICES=("nginx""docker")
LOG_FILE="/data/mirrors/logs/health-check.log"log() {echo"[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}check_service() {local service="$1"if systemctl is-active --quiet "$service"; thenlog"$service 服务正常运行"return 0elselog"$service 服务异常,尝试重启"systemctl restart "$service"sleep 5if systemctl is-active --quiet "$service"; thenlog"$service 服务重启成功"return 0elselog"$service 服务重启失败"return 1fifi
}check_disk_space() {local usage=$(df /data/mirrors | awk 'NR==2 {print $5}' | sed 's/%//')if [ "$usage" -gt 85 ]; thenlog"磁盘空间不足: ${usage}%"# 发送告警return 1elselog"磁盘空间正常: ${usage}%"return 0fi
}# 主检查流程
main() {local failed=0# 检查服务状态for service in"${SERVICES[@]}"; docheck_service "$service" || ((failed++))done# 检查磁盘空间check_disk_space || ((failed++))# 检查网络连通性if ! curl -s --max-time 10 http://localhost/status > /dev/null; thenlog"Web服务访问异常"((failed++))fiif [ $failed -eq 0 ]; thenlog"所有检查项正常"elselog"发现 $failed 个异常项"fi
}main "$@"
高可用与负载均衡
配置HAProxy负载均衡
# 安装HAProxy
sudo apt install -y haproxy# 配置HAProxy
sudo nano /etc/haproxy/haproxy.cfg
globaldaemonchroot /var/lib/haproxystats socket /run/haproxy/admin.sock mode 660 level adminstats timeout 30suser haproxygroup haproxydefaultsmode httptimeout connect 5000mstimeout client 50000mstimeout server 50000msoption httplogoption dontlognullerrorfile 400 /etc/haproxy/errors/400.httperrorfile 403 /etc/haproxy/errors/403.httperrorfile 408 /etc/haproxy/errors/408.httperrorfile 500 /etc/haproxy/errors/500.httperrorfile 502 /etc/haproxy/errors/502.httperrorfile 503 /etc/haproxy/errors/503.httperrorfile 504 /etc/haproxy/errors/504.httpfrontend mirror_frontendbind *:80bind *:443 ssl crt /etc/ssl/certs/mirror.pemredirect scheme https if !{ ssl_fc }# 根据域名分发acl is_ubuntu hdr(host) -i ubuntu-mirror.example.comacl is_centos hdr(host) -i centos-mirror.example.comacl is_docker hdr(host) -i docker-registry.example.comuse_backend ubuntu_backend if is_ubuntuuse_backend centos_backend if is_centosuse_backend docker_backend if is_dockerdefault_backend ubuntu_backendbackend ubuntu_backendbalance roundrobinoption httpchk GET /statusserver ubuntu1 192.168.1.10:80 checkserver ubuntu2 192.168.1.11:80 check backupbackend centos_backendbalance roundrobinoption httpchk GET /statusserver centos1 192.168.1.10:80 checkserver centos2 192.168.1.11:80 check backupbackend docker_backendbalance roundrobinoption httpchk GET /v2/server docker1 192.168.1.10:5000 checkserver docker2 192.168.1.11:5000 check backuplisten statsbind *:8404stats enablestats uri /statsstats refresh 30sstats admin if TRUE
配置Keepalived高可用
# 安装Keepalived
sudo apt install -y keepalived# 主节点配置
sudo nano /etc/keepalived/keepalived.conf
# 主节点配置
vrrp_script chk_haproxy {script "/bin/kill -0 `cat /var/run/haproxy.pid`"interval 2weight 2fall 3rise 2
}vrrp_instance VI_1 {state MASTERinterface eth0virtual_router_id 51priority 101advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.1.100}track_script {chk_haproxy}
}
监控与维护
配置Prometheus监控
# 创建Prometheus配置
sudo nano /etc/prometheus/prometheus.yml
global:scrape_interval:15s
evaluation_interval:15srule_files:
-"mirror_rules.yml"scrape_configs:
-job_name:'prometheus'static_configs:-targets: ['localhost:9090']-job_name:'node-exporter'static_configs:-targets: ['localhost:9100']-job_name:'nginx'static_configs:-targets: ['localhost:9113']-job_name:'haproxy'static_configs:-targets: ['localhost:8404']alerting:
alertmanagers:-static_configs:-targets:-alertmanager:9093
创建告警规则
# 创建告警规则
sudo nano /etc/prometheus/mirror_rules.yml
groups:
-name:mirror_alerts
rules:
-alert:HighDiskUsageexpr:(node_filesystem_size_bytes{mountpoint="/data"}-node_filesystem_free_bytes{mountpoint="/data"})/node_filesystem_size_bytes{mountpoint="/data"}*100>85for:5mlabels:severity:warningannotations:summary:"磁盘使用率过高"description:"镜像存储磁盘使用率超过85%"-alert:ServiceDownexpr:up==0for:2mlabels:severity:criticalannotations:summary:"服务不可用"description:"{{ $labels.instance }} 服务已停止"-alert:HighMemoryUsageexpr:(1-(node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes))*100>90for:5mlabels:severity:warningannotations:summary:"内存使用率过高"description:"内存使用率超过90%"-alert:SyncJobFailedexpr:increase(sync_job_failures_total[1h])>0for:0mlabels:severity:criticalannotations:summary:"镜像同步失败"description:"镜像同步任务执行失败"
Grafana仪表板
{"dashboard":{"id":null,"title":"Linux Mirror Repository Dashboard","tags":["mirror","linux"],"timezone":"browser","panels":[{"title":"磁盘使用率","type":"stat","targets":[{"expr":"(node_filesystem_size_bytes{mountpoint=\"/data\"} - node_filesystem_free_bytes{mountpoint=\"/data\"}) / node_filesystem_size_bytes{mountpoint=\"/data\"} * 100","legendFormat":"磁盘使用率"}],"fieldConfig":{"defaults":{"unit":"percent","thresholds":{"steps":[{"color":"green","value":null},{"color":"yellow","value":70},{"color":"red","value":85}]}}}},{"title":"网络流量","type":"graph","targets":[{"expr":"rate(node_network_receive_bytes_total{device=\"eth0\"}[5m])","legendFormat":"接收"},{"expr":"rate(node_network_transmit_bytes_total{device=\"eth0\"}[5m])","legendFormat":"发送"}]},{"title":"同步状态","type":"table","targets":[{"expr":"sync_last_success_timestamp_seconds","legendFormat":"最后同步时间"}]}],"time":{"from":"now-1h","to":"now"},"refresh":"30s"
}
}
安全配置
SSL/TLS配置
# 生成SSL证书
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \-keyout /etc/ssl/private/mirror.key \-out /etc/ssl/certs/mirror.crt \-subj "/C=CN/ST=Beijing/L=Beijing/O=Company/CN=mirror.example.com"# 合并证书文件(HAProxy使用)
sudocat /etc/ssl/certs/mirror.crt /etc/ssl/private/mirror.key > /etc/ssl/certs/mirror.pem
访问控制
# IP白名单配置
geo$allowed_ip {default0;192.168.0.0/16 1;10.0.0.0/8 1;172.16.0.0/12 1;
}server {listen80;server_name mirror.example.com;# IP访问控制if ($allowed_ip = 0) {return403;}# 限制连接数limit_conn_zone$binary_remote_addr zone=conn_limit_per_ip:10m;limit_conn conn_limit_per_ip 10;# 限制请求频率limit_req_zone$binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;limit_req zone=req_limit_per_ip burst=20 nodelay;location / {# 基本认证(可选)auth_basic"Private Mirror";auth_basic_user_file /etc/nginx/.htpasswd;# 其他配置...}
}
防火墙配置
# UFW防火墙配置
sudo ufw default deny incoming
sudo ufw default allow outgoing# 允许SSH
sudo ufw allow ssh# 允许HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp# 允许内网访问
sudo ufw allow from 192.168.0.0/16 to any port 80
sudo ufw allow from 10.0.0.0/8 to any port 80# 启用防火墙
sudo ufw enable
故障排除
常见问题诊断
1. 同步失败问题
# 检查网络连通性
curl -I http://archive.ubuntu.com/ubuntu/# 检查磁盘空间
df -h /data/mirrors# 检查权限
ls -la /data/mirrors/# 查看同步日志
tail -f /data/mirrors/logs/ubuntu-sync-*.log
2. 服务访问问题
# 检查Nginx状态
sudo systemctl status nginx
sudo nginx -t# 检查端口监听
sudo netstat -tlnp | grep :80# 检查防火墙
sudo ufw status# 测试本地访问
curl -I http://localhost/
3. 性能问题
# 检查系统负载
top
htop
iotop# 检查网络流量
iftop
nethogs# 检查磁盘IO
iostat -x 1
故障恢复脚本
# 创建故障恢复脚本
sudo nano /data/mirrors/scripts/recovery.sh
#!/bin/bash
# 故障恢复脚本SERVICES=("nginx""docker""haproxy")
BACKUP_DIR="/data/backup"# 服务恢复
recover_services() {for service in"${SERVICES[@]}"; doif ! systemctl is-active --quiet "$service"; thenecho"恢复服务: $service"systemctl restart "$service"sleep 5if systemctl is-active --quiet "$service"; thenecho"$service 恢复成功"elseecho"$service 恢复失败"fifidone
}# 配置文件恢复
recover_configs() {if [ -d "$BACKUP_DIR" ]; thenecho"恢复配置文件..."# 恢复Nginx配置if [ -f "$BACKUP_DIR/nginx.conf" ]; thencp"$BACKUP_DIR/nginx.conf" /etc/nginx/nginx.confnginx -t && systemctl reload nginxfi# 恢复HAProxy配置if [ -f "$BACKUP_DIR/haproxy.cfg" ]; thencp"$BACKUP_DIR/haproxy.cfg" /etc/haproxy/haproxy.cfgsystemctl reload haproxyfifi
}# 数据完整性检查
check_data_integrity() {echo"检查数据完整性..."# 检查Ubuntu镜像if [ -f "/data/mirrors/ubuntu/mirror/dists/jammy/Release" ]; thenecho"Ubuntu镜像完整"elseecho"Ubuntu镜像损坏,需要重新同步"/data/mirrors/scripts/sync-ubuntu.shfi# 检查CentOS镜像if [ -f "/data/mirrors/centos/8-stream/baseos/repodata/repomd.xml" ]; thenecho"CentOS镜像完整"elseecho"CentOS镜像损坏,需要重新同步"/data/mirrors/scripts/sync-centos.shfi
}# 主恢复流程
main() {echo"开始故障恢复..."recover_servicesrecover_configscheck_data_integrityecho"故障恢复完成"
}main "$@"
监控脚本
# 创建监控脚本
sudo nano /data/mirrors/scripts/monitor.sh
#!/bin/bash
# 实时监控脚本ALERT_EMAIL="admin@example.com"
WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"send_alert() {local message="$1"local severity="$2"echo"[$(date)] ALERT [$severity]: $message"# 发送邮件告警echo"$message" | mail -s "Mirror Alert [$severity]""$ALERT_EMAIL"# 发送Webhook通知curl -X POST -H 'Content-type: application/json' \--data "{\"text\":\"$message\", \"severity\":\"$severity\"}" \"$WEBHOOK_URL"
}# 检查磁盘空间
check_disk() {local usage=$(df /data/mirrors | awk 'NR==2 {print $5}' | sed 's/%//')if [ "$usage" -gt 90 ]; thensend_alert "磁盘空间严重不足: ${usage}%""CRITICAL"elif [ "$usage" -gt 80 ]; thensend_alert "磁盘空间不足: ${usage}%""WARNING"fi
}# 检查同步状态
check_sync() {local last_sync=$(stat -c %Y /data/mirrors/ubuntu/last_update 2>/dev/null || echo 0)local current_time=$(date +%s)local diff=$((current_time - last_sync))# 如果超过24小时未同步if [ $diff -gt 86400 ]; thensend_alert "Ubuntu镜像同步超时: $((diff/3600))小时""WARNING"fi
}# 检查服务状态
check_services() {local services=("nginx""docker")for service in"${services[@]}"; doif ! systemctl is-active --quiet "$service"; thensend_alert "$service 服务异常""CRITICAL"fidone
}# 主监控循环
main() {whiletrue; docheck_diskcheck_synccheck_servicessleep 300 # 5分钟检查一次done
}main "$@"