首页
留言
导航
统计
Search
1
追番推荐!免费看动漫的网站 - 支持在线观看和磁力下载
2,510 阅读
2
推荐31个docker应用,每一个都很实用
1,311 阅读
3
PVE自动启动 虚拟机 | 容器 顺序设置及参数说明
931 阅读
4
一条命令,永久激活!Office 2024!
618 阅读
5
优选 Cloudflare 官方 / 中转 IP
490 阅读
默认分类
服务器
宝塔
VPS
Docker
OpenWRT
Nginx
群晖
前端编程
Vue
React
Angular
NodeJS
uni-app
后端编程
Java
Python
SpringBoot
SpringCloud
流程引擎
检索引擎
Linux
CentOS
Ubuntu
Debian
数据库
Redis
MySQL
Oracle
虚拟机
VMware
VirtualBox
PVE
Hyper-V
计算机
网络技术
网站源码
主题模板
登录
Search
标签搜索
Java
小程序
Redis
SpringBoot
docker
Typecho
Cloudflare
docker部署
虚拟机
WordPress
群晖
uni-app
CentOS
Vue
Java类库
Linux命令
防火墙配置
Mysql
脚本
Nginx
微醺
累计撰写
264
篇文章
累计收到
11
条评论
首页
栏目
默认分类
服务器
宝塔
VPS
Docker
OpenWRT
Nginx
群晖
前端编程
Vue
React
Angular
NodeJS
uni-app
后端编程
Java
Python
SpringBoot
SpringCloud
流程引擎
检索引擎
Linux
CentOS
Ubuntu
Debian
数据库
Redis
MySQL
Oracle
虚拟机
VMware
VirtualBox
PVE
Hyper-V
计算机
网络技术
网站源码
主题模板
页面
留言
导航
统计
搜索到
33
篇与
的结果
2025-08-13
搭建私有 Linux 镜像仓库:从零到生产的完整指南(ubuntu,centos,docker)
概述为什么需要私有镜像仓库?在企业环境中,搭建私有Linux镜像仓库具有以下优势:网络优化:减少外网带宽消耗,提升下载速度安全控制:内网环境下的安全软件分发版本管理:统一管理软件包版本,确保环境一致性离线部署:支持无外网环境的软件安装成本节约:减少重复下载,节省带宽成本架构设计环境准备硬件要求组件最低配置推荐配置生产环境CPU2核4核8核+内存4GB8GB16GB+存储500GB2TB10TB+网络100Mbps1Gbps10Gbps软件环境# 操作系统: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 -e LOGFILE="/data/mirrors/logs/ubuntu-sync-$(date +%Y%m%d-%H%M%S).log" LOCKFILE="/var/run/ubuntu-mirror.lock" # 检查锁文件 if [ -f "$LOCKFILE" ]; then echo"同步进程已在运行,退出..." exit 1 fi # 创建锁文件 echo $$ > "$LOCKFILE" # 清理函数 cleanup() { rm -f "$LOCKFILE" } trap cleanup EXIT echo"开始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_update echo"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-mirrorserver { 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 -e MIRROR_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" ]; then echo"同步进程已在运行,退出..." exit 1 fi echo $$ > "$LOCKFILE" cleanup() { rm -f "$LOCKFILE" } trap cleanup EXIT echo"开始CentOS镜像同步: $(date)" | tee -a "$LOGFILE" # 同步CentOS 8 Stream sync_centos_stream() { local version=$1 local repo_dir="$MIRROR_BASE/$version" mkdir -p "$repo_dir" # 同步各个仓库 for repo in baseos appstream extras powertools; do echo"同步 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-centosofficialNginx配置(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.ymlversion:0.1 log: accesslog: disabled:false level:info formatter:text fields: service:registry storage: cache: blobdescriptor:inmemory filesystem: rootdirectory:/var/lib/registry delete: enabled:true http: 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:true interval:10s threshold:3 proxy: remoteurl:https://registry-1.docker.io username:your-dockerhub-username password:your-dockerhub-password启动Registry服务# 创建docker-compose文件 sudo nano /data/mirrors/docker/docker-compose.ymlversion:'3.8' services: registry: image:registry:2.8 container_name:docker-registry restart:unless-stopped ports: -"5000:5000" environment: REGISTRY_CONFIG_PATH:/etc/docker/registry/config.yml REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY:/var/lib/registry volumes: -/data/mirrors/docker/registry:/var/lib/registry -/data/mirrors/docker/config.yml:/etc/docker/registry/config.yml:ro networks: -registry-net registry-ui: image:joxit/docker-registry-ui:latest container_name:registry-ui restart:unless-stopped ports: -"8080:80" environment: REGISTRY_TITLE:"Private Docker Registry" REGISTRY_URL:http://registry:5000 DELETE_IMAGES:"true" SHOW_CONTENT_DIGEST:"true" depends_on: -registry networks: -registry-net networks: 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_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 -e SCRIPT_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" || true fi } # 执行同步任务 run_sync() { local script="$1" local name="$2" if [ -f "$script" ]; then log"开始同步 $name" if"$script"; then notify "$name 同步成功""success" else notify "$name 同步失败""error" return 1 fi else log"同步脚本不存在: $script" return 1 fi } # 主执行流程 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 -delete if [ $failed -eq 0 ]; then notify "所有镜像同步完成""success" else notify "有 $failed 个镜像同步失败""warning" fi log"镜像同步任务结束" } 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"; then log"$service 服务正常运行" return 0 else log"$service 服务异常,尝试重启" systemctl restart "$service" sleep 5 if systemctl is-active --quiet "$service"; then log"$service 服务重启成功" return 0 else log"$service 服务重启失败" return 1 fi fi } check_disk_space() { local usage=$(df /data/mirrors | awk 'NR==2 {print $5}' | sed 's/%//') if [ "$usage" -gt 85 ]; then log"磁盘空间不足: ${usage}%" # 发送告警 return 1 else log"磁盘空间正常: ${usage}%" return 0 fi } # 主检查流程 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; then log"Web服务访问异常" ((failed++)) fi if [ $failed -eq 0 ]; then log"所有检查项正常" else log"发现 $failed 个异常项" fi } main "$@"高可用与负载均衡配置HAProxy负载均衡# 安装HAProxy sudo apt install -y haproxy # 配置HAProxy sudo nano /etc/haproxy/haproxy.cfgglobal daemon chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s user haproxy group haproxy defaults 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.http frontend 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_backend backend ubuntu_backend balance roundrobin option httpchk GET /status server ubuntu1 192.168.1.10:80 check server ubuntu2 192.168.1.11:80 check backup backend centos_backend balance roundrobin option httpchk GET /status server centos1 192.168.1.10:80 check server centos2 192.168.1.11:80 check backup backend docker_backend balance roundrobin option httpchk GET /v2/ server docker1 192.168.1.10:5000 check server docker2 192.168.1.11:5000 check backup listen stats bind *:8404 stats enable stats uri /stats stats refresh 30s stats 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 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.ymlglobal: scrape_interval:15s evaluation_interval:15s rule_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.ymlgroups: -name:mirror_alerts rules: -alert:HighDiskUsage expr:(node_filesystem_size_bytes{mountpoint="/data"}-node_filesystem_free_bytes{mountpoint="/data"})/node_filesystem_size_bytes{mountpoint="/data"}*100>85 for:5m labels: severity:warning annotations: summary:"磁盘使用率过高" description:"镜像存储磁盘使用率超过85%" -alert:ServiceDown expr:up==0 for:2m labels: severity:critical annotations: summary:"服务不可用" description:"{{ $labels.instance }} 服务已停止" -alert:HighMemoryUsage expr:(1-(node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes))*100>90 for:5m labels: severity:warning annotations: summary:"内存使用率过高" description:"内存使用率超过90%" -alert:SyncJobFailed expr:increase(sync_job_failures_total[1h])>0 for:0m labels: severity:critical annotations: 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-*.log2. 服务访问问题# 检查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[@]}"; do if ! systemctl is-active --quiet "$service"; then echo"恢复服务: $service" systemctl restart "$service" sleep 5 if systemctl is-active --quiet "$service"; then echo"$service 恢复成功" else echo"$service 恢复失败" fi fi done } # 配置文件恢复 recover_configs() { if [ -d "$BACKUP_DIR" ]; then echo"恢复配置文件..." # 恢复Nginx配置 if [ -f "$BACKUP_DIR/nginx.conf" ]; then cp"$BACKUP_DIR/nginx.conf" /etc/nginx/nginx.conf nginx -t && systemctl reload nginx fi # 恢复HAProxy配置 if [ -f "$BACKUP_DIR/haproxy.cfg" ]; then cp"$BACKUP_DIR/haproxy.cfg" /etc/haproxy/haproxy.cfg systemctl reload haproxy fi fi } # 数据完整性检查 check_data_integrity() { echo"检查数据完整性..." # 检查Ubuntu镜像 if [ -f "/data/mirrors/ubuntu/mirror/dists/jammy/Release" ]; then echo"Ubuntu镜像完整" else echo"Ubuntu镜像损坏,需要重新同步" /data/mirrors/scripts/sync-ubuntu.sh fi # 检查CentOS镜像 if [ -f "/data/mirrors/centos/8-stream/baseos/repodata/repomd.xml" ]; then echo"CentOS镜像完整" else echo"CentOS镜像损坏,需要重新同步" /data/mirrors/scripts/sync-centos.sh fi } # 主恢复流程 main() { echo"开始故障恢复..." recover_services recover_configs check_data_integrity echo"故障恢复完成" } 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 ]; 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[@]}"; do if ! systemctl is-active --quiet "$service"; then send_alert "$service 服务异常""CRITICAL" fi done } # 主监控循环 main() { whiletrue; do check_disk check_sync check_services sleep 300 # 5分钟检查一次 done } main "$@"总结通过本文的详细指南,我们成功搭建了一个完整的私有 Linux 镜像仓库系统,包括:核心功能• 多发行版支持:Ubuntu、CentOS、Docker镜像• 自动化同步:定时同步上游镜像源• 负载均衡:HAProxy + Keepalived高可用方案• 监控告警:Prometheus + Grafana监控体系运维特性• 安全加固:SSL/TLS、访问控制、防火墙配置• 故障恢复:自动化故障检测和恢复机制• 性能优化:缓存策略、并发控制• 日志管理:完整的日志记录和轮转最佳实践定期备份:配置文件和关键数据的定期备份容量规划:根据使用情况合理规划存储容量网络优化:配置适当的缓存和CDN策略安全更新:及时更新系统和软件包这套方案可以满足企业级的私有镜像仓库需求,提供稳定、高效、安全的软件包分发服务。
2025年08月13日
29 阅读
0 评论
1 点赞
2025-03-11
CentOS 7 ens33获取不到ip地址和启动网卡报错的解决方法
当我们启动虚拟机输入 ifconfig 查看 IP 地址时出现下图这样的情况,发现没有 ens33 移动到 /etc/sysconfig/network-scripts 编辑 ifcfg-ens33cd /etc/sysconfig/network-scripts vim ifcfg-ens33将 ONBOOT=NO 改成 ONBOOT=yes 输入 i 进行编辑;将最后 ONBOOT=no 改为 yes 即可;单击 esc 键,然后输入 :wq 保存退出。这样就开启了 ens33 ;接着重启网络服务就可以看到 ip 地址。重启网络服务service network restart 出现下图表示已经重启成功输入 ifconfig ens33 有了 ip 地址。出现 异常# 关闭NetworkManager服务 systemctl stop NetworkManager systemctl restart network.service service network restart # 问题解决
2025年03月11日
63 阅读
0 评论
0 点赞
2024-10-19
apt 和 apt-get的区别
前言在开始对比 apt 与 apt-get 命令的区别之前,我们先来看看这两个命令的背景,以及它们要试图达到的目的。Debian 作为 Ubuntu、Linux Mint 和 elementary OS 等 Linux 操作系统的母板,其具有强健的 「包管理」 系统,它的每个组件和应用程序都内置在系统中安装的软件包中。Debian 使用一套名为 Advanced Packaging Tool(APT) 的工具来管理这种包系统,不过请不要把它与 apt 命令混淆,它们之间是其实不是同一个东西。在基于 Debian 的 Linux 发行版中,有各种工具可以与 APT 进行交互,以方便用户安装、删除和管理的软件包。apt-get 便是其中一款广受欢迎的命令行工具,另外一款较为流行的是 Aptitude 这一命令行与 GUI 兼顾的小工具。如果你已阅读过我们的 apt-get 命令指南,可能已经遇到过许多类似的命令,如 apt-cache、apt-config 等。如你所见,这些命令都比较低级又包含众多功能,普通的 Linux 用户也许永远都不会使用到。换种说法来说,就是最常用的 Linux 包管理命令都被分散在了 apt-get、apt-cache 和 apt-config 这三条命令当中。apt 命令的引入就是为了解决命令过于分散的问题,它包括了 apt-get 命令出现以来使用最广泛的功能选项,以及 apt-cache 和 apt-config 命令中很少用到的功能。在使用 apt 命令时,用户不必再由 apt-get 转到 apt-cache 或 apt-config ,而且 apt 更加结构化,并为用户提供了管理软件包所需的必要选项。简单来说就是:apt = apt-get、apt-cache 和 apt-config 中最常用命令选项的集合。虽然 apt 与 apt-get 有一些类似的命令选项,但它并不能完全向下兼容 apt-get 命令。也就是说,可以用 apt 替换部分 apt-get 系列命令,但不是全部。apt 命令取代的命令命令的功能apt installapt-get install安装软件包apt removeapt-get remove移除软件包apt purgeapt-get purge移除软件包及配置文件apt updateapt-get update刷新存储库索引apt upgradeapt-get upgrade升级所有可升级的软件包apt autoremoveapt-get autoremove自动删除不需要的包apt full-upgradeapt-get dist-upgrade在升级软件包时自动处理依赖关系apt searchapt-cache search搜索应用程序apt showapt-cache show显示装细节当然,apt 还有一些自己的命令:新的apt命令命令的功能apt list列出包含条件的包(已安装,可升级等)apt edit-sources编辑源列表需要大家注意的是: apt 命令也还在不断发展, 因此,你可能会在将来的版本中看到新的选项。apt-get已弃用?目前还没有任何 Linux 发行版官方放出 apt-get 将被停用的消息,至少它还有比 apt 更多、更细化的操作功能。对于低级操作,仍然需要 apt-get。我应该使用 apt 还是 apt-get ?既然两个命令都有用,那么我该使用 apt 还是 apt-get 呢?作为一个常规 Linux 用户,系统极客建议大家尽快适应并开始首先使用 apt。不仅因为广大 Linux 发行商都在推荐 apt,更主要的还是它提供了 Linux 包管理的必要选项。最重要的是,apt 命令选项更少更易记,因此也更易用,所以没理由继续坚持 apt-get。小结最后结大家提供两点使用上的建议:apt 可以看作 apt-get 和 apt-cache 命令的子集, 可以为包管理提供必要的命令选项。apt-get 虽然没被弃用,但作为普通用户,还是应该首先使用 apt。
2024年10月19日
17 阅读
0 评论
0 点赞
2024-09-26
Linux ubuntu debian ufw (防火墙) 使用指南
前言UFW 是 “简单防火墙” 的缩写,是更复杂的 iptables 实用程序的前端。它旨在使管理防火墙变得像设置端口打开和关闭以及调节允许通过的流量一样简单。ufw 可以在 Debian 和 Ubuntu 系统中使用,是默认的防火墙配置工具,默认 ufw 是禁用状态,支持 IPv4 和 IPv6。国内的服务器,一般都会有安全组,如果有安全组,则无须使用 ufw国外的服务器,一般端口全都是放行的,所以有必要使用 ufw如果是 CentOS 系统,可以使用 firewalld,强烈建议弃用 CentOS 系统,官方早已经不维护了,会有很多漏洞无法修复。推荐系统:Debian > Ubuntu >>>>> CentOS提示:以下所有命令默认在 root 环境下运行,如果是非 root 环境,则命令需要加前缀:sudoufw 使用更新软件包apt update apt upgrade -y安装# 安装 apt-get install ufw # 帮助命令 ufw --help推荐配置如果要开启防火墙的话,建议先拒绝所有入站流量,然后逐一打开需要的端口。# 默认阻止入站(不会立即切断你的 SSH 连接,因为防火墙尚未启用) ufw default deny incoming # 默认允许出站 ufw default allow outgoing # 拒绝所有访问(如果配置了入站/出战,这个可以不配置) ufw default deny # 根据需求开启端口 ufw allow 22⚠注意确保在修改 SSH 端口后,不要关闭当前 SSH 窗口,尝试使用新的端口进行 SSH 登录,以确保没有防火墙或其他网络配置问题,以免被自己锁定出服务器。启用禁用# 启用 ufw enable # 查看状态 ufw status verbose # 禁用 ufw disable # 防火墙规则存放位置 # /etc/ufw 中的规则文件(后缀名:.rules)允许拒绝allow 例子:# 接受 97 端口的 tcp/udp 流量 ufw allow 97 # 接受 97 端口的 tcp/udp 流量,并添加备注 ufw allow 97 comment 'open 97 port' # 接受 97 端口的 tcp 流量 ufw allow 97/tcp # 接受 97 端口的 udp 流量 ufw allow 97/udp # 通过服务名来处理, 会从 /etc/services 中查找端口 ufw allow ssh # 允许特定IP访问 ufw allow from 1.2.3.4 # 允许特定子网访问 ufw allow from 1.2.3.4/97 # 允许特定IP使用任何协议访问22端口 ufw allow from 1.2.3.4 to any port 22 # 允许特定IP使用任何TCP协议访问22端口 ufw allow from 1.2.3.4 to any port 22 proto tcpdeny 例子:# 拒绝 97 端口的 tcp/udp 流量 ufw deny 97 # 拒绝 97 端口的 tcp 流量 ufw deny 97/tcp # 拒绝 97 端口的 udp 流量 ufw deny 97/udp # 通过服务名来处理, 会从 /etc/services 中查找端口 ufw deny ssh # 拒绝特定IP访问 ufw deny from 1.2.3.4 # 同allow ufw deny from 1.2.3.4 to any port 22 ufw deny from 1.2.3.4 to any port 22 ufw allow from 1.2.3.4/97 to any port 22 proto tcp删除# 要删除规则,只需在原始规则前加上删除,删除 80 端口的 tcp 配置 ufw delete deny 80/tcp # 显示规则的顺序和ID号 ufw status numbered # 删除编号规则(删除规则,规则将向上移动以填充列表) ufw delete 1日志# 启用日志 ufw logging on # 禁用日志 ufw logging off
2024年09月26日
37 阅读
0 评论
0 点赞
2024-09-26
Linux ufw(防火墙)使用指南,解决ufw和docker冲突问题,保护你的服务器/VPS
前言如果你在服务端使用 Docker 映射了某个宿主机端口,然后公网访问这个端口的话,你会发现仍然可以访问,即使 ufw 禁用了这个端口,却不起效果。因为默认状态下的 Docker 并不遵守 ufw 的防火墙规则解决ufw和docker的问题解决方案:https://github.com/chaifeng/ufw-docker目前新的解决方案只需要修改一个 UFW 配置文件即可,Docker 的所有配置和选项都保持默认。修改 UFW 的配置文件 /etc/ufw/after.rules ,在最后添加上如下规则:# BEGIN UFW AND DOCKER *filter :ufw-user-forward - [0:0] :ufw-docker-logging-deny - [0:0] :DOCKER-USER - [0:0] -A DOCKER-USER -j ufw-user-forward -A DOCKER-USER -j RETURN -s 10.0.0.0/8 -A DOCKER-USER -j RETURN -s 172.16.0.0/12 -A DOCKER-USER -j RETURN -s 192.168.0.0/16 -A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN -A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16 -A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8 -A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12 -A DOCKER-USER -j RETURN -A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] " -A ufw-docker-logging-deny -j DROP COMMIT # END UFW AND DOCKER或者使用 ufw-docker 工具下载脚本,修改 after.rules 文件配置:# 下载脚本 wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker # 赋予权限 chmod +x /usr/local/bin/ufw-docker # 修改配置文件 ufw-docker installufw-docker install 命令做了以下事情:备份文件 /etc/ufw/after.rules把 UFW 和 Docker 的相关规则添加到文件 after.rules 的末尾然后重启 UFW ,systemctl restart ufw 。现在外部就已经无法访问 Docker 发布出来的任何端口了,但是容器内部以及私有网络地址上可以正常互相访问,而且容器也可以正常访问外部的网络。可能由于某些未知原因,重启 UFW 之后规则也无法生效,请重启服务器。如果希望允许外部网络访问 Docker 容器提供的服务,比如有一个容器的服务端口是 80。那就可以用以下命令来允许外部网络访问这个服务:ufw route allow proto tcp from any to any port 80这个命令会允许外部网络访问所有用 Docker 发布出来的并且内部服务端口为 80 的所有服务。请注意,这个端口 80 是容器的端口,而非使用 -p 0.0.0.0:8080:80 选项发布在服务器上的 8080 端口。如果有多个容器的服务端口为 80 ,但只希望外部网络访问某个特定的容器。比如该容器的私有地址为 172.17.0.2 ,就用类似下面的命令:ufw route allow proto tcp from any to 172.17.0.2 port 80如果一个容器的服务是 UDP 协议,假如是 DNS 服务,可以用下面的命令来允许外部网络访问所有发布出来的 DNS 服务:ufw route allow proto udp from any to any port 53同样的,如果只针对一个特定的容器,比如 IP 地址为 172.17.0.2ufw route allow proto udp from any to 172.17.0.2 port 53ufw-docker 也是支持 Docker Swarm 的,详细教程及配置参考文章:https://github.com/chaifeng/ufw-docker
2024年09月26日
197 阅读
0 评论
1 点赞
2024-06-06
解决 /usr/bin/xauth: file /.../.Xauthority does not exist 报错
root账户下执行命令:find / |grep ".Xauthority"普通账户下执行命令:find ~ |grep ".Xauthority"找了下原因,没找到,然后我重新登陆,发现,居然可以了。简直就是大无语事件!!!
2024年06月06日
286 阅读
0 评论
0 点赞
2024-06-06
Linux SSH Access denied(拒绝访问)解决方案
新安装的 CentOS 7 使用 SSH 连接出现 Access denied,记录一下这个坑。详细问题如下(见图):解决方案查了下资料,Linux 系统默认就是禁止远程登录的。那就打开权限就行了。因为需要修改系统设置,普通用户会出现没有权限,所以在超级管理员下操作!编辑配置文件:vim /etc/ssh/sshd_config修改 PermitRootLogin 为 yes退出编辑:按下 'Esc' 键,输入 ':wq',回车保存即可。重启 SSH:systemctl restart sshd大功告成,可以使用 ssh 链接了~~
2024年06月06日
205 阅读
0 评论
0 点赞
2024-02-03
ubuntu 利用systemback制作镜像备份(可用)
前言在ubuntu 22.04版本下,安装 systemback 成功制作出 iso 镜像文件,并在 VM虚拟机 下进行还原安装;移植好的镜像文件包含了当前的系统环境依赖,部署服务,系统文件内的图片,视频等内容。安装软件安装systemback安装make安装cdtools安装systembacksystemback 用来打包系统成压缩包,后再利用 cdtools 将其转换为iso镜像文件。安装systemback工具直接全部复制,粘贴到终端运行:sudo sh -c 'echo "deb [arch=amd64] http://mirrors.bwbot.org/ stable main" > /etc/apt/sources.list.d/systemback.list' sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key 50B2C005A67B264F sudo apt-get update sudo apt-get install systemback安装make编译器sudo apt-get install make安装gcc环境包sudo apt update sudo apt install build-essential安装cdtoolssudo apt install aria2 aria2c -s 10 https://nchc.dl.sourceforge.net/project/cdrtools/alpha/cdrtools-3.02a07.tar.gz下载完成后打开对应文件夹进行解压tar -xzvf cdrtools-3.02a07.tar.gz cd cdrtools-3.02 make make installsystemback系统打包进行 live 打包,执行下面命令:systemback-sustart点击 创建Live 系统可以 包含用户数据文件 点击 创建新的 如果出现报错:错误会在终端中显示出来(大概率由于snap文件内的内容报错)解决方法——卸载报错的软件或者删除报错的文件打包好的文件会生成在上一步选择好的工作目录(默认为 /home )到此已经结束!
2024年02月03日
252 阅读
0 评论
0 点赞
2024-01-29
使用Ubuntu|Debian的 UFW 禁止 ICMP 协议访问(禁 ping)
打开 UFW 配置文件vim /etc/ufw/before.rules修改配置允许 ping-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT禁止 ping-A ufw-before-input -p icmp --icmp-type echo-request -j DROP让配置生效ufw reload
2024年01月29日
73 阅读
0 评论
0 点赞
2024-01-29
Debian/Ubuntu 中安装和配置 UFW 防火墙
前言UFW 是一个 Arch Linux、Debian 或 Ubuntu 中管理防火墙规则的前端,可大大简化防火墙的配置过程。安装 UFW如还没有安装,可以使用 apt 命令来安装apt-get update && apt-get install ufw在使用前,你应该检查下 UFW 是否已经在运行。ufw status如果你发现状态是 inactive ,意思是没有被激活或不起作用。启用/禁用ufw enable #启用 ufw disable #禁用使用与配置列出当前UFW规则ufw status verbose添加规则允许入站(allow)默认情况,没有允许就是拒绝(入站),使用 ufw allow <端口> 来添加允许访问的端口或协议。ufw allow ssh #添加22端口 ufw allow http #添加80端口 ufw allow https #添加443端口 ufw allow 2333/tcp #添加2333端口,仅TCP协议 ufw allow 6666/udp #添加6666端口,仅UDP协议 ufw allow 8888:9999 #添加8888到9999之间的端口拒绝访问(deny)使用 ufw deny <端口> 来添加拒绝入站的端和协议,与添加允许的类似。删除规则先使用 ufw status 查看规则,再使用 ufw delete [规则] <端口> 来删除规则。ufw delete allow 2333/tcp如果你有很多条规则,使用 numbered 参数,可以在每条规则上加个序号数字。然后使用 ufw delete <序号> 来删除规则。root@p3terx:~# ufw status numbered #列出规则,并加上序号。 Status: active To Action From -- ------ ---- [ 1] 20,21,22,80,888,8888/tcp ALLOW IN Anywhere [ 2] 39000:40000/tcp ALLOW IN Anywhere [ 3] 8896/tcp ALLOW IN Anywhere [ 4] 8896/udp ALLOW IN Anywhere [ 5] 443/tcp ALLOW IN Anywhere [ 6] 20,21,22,80,888,8888/tcp (v6) ALLOW IN Anywhere (v6) [ 7] 39000:40000/tcp (v6) ALLOW IN Anywhere (v6) [ 8] 8896/tcp (v6) ALLOW IN Anywhere (v6) [ 9] 8896/udp (v6) ALLOW IN Anywhere (v6) [10] 443/tcp (v6) ALLOW IN Anywhere (v6) root@p3terx:~# ufw delete 4 #删除上面的第4条规则 Deleting: allow 8896/udp Proceed with operation (y|n)? y #最后会询问你是否进行操作以上都是一些简单常用的一些命令,想要深入了解,可以输入 man ufw 查看 ufw 用户手册。
2024年01月29日
31 阅读
0 评论
0 点赞
1
2
...
4