
轉自:馬哥Linux運維

概述
為什麼需要私有映象倉庫?
在企業環境中,搭建私有Linux映象倉庫具有以下優勢:
-
• 網路最佳化:減少外網頻寬消耗,提升下載速度 -
• 安全控制:內網環境下的安全軟體分發 -
• 版本管理:統一管理軟體包版本,確保環境一致性 -
• 離線部署:支援無外網環境的軟體安裝 -
• 成本節約:減少重複下載,節省頻寬成本
架構設計
環境準備
硬體要求
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
軟體環境
# 作業系統: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/logssudomkdir -p /data/mirrors/scriptssudomkdir -p /etc/mirrors
搭建APT私有映象源
安裝apt-mirror
# Ubuntu/Debian系統sudo apt updatesudo apt install -y apt-mirror nginx# 建立映象使用者sudo useradd -r -s /bin/false -d /data/mirrors aptmirrorsudochown -R aptmirror:aptmirror /data/mirrors
配置apt-mirror
# 編輯配置檔案sudo nano /etc/apt/mirror.list
# /etc/apt/mirror.list############# config ##################set base_path /data/mirrors/ubuntuset mirror_path $base_path/mirrorset skel_path $base_path/skelset var_path $base_path/varset cleanscript $var_path/clean.shset defaultarch amd64set postmirror_script $var_path/postmirror.shset run_postmirror 0set nthreads 20set _tilde 0############# end config ############### Ubuntu 22.04 LTS (Jammy)deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiversedeb http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiversedeb http://archive.ubuntu.com/ubuntu jammy-backports main restricted universe multiversedeb 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 multiversedeb http://archive.ubuntu.com/ubuntu focal-updates main restricted universe multiversedeb http://archive.ubuntu.com/ubuntu focal-backports main restricted universe multiversedeb 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/ubuntuclean 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 1fi# 建立鎖檔案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 -tsudo 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 1fiecho $$ > "$LOCKFILE"cleanup() {rm -f "$LOCKFILE"}trap cleanup EXITecho"開始CentOS映象同步: $(date)" | tee -a "$LOGFILE"# 同步CentOS 8 Streamsync_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 - BaseOSbaseurl=http://your-mirror.example.com/centos/8-stream/baseos/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial[appstream]name=CentOS Stream $releasever - AppStreambaseurl=http://your-mirror.example.com/centos/8-stream/appstream/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial[extras]name=CentOS Stream $releasever - Extrasbaseurl=http://your-mirror.example.com/centos/8-stream/extras/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial[powertools]name=CentOS Stream $releasever - PowerToolsbaseurl=http://your-mirror.example.com/centos/8-stream/powertools/gpgcheck=1enabled=0gpgkey=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
# 安裝Dockercurl -fsSL https://get.docker.com | shsudo usermod -aG docker $USER# 建立Registry目錄sudomkdir -p /data/mirrors/docker/{registry,auth,certs}
配置Registry
# 建立Registry配置檔案sudo nano /data/mirrors/docker/config.yml
version:0.1log:accesslog:disabled:falselevel:infoformatter:textfields:service:registrystorage:cache:blobdescriptor:inmemoryfilesystem:rootdirectory:/var/lib/registrydelete:enabled:truehttp:addr::5000headers: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.iousername:your-dockerhub-usernamepassword: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/dockersudo 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_timeout900; }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" ]; then curl -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"; then notify "$name 同步成功""success"else notify "$name 同步失敗""error"return 1fielselog"同步指令碼不存在: $script"return 1fi}# 主執行流程main() {log"開始映象同步任務"local failed=0# 同步Ubuntu run_sync "$SCRIPT_DIR/sync-ubuntu.sh""Ubuntu" || ((failed++))# 同步CentOS run_sync "$SCRIPT_DIR/sync-centos.sh""CentOS" || ((failed++))# 清理舊日誌 find "$LOG_DIR" -name "*.log" -mtime +30 -deleteif [ $failed -eq 0 ]; then notify "所有映象同步完成""success"else notify "有 $failed 個映象同步失敗""warning"filog"映象同步任務結束"}main "$@"
配置定時任務
# 編輯crontabsudo crontab -e# 新增定時任務# 每天凌晨2點同步0 2 * * * /data/mirrors/scripts/sync-all.sh# 每週日凌晨1點清理Docker Registry0 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[@]}"; do check_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負載均衡
# 安裝HAProxysudo apt install -y haproxy# 配置HAProxysudo nano /etc/haproxy/haproxy.cfg
global daemon chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s user haproxy group haproxydefaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms option httplog option dontlognull errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.httpfrontend mirror_frontend bind *:80 bind *:443 ssl crt /etc/ssl/certs/mirror.pem redirect scheme https if !{ ssl_fc } # 根據域名分發 acl is_ubuntu hdr(host) -i ubuntu-mirror.example.com acl is_centos hdr(host) -i centos-mirror.example.com acl is_docker hdr(host) -i docker-registry.example.com use_backend ubuntu_backend if is_ubuntu use_backend centos_backend if is_centos use_backend docker_backend if is_docker default_backend ubuntu_backendbackend ubuntu_backend balance roundrobin option httpchk GET /status server ubuntu1 192.168.1.10:80 check server ubuntu2 192.168.1.11:80 check backupbackend centos_backend balance roundrobin option httpchk GET /status server centos1 192.168.1.10:80 check server centos2 192.168.1.11:80 check backupbackend docker_backend balance roundrobin option httpchk GET /v2/ server docker1 192.168.1.10:5000 check server docker2 192.168.1.11:5000 check backuplisten stats bind *:8404 stats enable stats uri /stats stats refresh 30s stats admin if TRUE
配置Keepalived高可用
# 安裝Keepalivedsudo apt install -y keepalived# 主節點配置sudo nano /etc/keepalived/keepalived.conf
# 主節點配置vrrp_script chk_haproxy { script "/bin/kill -0 `cat /var/run/haproxy.pid`" interval 2 weight 2 fall 3 rise 2}vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 101 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.100 } track_script { chk_haproxy }}
監控與維護
配置Prometheus監控
# 建立Prometheus配置sudo nano /etc/prometheus/prometheus.yml
global:scrape_interval:15sevaluation_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_alertsrules:-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 incomingsudo ufw default allow outgoing# 允許SSHsudo ufw allow ssh# 允許HTTP/HTTPSsudo ufw allow 80/tcpsudo ufw allow 443/tcp# 允許內網訪問sudo ufw allow from 192.168.0.0/16 to any port 80sudo 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 nginxsudo nginx -t# 檢查埠監聽sudo netstat -tlnp | grep :80# 檢查防火牆sudo ufw status# 測試本地訪問curl -I http://localhost/
3. 效能問題
# 檢查系統負載tophtopiotop# 檢查網路流量iftopnethogs# 檢查磁碟IOiostat -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.conf nginx -t && systemctl reload nginxfi# 恢復HAProxy配置if [ -f "$BACKUP_DIR/haproxy.cfg" ]; thencp"$BACKUP_DIR/haproxy.cfg" /etc/haproxy/haproxy.cfg systemctl 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_services recover_configs check_data_integrityecho"故障恢復完成"}main "$@"
監控指令碼
# 建立監控指令碼sudo nano /data/mirrors/scripts/monitor.sh
#!/bin/bash# 即時監控指令碼ALERT_EMAIL="[email protected]"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 ]; then send_alert "磁碟空間嚴重不足: ${usage}%""CRITICAL"elif [ "$usage" -gt 80 ]; then send_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 ]; then send_alert "Ubuntu映象同步超時: $((diff/3600))小時""WARNING"fi}# 檢查服務狀態check_services() {local services=("nginx""docker")for service in"${services[@]}"; doif ! systemctl is-active --quiet "$service"; then send_alert "$service 服務異常""CRITICAL"fidone}# 主監控迴圈main() {whiletrue; do check_disk check_sync check_servicessleep 300 # 5分鐘檢查一次done}main "$@"
總結
透過本文的詳細指南,我們成功搭建了一個完整的私有Linux映象倉庫系統,包括:
核心功能
-
• 多發行版支援:Ubuntu、CentOS、Docker映象 -
• 自動化同步:定時同步上游映象源 -
• 負載均衡:HAProxy + Keepalived高可用方案 -
• 監控告警:Prometheus + Grafana監控體系
運維特性
-
• 安全加固:SSL/TLS、訪問控制、防火牆配置 -
• 故障恢復:自動化故障檢測和恢復機制 -
• 效能最佳化:快取策略、併發控制 -
• 日誌管理:完整的日誌記錄和輪轉
最佳實踐
-
1. 定期備份:配置檔案和關鍵資料的定期備份 -
2. 容量規劃:根據使用情況合理規劃儲存容量 -
3. 網路最佳化:配置適當的快取和CDN策略 -
4. 安全更新:及時更新系統和軟體包
這套方案可以滿足企業級的私有映象倉庫需求,提供穩定、高效、安全的軟體包分發服務。
想要學習Linux系統的讀者可以點選"閱讀原文"按鈕來了解書籍《Linux就該這麼學》,同時也非常適合專業的運維人員閱讀,成為輔助您工作的高價值工具書!