Keepalived+LVS实现LNMP网站的高可用部署

目录

1、项目概述

1.1、项目背景

1.2、项目模块

1.3、项目工作原理

1.4、核心模块功能介绍

2、项目的部署

2.1、部署环境介绍

2.2、项目的拓扑结构

3、项目环境调试

3.1、基础网络配置

3.2、关闭防火墙和selinux

4、项目的部署

4.1、部署主备服务配置VIP虚拟ip(keepalived节点)

[4.2、配置VIP回环接口(web节点和mariadb节点)](#4.2、配置VIP回环接口(web节点和mariadb节点))

4.3、配置route路由和持久化配置(web节点和mariadb节点)

4.4、配置ARP抑制(web节点和mariadb节点)

4.5、搭建数据库主从复制服务器(Mariadb节点)

4.6、搭建web站点(web节点)

4.7、搭建NFS服务器

4.8、将NFS共享的文件挂载到两个WEB服务器中

5、项目功能的验证

5.1、验证主备切换

5.2、验证Mariadb的主从复制

5.3、验证挂载功能

5.4、验证LNMP网站

6、项目的适用场景

7、项目总结


1、项目概述

1.1、项目背景

随着互联网业务的快速发展,企业对网站的可用性、性能和稳定性提出了更高的要求。LNMP(Linux + Nginx + MySQL + PHP)架构因其轻量、高效和易扩展的特性,被广泛应用于中小型网站和互联网应用中。然而,单一服务器的 LNMP 架构存在单点故障风险,一旦服务器出现故障,整个网站将无法访问,导致业务中断。

为了解决这一问题,企业需要引入高可用(HA)解决方案,通过冗余和负载均衡技术,确保在部分组件故障时,系统仍能持续提供服务。Keepalived 和 LVS(Linux Virtual Server)的组合是一种经典的高可用解决方案,能够有效提升 LNMP 网站的可用性和负载能力

1.2、项目模块

(1)Keepalived 高可用模块

(2)LVS 负载均衡模块

(3)MariaDB 主从复制模块

(4)NFS 共享存储模块

(5)Web 服务器模块(Nginx+PHP)

1.3、项目工作原理

|------------------|-----------------------------------------------------------|---------------------------------|
| 模块名称 | 实现原理 | 关联组件 |
| Keepalived 高可用模块 | 基于 VRRP 协议,通过虚拟路由器(VRID)管理 VIP,主节点定期发送 VRRP 广播包,备用节点监听并接管 | Keepalived(K1、K2) VIP(虚拟 IP) |
| LVS 负载均衡模块 | 通过修改请求的 MAC 地址(DR 模式)或 IP 地址(NAT 模式)实现流量分发 | LVS(K1、K2) WEB1、WEB2 |
| MariaDB 主从复制模块 | 主库将写操作记录到二进制日志(binlog),从库通过 I/O 线程和 SQL 线程同步数据 | Mariadb-M(主库) Mariadb-S(从库) |
| NFS 共享存储模块 | 将本地文件系统导出为网络文件系统,Web 服务器通过挂载访问 | NFS 服务器 WEB1、WEB2 |
| Web 服务器模块 | Nginx 作为反向代理服务器,PHP 通过 FastCGI 模式与 Nginx 集成 | WEB1(Nginx、PHP) WEB2(Nginx、PHP) |

1.4、核心模块功能介绍

|------------------|------------------------------------------|
| 模块名称 | 功能描述 |
| Keepalived 高可用模块 | - 实现 LVS 调度器的主备高可用 - 管理 VIP(虚拟 IP) |
| LVS 负载均衡模块 | - 将客户端请求分发到后端 Web 服务器 - 支持多种负载均衡算法(加权轮询) |
| MariaDB 主从复制模块 | - 实现数据库的高可用 - 主库负责写操作,从库负责读操作 |
| NFS 共享存储模块 | - 提供共享存储,确保 Web 服务器访问统一的文件资源 |
| Web 服务器模块 | - 处理客户端请求 - 运行 Nginx 和 PHP 服务 |

2、项目的部署

2.1、部署环境介绍

|-------------------|---------------------------------|---------|----------------|
| 服务器角色 | 主机名IP | 操作系统 | 组件 |
| Keepalived-Master | 192.168.157.18 | Centos7 | Keepalived+LVS |
| Keepalived-Slave | 192.168.157.20 | Centos7 | Keepalived+LVS |
| Web-1 | 192.168.157.21 | Centos7 | Nginx+PHP |
| Web-2 | 192.168.157.22 | Centos7 | Nginx+PHP |
| Mariadb-Master | 192.168.157.16 | Centos7 | Mariadb |
| Mariadb-Backup | 192.168.157.17 | Centos7 | Mariadb |
| NFS | 192.168.157.128 | Rocky | NFS |
| VIP | 192.168.157.100 192.168.157.200 | | |

2.2、项目的拓扑结构

3、项目环境调试

3.1、基础网络配置

复制代码
vim /etc/sysconfig/network-scripts/ifcfg-ens33

#192.168.157.18 keepalived-Master
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.157.18
NETMASK=255.255.255.0
GATEWAY=192.168.157.2
DNS1=8.8.8.8
DNS2=114.114.114.114

#192.168.157.20 keepalived-slave
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.157.20
NETMASK=255.255.255.0
GATEWAY=192.168.157.2
DNS1=8.8.8.8
DNS2=114.114.114.114

#192.168.157.21 web-1
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.157.21
NETMASK=255.255.255.0
GATEWAY=192.168.157.2
DNS1=8.8.8.8
DNS2=114.114.114.114

#192.168.157.22 web-2
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.157.22
NETMASK=255.255.255.0
GATEWAY=192.168.157.2
DNS1=8.8.8.8
DNS2=114.114.114.114

#192.168.157.16 Mariadb-Master
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.157.16
NETMASK=255.255.255.0
GATEWAY=192.168.157.2
DNS1=8.8.8.8
DNS2=114.114.114.114

#192.168.157.17 Master-Backup
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.157.17
NETMASK=255.255.255.0
GATEWAY=192.168.157.2
DNS1=8.8.8.8
DNS2=114.114.114.114

#192.168.157.128 NFS

3.2、关闭防火墙和selinux

复制代码
systemctl stop firewalld
systemctl disable firewalld
vim /etc/sysconfig/selinux
修改SELINUX=disabled
reboot

4、项目的部署

4.1、部署主备服务配置VIP虚拟ip(keepalived节点)

复制代码
#安装keepalived ipvsadm
modprobe  ip_vs
yum -y install keepalived ipvsadm
vim /etc/keepalived/keepalived.conf

#keepalived
global_defs {
   router_id centos01   #keepalived-Backup修改为centos02
}
vrrp_instance VI_1 {
    state MASTER     #keepalived-Backup修改为Backup
    interface ens33
    virtual_router_id  10
priority 100    #keepalived-Backup修改为50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.157.100 dev ens33 label ens33:0
        192.168.157.200 dev ens33 label ens33:1
    }
}
virtual_server 192.168.157.100 80 {
   delay_loop 15
   lb_algo wrr
    lb_kind DR
!    persistence_timeout 50
    protocol TCP
    real_server 192.168.157.21 80 {
        weight 1
       TCP_CHECK {
        connect_port 80
        connect_timeout 3
        nb_get_retry 3
        delay_before_retry 4
       }
    }
     real_server 192.168.157.22 80 {
        weight 1
       TCP_CHECK {
        connect_port 80
        connect_timeout 3
        nb_get_retry 3
        delay_before_retry 4
       }
    }
}
virtual_server 192.168.157.200 3306 {
    delay_loop 6
    lb_algo wrr
    lb_kind DR
    protocol TCP

    real_server 192.168.157.16 3306 {
        weight 1
        TCP_CHECK {
            connect_port 3306
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    real_server 192.168.157.17 3306 {
        weight 1
        TCP_CHECK {
            connect_port 3306
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

#启动服务
systemctl restart keepalived
systemctl enable keepalived

#查看
ip a

4.2、配置VIP回环接口(web节点和mariadb节点)

复制代码
#修改网络配置文件
cd /etc/sysconfig/network-scripts/
cp ifcfg-lo ifcfg-lo:0
vim ifcfg-lo:0

DEVICE=lo:0
IPADDR=192.168.157.100  #mariadb节点改成192.168.157.200
NETMASK=255.255.255.255
NETWORK=127.0.0.0
# If you're having problems with gated making 127.0.0.0/8 a martian,
# you can change this to something else (255.255.255.255, for example)
BROADCAST=127.255.255.255
ONBOOT=yes
NAME=lo:0

#启动lo:0
ifup lo:0

#查看IP设置
ip a show lo:0

#连通性测试
ping -c 4 192.168.157.100   #mariadb节点改成192.168.157.200

4.3、配置route路由和持久化配置(web节点和mariadb节点)

复制代码
#添加启动任务
vim /etc/rc.local 
添加/sbin/route add -host 192.168.157.100 dev lo:0 #mariadb节点改为192.168.157.200

#查看route
route -n

4.4、配置ARP抑制(web节点和mariadb节点)

复制代码
#配置内核参数
vim /etc/sysctl.conf
添加如下内容:
net.ipv4.conf.all.arp_ignore = 1 
net.ipv4.conf.all.arp_announce = 2 
net.ipv4.conf.default.arp_ignore = 1 
net.ipv4.conf.default.arp_announce = 2 
net.ipv4.conf.lo.arp_ignore = 1 
net.ipv4.conf.lo.arp_announce = 2

#查看
sysctl -p

4.5、搭建数据库主从复制服务器(Mariadb节点)

复制代码
#Mariadb-Master服务器
#yum安装mariadb服务
yum install -y mariadb-server

#启动数据库服务
systemctl restart mariadb

#修改mariadb配置文件
vim /etc/my.cnf

[mysqld]
server_id=1 # ID号
binlog_format=row   # 基于行复制
log-bin=/data/bin/mysql-bin # 生成二进制文件的目录与格式

#创建二进制文件存放的目录
mkdir /data/bin

#授予目录所属关系
chown mysql.mysql /data/bin/ -R

#重新启动mariadb服务
systemctl restart mariadb

#执行安全脚本
mysql_secure_installation

# 进入数据库
mysql -uroot -p

# 添加slave复制权限
grant replication slave on *.* to repluser@'%' identified by '123456';

# 刷新权限
flush privileges;

# 重置master二进制文件大小
reset master;
 
# 查看并记录
show master logs; 
复制代码
#Mariadb-Slave服务器
#yum安装mariadb服务
yum install -y mariadb-server

#启动数据库服务
systemctl restart mariadb

#修改mariadb配置文件
vim /etc/my.cnf

[mysqld]
server_id=2 # ID号
read_only   # 只读

#重新启动mariadb服务
systemctl restart mariadb

#执行安全脚本
mysql_secure_installation

# Slave节点添加同步Master数据库的语句
CHANGE MASTER TO MASTER_HOST='192.168.157.16', MASTER_USER='repluser', MASTER_PASSWORD='123456',MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=245;

# 启用从节点
slave start;

# 状态查看
show slave status\G;
复制代码
#测试
# Master节点创建一个darius数据库
create database darius;

# Slave查看,如同步成功,则主从复制创建完成
show databases;

4.6、搭建web站点(web节点)

复制代码
#编写nginx编译安装脚本
vim nginx.sh

#!/bin/bash
# 安装依赖包
yum install -y vim lrzsz tree screen psmisc lsof tcpdump wget ntpdate gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools iotop bc zip unzip zlib-devel bash-completion nfs-utils automake libxml2 libxml2-devel libxslt libxslt-devel perl perl-ExtUtils-Embed &>/dev/null
# 下载 Nginx 源码包
wget https://nginx.org/download/nginx-1.14.2.tar.gz &>/dev/null
# 解压并进入 Nginx 目录
tar -zxvf nginx-1.14.2.tar.gz &>/dev/null
cd nginx-1.14.2/
# 配置 Nginx
./configure \
    --prefix=/apps/nginx \
    --user=nginx \
    --group=nginx \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_realip_module \
    --with-http_stub_status_module \
    --with-http_gzip_static_module \
    --with-pcre \
    --with-stream \
    --with-stream_ssl_module \
    --with-stream_realip_module &>/dev/null
# 编译并安装 Nginx
make && make install
# 创建 Nginx 用户
useradd nginx -s /sbin/nologin -u 2000
# 设置 Nginx 目录权限
chown nginx.nginx -R /apps/nginx/
# 输出 Nginx 版本信息
echo -e "\n=======================版本==================================\n"
/apps/nginx/sbin/nginx -V

# 给脚本添加执行权限
chmod a+x nginx.sh
  
# 启动安装脚本
./nginx.sh

# 成功安装Nginx,做nginx命令软链接
ln -sv /apps/nginx/sbin/nginx /usr/sbin/

# 启动Nginx
Nginx

# 查看80端口
ss -ntl

# 修改Nginx配置文件,使其开启php页面访问功能
vim /apps/nginx/conf/nginx.conf
2 user  nginx nginx;
  9 pid        logs/nginx.pid;
35    server {
  36         listen       80;
  37         server_name  _;
38         charset utf-8;
  42         location / {
  43             root   /apps/nginx/html;
  44             index  index.php index.html index.htm;
  45         }
  64         location ~ \.php$ {
  65             root           /apps/nginx/html;
  66             fastcgi_pass   127.0.0.1:9000;
  67             fastcgi_index  index.php;
  68    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  69             include        fastcgi_params;
  70         }

# 编写php状态页面
vim /apps/nginx/html/index.php
<?php
phpinfo();
?>

# 重新加载Nginx配置文件
nginx -t && nginx -s reload

# 安装php-fpm模块
yum install -y php-fpm php-mysql

# 编写php-fpm模块配置文件
vim /etc/php-fpm.d/www.conf
 12 listen = 127.0.0.1:9000
 33 listen.mode = 0666
 39 user = nginx
 41 group = nginx

# 启动php-fpm
systemctl restart php-fpm

# 9000端口查看
ss -ntl

#浏览器输入web节点的ip或者192.168.157.100
192.168.157.21
192.168.157.22
192.168.157.100

4.7、搭建NFS服务器

复制代码
#安装nfs-utils
sudo dnf install nfs-utils -y

# 修改NFS配置文件,设置将要共享的目录
vim /etc/exports
/data *(rw,no_root_squash)

# 重新启动NFS服务,并设置开机启动
systemctl restart nfs
systemctl enable nfs
#加载
exportfs -a

# 查看NFS共享目录
exportfs -v

4.8、将NFS共享的文件挂载到两个WEB服务器中

复制代码
# 写入fstab文件中,开机自动挂载
vim /etc/fstab 
192.168.157.128:/data /apps/nginx/html nfs _netdev,defaults 0 0

#挂载
mount -a

# 查看挂载情况
df -h

5、项目功能的验证

5.1、验证主备切换

#查看主ip

#在keepalived-Master上停止keepalived,在备主机上查看IP

复制代码
systemctl stop keepalived

5.2、验证Mariadb的主从复制

#在Mariadb-Master上创建一个数据库

复制代码
create database zyz;

#在Mariadb-Backup上查看

复制代码
slave start;
show databases;

5.3、验证挂载功能

#在NFS服务器中创建一个文件

复制代码
cd /data/
touch 111.txt

#在web服务器中查看

复制代码
ls /apps/nginx/html

5.4、验证LNMP网站

#在NFS服务器中搭建wordpress

复制代码
#解压wordpress包
unzip wordpress-4.7.3.zip

#将wordpress包内文件移动到共享目录中,进行共享
mv wordpress/* /data/
cd /data/

# 生成wordpress配置文件
mv wp-config-sample.php wp-config.php

# 修改wordpress配置文件
[root@NFS data]#vim wp-config.php
...
/** WordPress数据库的名称 */
define('DB_NAME', 'wordpress');

/** MySQL数据库用户名 */
define('DB_USER', 'wpuser');

/** MySQL数据库密码 */
define('DB_PASSWORD', '123456');

/** MySQL主机 */
define('DB_HOST', '192.168.157.200');

/** 创建数据表时默认的文字编码 */
define('DB_CHARSET', 'utf8');

#查看解压文件,主要是index.php
ls

#创建对应数据库-在Mariadb-Master服务器

复制代码
#创建wordpress数据库
CREATE DATABASE wordpress;

#创建wpuser用户
CREATE USER 'wpuser'@'%' IDENTIFIED BY '123456';

#授予用户对数据库的所有权限
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'%';

#刷新权限
FLUSH PRIVILEGES;

#浏览器输入192.168.157.100

#登入测试

#重新登入192.168.157.100

#最终结果

6、项目的适用场景

Keepalived+LVS组合适用于对网站高可用性要求较高的LNMP架构场景,主要解决以下问题:

单点故障:避免因单台服务器宕机导致服务中断

负载均衡:合理分配流量到多台后端服务器

故障自动切换:主服务器故障时自动切换到备用服务器

网络层高可用:通过VIP(虚拟IP)对外提供服务,隐藏后端服务器细节

7、项目总结

当我们访问某个网站的时候可以在浏览器中输入IP或者域名链接到Web Server进行访问,如果这个Web Server挂了,那么整个系统都无法使用,用户也就不能进行正常的访问,这种情况将对公司产生一定的影响。这就是我们常说的系统中的单点故障。这部分的单点故障可以通过引入负载均衡器和至少另一个Web Server来缓解。同时由于有多台服务器同时提供服务,也加大了系统的负载能力提高了性能

因此我们采用LVS的负载均衡技术,将前端请求按照设定规则调度到后端服务器,并与keepalived相结合实现高可用负载均衡

相关推荐
basketball61614 分钟前
Linux C 管道文件操作
linux·运维·c语言
颖川初尘28 分钟前
端口到底是个什么鬼?回答我!
服务器·网络·tcp/ip·node.js
浩浩测试一下43 分钟前
Windows 与 Linux 内核安全及 Metasploit/LinEnum 在渗透测试中的综合应用
linux·运维·windows·web安全·网络安全·系统安全·安全架构
stark张宇1 小时前
Linux 文件创建、删除、移动、复制基础知识整理
linux·服务器·centos
将心ONE1 小时前
使用 lstrip() 和 rstrip() 方法
运维·服务器
IT小辉同学2 小时前
PostgreSQL 与 MySQL 获取字段注释并转换为驼峰命名教程
数据库·mysql·postgresql
叁沐2 小时前
MySQL 12 为什么我的MySQL会“抖”一下?
mysql
G_whang2 小时前
centos7 安装jenkins
运维·jenkins
Jiangnan_Cai2 小时前
Linux 系统 docker 部署 Dify
linux·docker·大模型·dify
一只fish2 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(21)
数据库·mysql