目录
项目名称
项目环境
项目描述
项目步骤
前期准备工作:
所有机器关闭防火墙与selinux
1.规划设计整个集群的网络拓扑结构,按照规划为每台服务器配好IP
2.在中控机上安装部署ansible服务,通过SSH与其他服务器之间建立免密通道,编写playbook完成nginx、Prometheus的安装与部署
安装ansible并与三台real server、两台LB建立免密通道
使用ansible部署nginx集群
搭建监控平台
3.通过ansible修改nginx中的长连接数,并发数,worker进程数、限制速度等以及修改Prometheus相关配置。
4.在Prometheus监控平台上添加服务器与监控项在相关服务器上安装exporter程序,在Grafana中配置好Prometheus的数据源
使用ansible在node节点服务器上安装exporter程序
配置Grafana
5.使用2台服务器作为双VIP负载均衡器,使用nginx的7层负载均衡并实现realip功能,配置并运行keepalived软件
配置负载均衡
实现realip功能
配置keepalived软件,实现双VIP架构
编辑
6.配置nfs服务器,并在real server中设置开机自动挂载
7.在客户机上使用ab软件进行压力测试
8.搭建DNS服务器,添加负载均衡记录,将负载均衡器的2个VIP绑定在一个域名上
搭建DNS服务器
域名绑定VIP
9.尝试优化整个web集群,通过修改内核参数,nginx参数等方式来提升性能
项目中遇到的困难
项目心得
搭建基于nginx(双机热备+keepalived)的高可用web集群项目
9台centos7服务器、nginx 1.23.3、nfs-utils、keepalived 1.3.5、Prometheus 2.42、bind、ab、ansible 2.9.27、Grafana 9.1.2
搭建一个基于nginx的7层负载均衡web集群项目。使用nfs实现数据同源;keepalived实现双vip架构,提高可用性;利用prometheus实现监控功能并通过grafana进行监控数据可视化。构建一个高并发,高可用的web集群,通过ab压力测试对集群性能不断优化,并调整内核参数,解决瓶颈问题。
systemctl disable firewalld
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/selinux/config
#1.从ansible上生成ssh密钥同步到两台node主机上,实现无密钥登陆管理
[root@localhost ~]# ssh-keygen
#2.建立免密通道
[root@localhost ~]# ssh-copy-id -i id_rsa.pub [email protected]
[root@localhost .ssh]# ssh-copy-id -i id_rsa.pub [email protected]
[root@localhost .ssh]# ssh-copy-id -i id_rsa.pub [email protected]
[root@localhost .ssh]# ssh-copy-id -i id_rsa.pub [email protected]
#3.验证是否建立成功(远程登陆)
[root@ansible ~]# ssh '[email protected]'
Last login: Fri Apr 7 10:28:46 2023
[root@lb1 ~]# exit
登出
Connection to 192.168.81.12 closed.
[root@ansible ~]# ssh '[email protected]'
Last login: Fri Apr 7 10:28:57 2023
[root@lb2 ~]# exit
登出
Connection to 192.168.81.13 closed.
[root@ansible ~]# ssh '[email protected]'
Last login: Fri Apr 7 10:29:22 2023
[root@web2 ~]# exit
登出
Connection to 192.168.81.14 closed.
[root@ansible ~]# ssh '[email protected]'
Last login: Fri Apr 7 10:29:53 2023 from 192.168.81.45
#4.安装ansible
[root@ansible ~]# yum install epel-release -y
[root@ansible ~]# yum install ansible -y
#5.将node主机添加到管主机单中
[root@ansible ~]# cd /etc/ansible
[root@ansible ansible]# ls
ansible.cfg hosts roles
[root@ansible ansible]# cat hosts
[webservers]
192.168.81.12
192.168.81.13
192.168.81.14
192.168.81.17
编译安装nignx,编写一键安装脚本:
[root@ansible nginx]# cat onekey_install_nginx.sh
#!/bin/bash
#新建一个文件夹用来存放下载的nginx源码包
#mkdir -p /nginx
cd /nginx
#新建用户
#useradd -s /sbin/nologin lianyu
#下载nginx
curl -O http://nginx.org/download/nginx-1.23.3.tar.gz
#解压压缩包
tar xf nginx-1.23.3.tar.gz
#解决依赖关系
yum install gcc openssl openssl-devel pcre pcre-devel automake make -y
#编译前的配置
cd nginx-1.23.3
./configure --prefix=/usr/local/scnginx99 --user=lianyu --with-http_ssl_module --with-http_v2_module --with-threads --with-http_stub_status_module --with-stream
#编译,开启两个进程同时编译,速度更快
make -j 2
#安装
make install
#启动 nginx
/usr/local/scnginx99/sbin/nginx
#修改path变量
PATH=$PATH:/usr/local/scnginx99/sbin
echo "PATH=$PATH:/usr/local/scnginx99/sbin" >>/root/.bashrc
#设置nginx的开机启动
echo "/usr/local/scnginx99/sbin/nginx" >>/etc/rc.local
chmod +x /etc/rc.d/rc.local
#selinux和firewalld防火墙都关闭
setenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/selinux/config
service firewalld stop
systemctl disable firewalld
使用ansible将一键安装脚本传至其他机器:
[root@ansible nginx]# ansible all -m copy -a "src=/nginx/onekey_install_nginx.sh dest=/nginx"
使用ansible编写playbook进行安装:
#编写playbook
[root@ansible playbooks]# cat nginx_install.yaml
- hosts: all
remote_user: root
tasks:
- name: install nginx
script: /nginx/onekey_install_nginx.sh
#检查playbook的语法
[root@ansible playbooks]# ansible-playbook --syntax-check nginx_install.yaml
#执行playbook
[root@ansible playbooks]# ansible-playbook nginx_install.yaml
在规划的服务器上安装部署Prometheus:
#1.上传下载的源码包到linux服务器
[root@localhost ~]# mkdir /prom
[root@localhost ~]# mv prometheus-2.42.0.linux-amd64.tar.gz /prom/
[root@localhost ~]# cd /prom
#2.解压源码包
[root@localhost prom]# tar xf prometheus-2.42.0.linux-amd64.tar.gz
#修改解压后压缩包的名字
[root@localhost prom]# mv prometheus-2.42.0.linux-amd64 prometheus
#3.永久修改PATH变量,添加prometheus的路径
[root@localhost prometheus]# vim /root/.bashrc
[root@localhost prometheus]# cat /root/.bashrc
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
[root@localhost prometheus]# which prometheus
/prom/prometheus/prometheus
#4.执行promethues
[root@localhost prometheus]# nohup prometheus --config.file=/prom/prometheus/prometheus.yml &
[2] 1446
[root@localhost prometheus]# nohup: #忽略输入并把输出追加到"nohup.out"
[root@localhost prometheus]# ps aux|grep prome #查看prometheus进程
root 1446 0.2 4.4 798412 43820 pts/0 Sl 21:44 0:00 prometheus --config.file=/prom/prometheus/prometheus.yml
root 1453 0.0 0.0 112824 980 pts/0 S+ 21:44 0:00 grep --color=auto prome
[root@localhost prometheus]# netstat -antplu |grep prometheus #查看prometheus监听的端口号
tcp6 0 0 :::9090 :::* LISTEN 1446/prometheus
tcp6 0 0 ::1:9090 ::1:33180 ESTABLISHED 1446/prometheus
tcp6 0 0 ::1:33180 ::1:9090 ESTABLISHED 1446/prometheus
#5.将prometheus做成服务进行管理
[root@localhost nginx]# vim /usr/lib/systemd/system/prometheus.service
[root@localhost nginx]# systemctl daemon-reload #重新加载systemd相关服务
[root@localhost nginx]# cat /usr/lib/systemd/system/prometheus.service
[Unit]
Description=prometheus
[Service]
ExecStart=/prom/prometheus/prometheus --config.file=/prom/prometheus/prometheus.yml
ExecReload=/bin/kill -HUP $MAINPID
killMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
[root@localhost nginx]# kill -9 1446 先杀死使用nohup命令启动的进程,再使用service方式管理prometheus
[root@localhost nginx]# service prometheus restart #再重新启动查看服务效果
修改配置文件nginx.conf
[root@lb1 conf]# pwd
/usr/local/scnginx99/conf
[root@lb1 conf]# cat nginx.conf
worker_processes 2; #修改进程数
worker_connections 1024; #修改并发连接数
keepalive_requests 10000;
#2.限制速度
#放在http或server里面,若放在http则影响全局
server{
limit_rate_after 100k; #下载速度达到100k每秒的时候,进行限制
limit_rate 10k; #限制每秒10k的速度
}
[root@ansible prometheus]# cd /node_exporter/
[root@ansible node_exporter]# ls
LICENSE node_exporter NOTICE
[root@ansible node_exporter]#
[root@ansible node_exporter]# ansible all -m copy -a "src=/node_exporter dest=/prometheus"
#在node节点上修改path变量
[root@lb1 node_exporter]# PATH=/prometheus/node_exporter/:$PATH
#执行node exporter代理程序
[root@lb1 node_exporter]# ansible all -m shell -a "nohup node_exporter --web.listen-address 0.0.0.0:8090 &"
在prometheus服务器上添加抓取数据的配置,添加node节点服务器,将抓取的数据存储到时序数据库里:
[root@localhost ~]# cd /prom/prometheus
[root@localhost prometheus]# cat prometheus.yml
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "LB1"
static_configs:
- targets: ["192.168.81.12:8090"]
- job_name: "LB2"
static_configs:
- targets: ["192.168.81.13:8090"]
- job_name: "web1"
static_configs:
- targets: ["192.168.81.17:8090"]
- job_name: "web2"
static_configs:
- targets: ["192.168.81.14:8090"]
访问192.168.81.99:9090端口,prometheus配置成功,达到监控服务的效果:
下载好Grafana软件后,启动服务
#启动grafana工具
[root@localhost prometheus]# service grafana-server start
#设置grafana开机启动
[root@localhost prometheus]# systemctl enable grafana-server
访问192.168.81.99:3000进入Grafana界面,在grafana中配置prometheus的数据源,并导入相关模板进行数据可视化展示,界面如图
负载均衡器中默认使用轮询调度,调度算法采用加权轮询。实现https的负载均衡。
添加配置负载均衡的相关模块:
[root@lb nginx]# cd /usr/local/scnginx99/conf
[root@lb conf]# vim nginx.conf
#定义一个负载均衡器,名字为layapp
http{
upstream layapp{ #添加模块
server 192.168.81.17;
server 192.168.81.100 weight=3;
server 192.168.81.14;
}
# weight=3,#表示权重值,默认情况下为1,可以使负载均衡更向加了权重值的浏览器倾斜
server {
listen 80;
server_name www.li.com;
location / {
proxy_pass http://layapp;
}
}
}
实现https的负载均衡 :
首先需要将域名证书下载为压缩包上传至conf的文件夹中,再进行操作。详细操作在之前的博客中已进行分享,此处不再重复,仅展示成功的页面效果:在nginx中部署https服务,详细步骤_nginx 发布https_钰儿yu1228的博客-CSDN博客
能让real server记录访问过来的真实IP:
#步骤1:在两台负载均衡器上修改http请求报文头部字段,添加一个x_real_ip字段
http{
server {
listen 80;
server_name www.li.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://layapp;
proxy_set_header X-Real-IP $remote_addr;
}
}
#步骤2:在后端3台real server上使用这个x_real_ip字段,在记录日志部分加入$http_x_real_ip -
http {
include mime.types;
default_type application/octet-stream;
log_format main '$http_x_real_ip - $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
}
在两台负载均衡器上安装keepalived软件:
[root@lb1 conf]# yum install keepalived -y
实现双VIP架构:
修改keepalived配置文件:
[root@lb2 conf]# cd /etc/keepalived/
[root@lb2 keepalived]# ls
keepalived.conf
[root@lb2 keepalived]# vim keepalived.conf
#192.168.81.12负载均衡器配置
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 56
priority 120
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.81.111
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 57
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.81.222
}
}
#192.168.81.13负载均衡器配置
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 11
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.81.111
}
}
vrrp_instance VI_2 {
state MASTER
interface ens33
virtual_router_id 22
priority 120
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.81.222
}
}
#在两台机器上重启keepalived服务
[root@lb1 keepalived]# service keepalived restart
当挂掉192.168.81.13这台负载均衡器时,VIP进行漂移:
使用一台新的服务器部署nfs服务,3台real server需要安装nfs-utils
在之前的博客中具体介绍了配置nfs服务器的方法,在此不进行赘述
nfs安装配置_安装配置nfs_钰儿yu1228的博客-CSDN博客
效果展示:
在web集群外的机器上对该集群进行ab压力测试
安装ab软件:
[root@web2 ~]# yum install httpd-tools -y
使用ab压力测试对负载均衡器进行测试:
#10个并发数,10000个请求数
[root@web2 ~]# ab -n 10000 -c 10 http://192.168.81.12/
查看吞吐率:
多次测试后吞吐率达到一个相对稳定的值,在1200左右。
DNS服务器为该集群提供域名解析服务,将域名与2个VIP绑定后,用户在访问该域名时,可以直接访问到服务器集群中的任意一台服务器上的网站。这种绑定方式访问速度快,可靠性高,同时能够实现负载均衡和故障转移等功能。
按照规划在集群中的DNS服务器上先关闭所有的防火墙与selinux,详细的搭建步骤在之前的博客中已为大家进行介绍:
在linux搭建dns服务器(缓存域名服务器)_linux dns 缓存服务器_钰儿yu1228的博客-CSDN博客
按照步骤修改配置后的效果展示:
使用主域名服务器搭建,添加负载均衡记录:
#1.在localhosts后面添加一条配置文件,告诉named为cdn.chenzhengben.xyz提供域名
[root@dns-server ~]# cat /etc/named.rfc1912.zones
zone "cdn.chenzhengben.xyz" IN {
type master;
file "chenzhengben.xyz.zone";
allow-update { none; };
};
#2./var/named 存放dns域名解析的数据文件 --> 创建chenzhengben.xyz的数据文件
[root@dns-server ~]# cd /var/named
[root@dns-server named]# cp -a named.localhost chenzhengben.xyz.zone
[root@dns-server named]# cat chenzhengben.xyz.zone
$TTL 1D
@ IN SOA @ rname.invalid. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS @
A 192.168.81.12
A 192.168.81.13
AAAA ::1
cdn IN A 192.168.81.111
cdn IN A 192.168.81.222
#重新刷新服务
[root@dns-server named]# service named restart
使用客户机检验添加的数据文件是否生效:
#将两台负载均衡器的dns指向192.168.81.128
[root@lb2 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.81.128
#检验域名解析效果
[root@lb2 ~]# nslookup cdn.chenzhengben.xyz
Server: 192.168.81.128
Address: 192.168.81.128#53
Name: cdn.chenzhengben.xyz
Address: 192.168.81.111
Name: cdn.chenzhengben.xyz
Address: 192.168.81.222
Name: cdn.chenzhengben.xyz
Address: ::1
将windows的dns改成集群中所配置的dns服务器ip地址,对网站进行访问,查看效果:
通过ulimit命令可以查看资源限制,并进行修改:
1.做双VIP架构的时候,VIP的效果起不来:
配置的虚拟路由id冲突
2.配置nfs时设置了开机自动挂载导致web服务器不能开机:
开机时按e进入单用户模式,注释掉/etc/rc.d/rc.local或/etc/fstab中的命令行再开机
3.域名绑定VIP后,访问没有效果:
keepalived的配置文件中vrrp_strict没有注释,导致产生了一条防火墙规则
逐渐理解了集群的概念,对高可用高性能以及系统性能指标有了一定的认识,学习了脑裂现象的原因和解决方案,对一键安装部署与ansible的使用更加清晰。掌握了压力测试,尝试进行系统优化和参数调整,以此来提升性能。基础功能的软件配合搭建有了一定的了解,对今后大规模的集群打下基础,提升了整体规划与troublshooting的能力。