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
浙公网安备 33010602011771号