Rocky Linux 10.2 Minimal Docker compose安装Nginx+Keepalived实现双机主备高可用

1、更新系统并安装Docker及Docker compose

# 1.更新系统 
sudo dnf update -y
# 2.添加dnf阿里源仓库
sudo dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3.安装Docker及Docker Compose
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 4.立即启动并设置开机启动
systemctl enable --now docker
# 5.查看状态
sudo systemctl status docker

2、配置Docker镜像加速器

vi /etc/docker/daemon.json
{
  "registry-mirrors": [
      "https://docker.1ms.run",
      "https://docker.1panel.live",
      "https://7dc3jqs1.mirror.aliyuncs.com"
  ],
  "insecure-registries": ["192.168.3.15:2250","192.168.3.15:8889"]
}

# 重新加载docker配置并重启docker服务
systemctl daemon-reload
systemctl restart docker.service
sudo systemctl start docker

3、防火墙设置

# 以下临时测试时才需要停用防火墙
# 停用防火墙
sudo systemctl stop firewalld
# 启用防火墙 
sudo systemctl start firewalld
# 查看防火墙状态
sudo firewall-cmd --state

# 以下为正式配置
# 添加http服务,开放80端口
sudo firewall-cmd --permanent --add-service=http
# 添加https服务,开放443端口,根据实际需要开通(可选)
sudo firewall-cmd --permanent --add-service=https
# 虚拟路由冗余协议VRRP,用于实现网关的高可用(Keepalived)。它使用 IP 协议号 112(不是 TCP 或 UDP 端口)
sudo firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'
# 重载规则,使配置生效
sudo firewall-cmd --reload

4、系统内核参数:允许VIP绑定(2台服务器都要执行)

# 立即生效
sudo sysctl -w net.ipv4.ip_nonlocal_bind=1
# 永久生效(重启后保持)
echo 'net.ipv4.ip_nonlocal_bind = 1' | sudo tee /etc/sysctl.d/99-keepalived.conf
# 验证
sysctl net.ipv4.ip_nonlocal_bind

5、健康检查脚本赋予执行权限

chmod +x config/nginx/scripts/check_nginx.sh

6、修改.evn配置文件及节点网卡及虚拟IP

# 复制为 .env 后按节点修改
# 节点1(主):KEEPALIVED_ROLE=master
# 节点2(备):KEEPALIVED_ROLE=backup

KEEPALIVED_ROLE=master

主节点,查看网卡命令:ip a

! - INTERFACE: 主机网卡名(如 eth0 / ens32)
! - auth_pass: 密码最多8位
! - virtual_ipaddress: 要漂移的 VIP(带掩码,例如 192.168.100.200/24)

global_defs {
    router_id NGINX_HA_MASTER
    script_user root
    enable_script_security
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 3
    weight -20
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface ens32
    virtual_router_id 51
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass Ng1nX_H@
    }

    virtual_ipaddress {
        192.168.3.130/24 dev ens32 label ens32:vip
    }

    track_script {
        chk_nginx
    }
}

备份节点,查看网卡命令:ip a

global_defs {
    router_id NGINX_HA_BACKUP
    script_user root
    enable_script_security
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 3
    weight -20
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass Ng1nX_H@
    }

    virtual_ipaddress {
        192.168.3.130/24 dev ens33 label ens33:vip
    }

    track_script {
        chk_nginx
    }
}

7、Docker Compose文件

# 在两台 Rocky Linux 10.1 服务器上分别部署,通过 .env 区分主备角色
# 使用前:cp .env.example .env 并按节点修改 KEEPALIVED_ROLE / NODE_IP

services:
  nginx:
    image: nginx:1.31.1-alpine
    container_name: nginx
    restart: unless-stopped
    network_mode: host
    environment:
      TZ: Asia/Shanghai
    volumes:
      - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./config/nginx/conf.d:/etc/nginx/conf.d:ro
      - ./config/nginx/ssl:/etc/nginx/ssl
      - ./data/nginx/:/usr/share/nginx/html/
      - ./logs/nginx/:/var/log/nginx
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://127.0.0.1/health || exit 1"]
      interval: 5s
      timeout: 3s
      retries: 3
      start_period: 10s
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

  keepalived:
    image: osixia/keepalived:2.3.4
    container_name: keepalived
    restart: unless-stopped
    network_mode: host
    environment:
      TZ: Asia/Shanghai
    cap_add:
      - NET_ADMIN
      - NET_BROADCAST
      - NET_RAW
    volumes:
      - ./config/keepalived/${KEEPALIVED_ROLE}.conf:/etc/keepalived/keepalived.conf:ro
      - ./config/nginx/scripts/check_nginx.sh:/etc/keepalived/check_nginx.sh:ro  #注意添加执行权限chmod +x config/nginx/scripts/check_nginx.sh
    depends_on:
      nginx:
        condition: service_healthy
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "3"

8、检测虚拟IP漂移

# 检测Nginx(脚本如果报错用vi命令新建一个文件后重新赋权限)
docker exec keepalived sh /etc/keepalived/check_nginx.sh && echo "成功 0" || echo "失败 $?"
# 主机nginx停掉后会输出一个Script `chk_nginx` now returning 1 代表检测失败
# 反复查看主机和备机的日志
sudo docker logs keepalived
ip a | grep -A 3 ens32

9、改Nginx配置不停机重载,改Keepalived重启

# 改 conf.d/ 下的配置后,热重载,零停机
# nginx -t 先验证配置语法,通过后才 -s reload
docker compose exec nginx nginx -t && sudo docker compose exec nginx nginx -s reload

# 改站点配置(不中断,零停机)
docker compose exec nginx nginx -s reload

# 改keepalived 配置(短暂漂移)
docker compose restart keepalived

# 不管配置变没变,强制删除旧容器 + 创建新容器
docker compose up -d --force-recreate

10、新增域名解析和端口

# 新增端口
sudo firewall-cmd --zone=public --add-port=8088/tcp --permanent
# 重载生效
sudo firewall-cmd --reload
# 查看端口是否出现在列表里
sudo firewall-cmd --list-all
# 新增Nginx配置文件:/home/docker/config/nginx/conf.d下复制默认文件并重命名 cp default.conf keycloak-test.conf
server {
    listen       8088;
    listen       [::]:8088;
    #server_name  test.szbxl.cn;

    location / {
        proxy_pass http://192.168.3.15:8087;
        proxy_http_version 1.1;              # 长链接复用,必须手动加,否则默认 1.0
        proxy_set_header Connection "";      # 配合1.1,清空Connection header,让长连接生效
        proxy_set_header Host $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;   # 关键:告诉后端原始请求是https还是http
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Host $host;
        proxy_buffering off;
    }
}
# 重载nginx使新增域名解析和端口生效
docker compose exec nginx nginx -t && sudo docker compose exec nginx nginx -s reload

 

posted @ 2026-06-11 15:27  滔天蟹  阅读(36)  评论(0)    收藏  举报