Nginx+keepalived主從,雙主架構詳解
一、Nginx 與 Keepalived 基礎概念
1.1 Keepalived 原理詳解
Keepalived 是 Linux 系統(tǒng)下實現(xiàn) VRRP(Virtual Router Redundancy Protocol,虛擬路由冗余協(xié)議)的高可靠性軟件。其核心功能是通過 VRRP 協(xié)議實現(xiàn)服務器的故障切換,確保服務的高可用性。
VRRP 協(xié)議的工作機制如下:
- 將多臺提供相同服務的設備組成一個路由器組(Router Group),其中包含一個 master 和多個 backup
- 對外呈現(xiàn)一個虛擬 IP(VIP),master 負責處理 ARP 響應和數(shù)據(jù)包轉發(fā)
- master 定期發(fā)送組播消息(VRRP 包),backup 通過接收該消息監(jiān)控 master 狀態(tài)
- 當 backup 在超時時間內未收到 VRRP 包時,認為 master 故障,會根據(jù)優(yōu)先級選舉新的 master
- 新舊 master 切換時,VIP 會從原 master 轉移到新 master,實現(xiàn)服務的無縫接管
1.2 服務架構概述
本次實踐采用的架構包含:
- 兩臺 Nginx 服務器(nginx01 和 nginx02)
- 兩臺 Web 服務器(web01 和 web02)
- 虛擬 IP(VIP)用于對外提供服務
二、環(huán)境準備與 IP 規(guī)劃
2.1 服務器角色與 IP 分配
| 服務器角色 | IP 地址 | 備注 |
|---|---|---|
| web01 | 192.168.10.103 | 提供 Web 服務,端口 8081 |
| web02 | 192.168.10.104 | 提供 Web 服務,端口 8082 |
| nginx01 | 192.168.10.101 | Nginx 主服務器(主從架構中為 master) |
| nginx02 | 192.168.10.102 | Nginx 從服務器(主從架構中為 backup) |
| 虛擬 IP(主從) | 192.168.10.100 | 對外服務 IP |
| 虛擬 IP1(雙主) | 192.168.10.100 | nginx01 為主時使用 |
| 虛擬 IP2(雙主) | 192.168.10.200 | nginx02 為主時使用 |
2.2 基礎環(huán)境配置
在所有服務器上執(zhí)行以下操作,關閉防火墻和 SELinux:
# 停止防火墻 systemctl stop firewalld # 禁用防火墻開機自啟動 systemctl disable firewalld # 臨時關閉SELinux setenforce 0 # 永久關閉SELinux(修改配置文件) sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
三、Web 服務安裝與配置
3.1 安裝 HTTPD 服務
在 web01 和 web02 上分別安裝 HTTPD:
# 安裝httpd yum -y install httpd
3.2 配置 Web 測試頁面
在 web01 上創(chuàng)建測試頁面:
# 創(chuàng)建測試頁面 echo "test01" > /var/www/html/index.html # 修改監(jiān)聽端口為8081 vim /etc/httpd/conf/httpd.conf # 找到Listen 80行,修改為 Listen 8081 # 啟動httpd服務 systemctl start httpd # 設置開機自啟動 systemctl enable httpd
在 web02 上執(zhí)行類似操作,但測試頁面內容為 "test02",監(jiān)聽端口為 8082:
echo "test02" > /var/www/html/index.html vim /etc/httpd/conf/httpd.conf Listen 8082 systemctl start httpd systemctl enable httpd
四、Nginx 服務安裝與配置
4.1 安裝依賴包
在 nginx01 和 nginx02 上安裝編譯所需的依賴包:
yum -y install pcre-devel zlib-devel gcc*
4.2 創(chuàng)建 Nginx 用戶
創(chuàng)建專用的 Nginx 用戶,提高安全性:
useradd -M -s /sbin/nologin nginx
4.3 編譯安裝 Nginx
下載 Nginx 源碼并編譯安裝:
# 解壓源碼包 tar zxvf nginx-1.12.0.tar.gz # 進入源碼目錄 cd nginx-1.12.0 # 配置編譯參數(shù) ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx # 編譯并安裝 make && make install # 創(chuàng)建軟鏈接,方便命令行調用 ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ # 驗證安裝結果 ls -l /usr/local/sbin/nginx
4.4 配置 Nginx 代理
在 nginx01 和 nginx02 上配置 Nginx 代理參數(shù),指向后端 Web 服務器:
vim /usr/local/nginx/conf/nginx.conf
修改 http 塊內容如下:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream webserver {
server 192.168.10.103:8081;
server 192.168.10.104:8082;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://webserver;
}
}
}
五、Keepalived 主從架構搭建
5.1 Nginx01 上的 Keepalived 配置
安裝 Keepalived 并配置為主節(jié)點:
# 安裝keepalived yum -y install keepalived # 修改配置文件 vim /etc/keepalived/keepalived.conf
配置內容如下:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_01
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100
}
track_script {
check_nginx
}
}
5.2 Nginx02 上的 Keepalived 配置
安裝 Keepalived 并配置為從節(jié)點:
yum -y install keepalived vim /etc/keepalived/keepalived.conf
配置內容如下:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_02
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100
}
track_script {
check_nginx
}
}
5.3 編寫健康檢查腳本
在 nginx01 和 nginx02 上創(chuàng)建檢查 Nginx 運行狀態(tài)的腳本:
cd /etc/keepalived/ vim check_nginx.sh
腳本內容如下:
#!/bin/bash
pidof nginx
if [ $? -ne 0 ];then
/etc/init.d/keepalived stop
fi
賦予腳本執(zhí)行權限:
chmod +x check_nginx.sh
5.4 啟動 Keepalived 服務
在 nginx01 和 nginx02 上啟動 Keepalived:
systemctl start keepalived systemctl enable keepalived
5.5 主從架構測試
5.5.1 正常狀態(tài)測試
在客戶端訪問 VIP,驗證負載均衡效果:
curl 192.168.10.100 # 輸出應為test01或test02
5.5.2 故障切換測試
關閉 nginx01 上的 Nginx 服務,模擬主節(jié)點故障:
# 停止nginx服務 /usr/local/sbin/nginx -s stop
觀察 VIP 是否轉移到 nginx02,并驗證服務可用性:
# 在nginx02上查看VIP是否存在 ip addr show ens33 | grep 192.168.10.100 # 客戶端訪問VIP curl 192.168.10.100 # 此時應能正常返回test01或test02
當 nginx01 恢復后,VIP 會重新轉移回 nginx01:
# 啟動nginx服務 /usr/local/sbin/nginx # 等待片刻后,在nginx01上查看VIP ip addr show ens33 | grep 192.168.10.100
六、Nginx 雙主架構搭建
6.1 雙主架構介紹
雙主架構使用兩個 VIP,兩臺 Nginx 服務器互為主備,同時工作,提高資源利用率。當一臺服務器故障時,另一臺服務器接管兩個 VIP 的請求。
6.2 Nginx01 的雙主配置
在 nginx01 上修改 Keepalived 配置,添加第二個 VRRP 實例:
vim /etc/keepalived/keepalived.conf
完整配置如下:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_01
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100
}
track_script {
check_nginx
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 52
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.200
}
track_script {
check_nginx
}
}
6.3 Nginx02 的雙主配置
在 nginx02 上修改 Keepalived 配置,與 nginx01 形成互補:
vim /etc/keepalived/keepalived.conf
完整配置如下:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_02
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100
}
track_script {
check_nginx
}
}
vrrp_instance VI_2 {
state MASTER
interface ens33
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.200
}
track_script {
check_nginx
}
}
6.4 雙主架構測試
6.4.1 正常狀態(tài)測試
在客戶端訪問兩個 VIP,驗證負載均衡效果:
curl 192.168.10.100 # 輸出應為test01或test02 curl 192.168.10.200 # 輸出應為test01或test02
6.4.2 故障切換測試
關閉 nginx01 上的 Nginx 服務,模擬故障:
/usr/local/sbin/nginx -s stop
觀察兩個 VIP 是否都轉移到 nginx02:
# 在nginx02上查看VIP ip addr show ens33 | grep 192.168.10.100 ip addr show ens33 | grep 192.168.10.200 # 客戶端訪問兩個VIP curl 192.168.10.100 curl 192.168.10.200 # 此時兩個VIP應都能正常返回結果
當 nginx01 恢復后,VIP 會按配置轉移回各自的主節(jié)點。
6.5 非搶占模式配置
如需配置 master 重新接入后不搶占 VIP,需在配置中添加 nopreempt 參數(shù):
# 在需要設置非搶占的實例中添加
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100
}
track_script {
check_nginx
}
nopreempt # 添加非搶占參數(shù)
}
注意:state 必須設置為 BACKUP,MASTER 角色不能設置 nopreempt 參數(shù)。
七、架構對比與總結
7.1 主從架構與雙主架構對比
| 指標 | 主從架構 | 雙主架構 |
|---|---|---|
| VIP 數(shù)量 | 1 個 | 2 個 |
| 服務器利用率 | 只有 master 工作,backup 閑置 | 兩臺服務器同時工作 |
| 資源消耗 | 較低 | 較高 |
| 適用場景 | 服務器資源有限,對高可用性要求較高 | 服務器資源充足,追求資源利用率和高可用性 |
| 故障影響 | 一臺服務器故障,服務不受影響 | 一臺服務器故障,另一臺服務器負載增加 |
7.2 高可用架構關鍵點
- 健康檢查機制:通過腳本實時監(jiān)控 Nginx 狀態(tài),確保故障及時發(fā)現(xiàn)
- VRRP 協(xié)議:實現(xiàn) VIP 的自動切換,保證服務連續(xù)性
- 配置一致性:主從服務器配置需保持一致,避免切換失敗
- 測試驗證:定期進行故障切換測試,確保架構可靠性
7.3 進一步優(yōu)化方向
- 添加日志記錄:在檢查腳本中添加日志,方便故障排查
# 修改檢查腳本 vim /etc/keepalived/check_nginx.sh
#!/bin/bash
LOG_FILE="/var/log/keepalived/nginx_check.log"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Checking Nginx status..." >> $LOG_FILE
pidof nginx
if [ $? -ne 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Nginx process not found, stopping keepalived..." >> $LOG_FILE
/etc/init.d/keepalived stop
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Nginx is running normally." >> $LOG_FILE
fi
# 創(chuàng)建日志目錄并賦予權限 mkdir -p /var/log/keepalived chmod 755 /var/log/keepalived chown nginx:nginx /var/log/keepalived -R
- 配置郵件告警:當 Keepalived 發(fā)生切換時發(fā)送郵件通知
# 修改keepalived.conf配置文件 vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
admin@example.com # 替換為實際郵箱
}
notification_email_from keepalived@example.com # 替換為實際發(fā)件郵箱
smtp_server 192.168.1.1 # 替換為實際SMTP服務器IP
smtp_connect_timeout 30
router_id LVS_01
# 其他配置保持不變...
}
- 優(yōu)化 Nginx 配置:添加健康檢查和連接超時參數(shù)
vim /usr/local/nginx/conf/nginx.conf
upstream webserver {
server 192.168.10.103:8081 max_fails=3 fail_timeout=30s;
server 192.168.10.104:8082 max_fails=3 fail_timeout=30s;
keepalive 32; # 保持長連接數(shù)
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://webserver;
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_connect_timeout 10s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}
- 添加磁盤監(jiān)控:避免因磁盤滿導致服務異常
# 創(chuàng)建磁盤監(jiān)控腳本 vim /usr/local/sbin/disk_monitor.sh
#!/bin/bash
LOG_FILE="/var/log/disk_monitor.log"
THRESHOLD=90 # 磁盤使用率閾值(%)
df -h | grep -v tmpfs | while read line; do
device=$(echo $line | awk '{print $1}')
if [ "$device" != "Filesystem" ]; then
usage=$(echo $line | awk '{print $5}' | tr -d '%')
if [ $usage -ge $THRESHOLD ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $device disk usage reaches $usage%, please check!" >> $LOG_FILE
# 發(fā)送郵件告警
echo "磁盤 $device 使用率達到 $usage%,請及時檢查!" | mail -s "磁盤告警" admin@example.com
fi
fi
done
# 賦予執(zhí)行權限 chmod +x /usr/local/sbin/disk_monitor.sh # 添加定時任務,每10分鐘檢查一次 crontab -e */10 * * * * /usr/local/sbin/disk_monitor.sh
- 配置 Keepalived 優(yōu)先級動態(tài)調整:根據(jù)服務器負載動態(tài)調整優(yōu)先級
# 創(chuàng)建負載監(jiān)控腳本 vim /etc/keepalived/load_monitor.sh
#!/bin/bash
LOG_FILE="/var/log/keepalived/load_monitor.log"
VIP1="192.168.10.100"
VIP2="192.168.10.200"
INTERFACE="ens33"
MAX_LOAD=4.0 # 最大負載閾值
# 獲取1分鐘系統(tǒng)負載
load=$(cat /proc/loadavg | awk '{print $1}')
echo "[$(date '+%Y-%m-%d %H:%M:%S')] System load: $load" >> $LOG_FILE
if [ $(echo "$load > $MAX_LOAD" | bc -l) -eq 1 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: System load too high, reducing keepalived priority." >> $LOG_FILE
# 降低Keepalived優(yōu)先級(需根據(jù)實際角色調整)
if [ $(cat /etc/keepalived/keepalived.conf | grep "state MASTER" | wc -l) -ge 1 ]; then
# 如果是主節(jié)點,降低優(yōu)先級使其成為從節(jié)點
sed -i 's/priority 100/priority 80/g' /etc/keepalived/keepalived.conf
systemctl restart keepalived
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Keepalived priority reduced to 80, service migrated." >> $LOG_FILE
fi
else
# 負載正常時恢復優(yōu)先級
if [ $(cat /etc/keepalived/keepalived.conf | grep "priority 80" | wc -l) -ge 1 ]; then
sed -i 's/priority 80/priority 100/g' /etc/keepalived/keepalived.conf
systemctl restart keepalived
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Keepalived priority restored to 100." >> $LOG_FILE
fi
fi
# 賦予執(zhí)行權限 chmod +x /etc/keepalived/load_monitor.sh # 添加定時任務,每5分鐘檢查一次 crontab -e */5 * * * * /etc/keepalived/load_monitor.sh
7.4 常見故障排查
VIP 無法正常綁定
- 檢查網(wǎng)絡接口名稱是否正確(
interface ens33需與實際接口一致) - 確認兩臺服務器的
virtual_router_id是否相同 - 檢查防火墻是否允許 VRRP 協(xié)議通信(UDP 112 端口)
- 執(zhí)行
ip addr show查看 VIP 是否被正確綁定
Nginx 故障時 Keepalived 未切換
- 檢查
check_nginx.sh腳本是否有執(zhí)行權限 - 通過
/var/log/messages查看 Keepalived 日志,確認是否檢測到 Nginx 故障 - 手動執(zhí)行
check_nginx.sh腳本,查看是否能正確停止 Keepalived - 確認
track_script配置是否正確關聯(lián)到檢查腳本
雙主架構中 VIP 搶占異常
- 檢查是否配置了
nopreempt參數(shù)且state為BACKUP - 確認兩臺服務器的優(yōu)先級配置是否正確(主節(jié)點優(yōu)先級高于從節(jié)點)
- 檢查網(wǎng)絡延遲是否過高,導致心跳包丟失
Nginx 代理返回 502 錯誤
- 檢查后端 Web 服務器是否正常運行
- 查看 Nginx 錯誤日志(
/usr/local/nginx/logs/error.log) - 確認
upstream配置中的服務器 IP 和端口是否正確 - 檢查 Web 服務器防火墻是否允許 Nginx 服務器訪問
7.5 生產(chǎn)環(huán)境最佳實踐
硬件配置建議
- Nginx 服務器:4 核 CPU、8GB 內存、100GB SSD 硬盤
- Web 服務器:根據(jù)業(yè)務需求調整,建議至少 2 核 CPU、4GB 內存
- 網(wǎng)絡:千兆網(wǎng)卡,交換機支持組播轉發(fā)
監(jiān)控體系搭建
- 使用 Prometheus+Grafana 監(jiān)控 Nginx 和 Keepalived 狀態(tài)
- 監(jiān)控指標包括:CPU 使用率、內存占用、磁盤空間、網(wǎng)絡流量、Nginx 請求數(shù)、Keepalived 狀態(tài)
- 設置告警閾值,當指標異常時及時通知運維人員
定期維護計劃
- 每周進行一次架構切換測試,確保故障切換正常
- 每月更新服務器系統(tǒng)補丁,修復安全漏洞
- 每季度檢查硬件狀態(tài),更換老化部件
- 每年重新評估架構性能,根據(jù)業(yè)務增長調整配置
災備方案擴展
- 跨機房部署 Nginx+Keepalived 架構,實現(xiàn)異地容災
- 使用 DNS 輪詢結合 Keepalived,實現(xiàn)多機房流量分發(fā)
- 對重要數(shù)據(jù)進行異地備份,確保數(shù)據(jù)可靠性
7.6 架構擴展方案
增加 Nginx 服務器節(jié)點
- 在雙主架構基礎上,添加更多 Nginx 節(jié)點,形成多主多備架構
- 使用 DNS 輪詢或更高層的負載均衡設備分發(fā)流量到多個 VIP
- 調整 Keepalived 配置,實現(xiàn)多節(jié)點之間的故障切換
集成 Haproxy 實現(xiàn)四層負載均衡
- 在 Nginx 前端部署 Haproxy,實現(xiàn) TCP 層負載均衡
- Haproxy 監(jiān)控 Nginx 服務器狀態(tài),當某臺 Nginx 故障時自動剔除
- 配置 Haproxy 的健康檢查機制,確保流量只轉發(fā)到正常工作的 Nginx 節(jié)點
容器化部署
- 將 Nginx 和 Keepalived 打包為 Docker 容器,便于部署和管理
- 使用 Kubernetes 管理容器集群,實現(xiàn)自動擴縮容和故障轉移
- 通過 Service 和 Ingress 資源暴露服務,實現(xiàn)高可用架構
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
nginx使用replace-filter-nginx-module實現(xiàn)內容替換的示例
本篇文章主要介紹了nginx使用replace-filter-nginx-module實現(xiàn)內容替換的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
nginx配置中proxy_pass反向代理502的bug記錄
這篇文章主要介紹了nginx配置中proxy_pass反向代理502的bug記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01

