搭建私有Linux映象倉庫:從零到生產的完整指南

轉自:馬哥Linux運維

概述

為什麼需要私有映象倉庫?

在企業環境中,搭建私有Linux映象倉庫具有以下優勢:
  • • 網路最佳化:減少外網頻寬消耗,提升下載速度
  • • 安全控制:內網環境下的安全軟體分發
  • • 版本管理:統一管理軟體包版本,確保環境一致性
  • • 離線部署:支援無外網環境的軟體安裝
  • • 成本節約:減少重複下載,節省頻寬成本

架構設計

客戶端

負載均衡器

映象伺服器1

映象伺服器2

儲存後端

同步伺服器

上游映象源

環境準備

硬體要求

元件
最低配置
推薦配置
生產環境
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/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() {whiletruedo        check_disk        check_sync        check_servicessleep 300  # 5分鐘檢查一次done}main "$@"

總結

透過本文的詳細指南,我們成功搭建了一個完整的私有Linux映象倉庫系統,包括:

核心功能

  • • 多發行版支援:Ubuntu、CentOS、Docker映象
  • • 自動化同步:定時同步上游映象源
  • • 負載均衡:HAProxy + Keepalived高可用方案
  • • 監控告警:Prometheus + Grafana監控體系

運維特性

  • • 安全加固:SSL/TLS、訪問控制、防火牆配置
  • • 故障恢復:自動化故障檢測和恢復機制
  • • 效能最佳化:快取策略、併發控制
  • • 日誌管理:完整的日誌記錄和輪轉

最佳實踐

  1. 1. 定期備份:配置檔案和關鍵資料的定期備份
  2. 2. 容量規劃:根據使用情況合理規劃儲存容量
  3. 3. 網路最佳化:配置適當的快取和CDN策略
  4. 4. 安全更新:及時更新系統和軟體包
這套方案可以滿足企業級的私有映象倉庫需求,提供穩定、高效、安全的軟體包分發服務。
END
想要學習Linux系統的讀者可以點選"閱讀原文"按鈕來了解書籍《Linux就該這麼學》,同時也非常適合專業的運維人員閱讀,成為輔助您工作的高價值工具書!

相關文章