集群架构学习整理 - 四层负载均衡（十）
LVS四层负载均衡四种模式1.NAT模式2.TUN隧道模式3.DR直接路由，推荐使用4.FULLNAT，完全NATLVS负载均衡实践环境准备 1.MySQL负载均衡 外部IP地址 内部IP地址 角色 备注 L4: 192.168.238.15 172.16.1.15 LVS调度器（Director） 对外提供服务的VIP为192.168.238.17 192.168.238.16 172.16.1.16 LVS调度器（Director） 对外提供服务的VIP为192.168.238.17 192.168.238.51 172.16.1.51 RS1（真实服务器） MySQL 192.168.238.52 172.16.1.52 RS2（真实服务器） MySQL #L4+L7+WEB 大规模web负载均衡 L4: 192.168.238.15 172.16.1.15 LVS调度器（Director） 对外提供服务的VIP为192.168.238.17 192.168.238.16 172.16.1.16 LVS调度器（Director） 对外提供服务的VIP为192.168.238.17 L7: 192.168.238.5 172.16.1.5 LVS调度器（Director） 192.168.238.6 172.16.1.6 LVS调度器（Director） 192.168.238.7 172.16.1.7 RS1（真实服务器） web01 192.168.238.8 172.16.1.8 RS2（真实服务器） web02LVS负载均衡安装#在lb4-01、lb4-02上安装LVS [root@lb4-01 ~]# yum install ipvsadm -y [root@lb4-01 ~]# rpm -qa ipvsadm ipvsadm-1.27-8.el7.x86_64 [root@lb4-01 ~]# modprobe ip_vs #把ipvs加入到内核 [root@lb4-01 ~]# lsmod|grep ip_vs #检查内核是否有ip_vs ip_vs 145458 0 nf_conntrack 143360 1 ip_vs libcrc32c 12644 3 xfs,ip_vs,nf_conntrack [root@lb4-01 ~]# uname -r 3.10.0-1160.83.1.el7.x86_64 [root@lb4-01 ~]# yum install kernel-devel -y [root@lb4-01 ~]# ln -s /usr/src/kernels/3.10.0-1160.83.1.el7.x86_64/ /usr/src/linux [root@lb4-01 ~]# ls -l /usr/src/ lrwxrwxrwx 1 root root 45 Mar 3 10:34 linux -> /usr/src/kernels/3.10.0-1160.83.1.el7.x86_64/ 特别注意： ln命令链接路径要和uname -r输出结果内核版本对应。 如果没有/usr/src/kernels/xx路径,可通过yum install kernel-devel -y安装。场景1：实现MySQL数据库负载均衡###配置LVS虚拟IP（VIP） ifconfig eth1:17 172.16.1.17/24 up #==>简便写法 #route add -host 172.16.1.17 dev eth1 #==添加主机路由，也可不加此行。 ###手工执行配置添加LVS服务并增加两台RS ipvsadm ipvsadm -C #<== -C clear the whole table ipvsadm --set 30 5 60 #<== --set tcp tcpfin udp set connection timeout values #ipvsadm -A -t 172.16.1.17:3306 -s wrr #--add-service -A add virtual service with options ipvsadm -A -t 172.16.1.17:3306 -s wrr -p 20 #dr模式 ipvsadm -a -t 172.16.1.17:3306 -r 172.16.1.51:3306 -g -w 1 ipvsadm -a -t 172.16.1.17:3306 -r 172.16.1.52:3306 -g -w 1 # ipvsadm -a|e -t|u|f service-address -r server-address [options] [root@lb4-01 ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.1.17:3306 wrr persistent 20 -> 172.16.1.51:3306 Route 1 0 0 -> 172.16.1.52:3306 Route 1 0 0 [root@lb4-01 ~]# ipvsadm -Ln --stats IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes -> RemoteAddress:Port TCP 172.16.1.17:3306 0 0 0 0 0 -> 172.16.1.51:3306 0 0 0 0 0 -> 172.16.1.52:3306 0 0 0 0 0 [删除方法] ipvsadm -D -t 172.16.1.17:3306 ipvsadm -d -t 172.16.1.17:3306 -r 172.16.1.51:3306 <==正确 [相关参数说明] [root@oldboy ~]# ipvsadm -help # --clear -C clear the whole table # --add-service -A add virtual service with options # --tcp-service -t service-address service-address is host[:port] # --scheduler -s scheduler one of rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq, # --add-server -a add real server with options # --real-server -r server-address server-addres s is host (and port) # --masquerading -m masquerading (NAT) # --gatewaying -g gatewaying (direct routing) (default) # --delete-server -d delete real server # --persistent -p [timeout] persistent service（会话保持功能） # --set tcp tcpfin udp set connection timeout values # --weight -w weight capacity of real server # --ipip -i ipip encapsulation (tunneling) 提示：更多参数请ipvsadm -help自行查看 命令执行过程及检查配置的执行结果 ipvsadm -C ipvsadm --set 30 5 60 ipvsadm -A -t 172.16.1.17:3306 -s wrr -p 20 ipvsadm -a -t 172.16.1.17:3306 -r 172.16.1.51:3306 -g -w 1 ipvsadm -a -t 172.16.1.17:3306 -r 172.16.1.52:3306 -g -w 1 ipvsadm -L -n --sort ipvsadm -d -t 172.16.1.17:3306 -r 172.16.1.51:3306 #==>删除测试 ipvsadm -L -n --sort ipvsadm -a -t 172.16.1.17:3306 -r 172.16.1.51:3306 -g -w 1 ipvsadm -L -n --sort手工在RS端绑定lo网卡及抑制ARP#每台real server端执行db01、db02 命令： ifconfig lo:17 172.16.1.17 up route add -host 172.16.1.17 dev lo 工作中写到配置文件: vim /etc/sysconfig/network-scripts/ifcfg-lo:17 #centos7 添加方法 ip addr add 172.16.1.17/32 dev lo label lo:17 route add -host 172.16.1.17 dev lo 过程： ifconfig lo:17 route -n|grep 172.16.1.17 #172.16.1.17 0.0.0.0 255.255.255.255 UH 0 0 0 lo 每个集群节点上的环回接口（lo）设备上被绑定VIP地址（其广播地址是其本身，子网掩码是255.255.255.255，采取可变长掩码方式把网段划分成只含一个主机地址的目的是避免ip地址冲突）允许LVS-DR集群中的集群节点接受发向该VIP地址的数据包，这会有一个非常严重的问题发生，集群内部的真实服务器将尝试回复来自正在请求VIP客户端的ARP广播，这样所有的真实服务器都将声称自己拥有该VIP地址，这时客户端将有可能直接发送请求数据包到某台真实服务器上，从而破坏了DR集群的负载均衡策略。因此，必须要抑制所有真实服务器响应目标地址为VIP的ARP广播，而把客户端ARP广播的响应交给负载均衡调度器。手工在RS端抑制ARP响应#在db01、db02执行 抑制ARP响应方法如下： echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce cat /proc/sys/net/ipv4/conf/lo/arp_ignore cat /proc/sys/net/ipv4/conf/all/arp_ignore cat /proc/sys/net/ipv4/conf/all/arp_announce cat /proc/sys/net/ipv4/conf/lo/arp_announce #在web01上安装mysql测试： yum install mariadb -y mysql -h 172.16.1.17 -uroot -poldboy123 #172.16.1.17是VIP ####停掉了51，发现连不了 lvs没有健康检查功能，51停掉了，仍然请求发给51,需要手工清理51 [root@lb4-01 ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.1.17:3306 wrr persistent 20 -> 172.16.1.51:3306 Route 1 0 0 -> 172.16.1.52:3306 Route 1 0 4 [root@lb4-01 ~]# ipvsadm -d -t 172.16.1.17:3306 -r 172.16.1.51:3306 [root@lb4-01 ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.1.17:3306 wrr persistent 20 -> 172.16.1.52:3306 Route 1 0 0 重连成功，LVS的健康检查要靠keepalved配合实现抑制ARP脚本实现脚本开发脚本配置LVS RS真实服务器端 #!/bin/bash # Written by oldboy # description: Config realserver lo and apply noarp VIP=( 172.16.1.17 ) . /etc/rc.d/init.d/functions case "$1" in start) for ((i=0; i<`echo ${#VIP[*]}`; i++)) do interface="lo:`echo ${VIP[$i]}|awk -F . '{print $4}'`" /sbin/ifconfig $interface ${VIP[$i]} broadcast ${VIP[$i]} netmask 255.255.255.255 up done echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce action "Start LVS of RearServer.by old1boy" ;; stop) for ((i=0; i<`echo ${#VIP[*]}`; i++)) do interface="lo:`echo ${VIP[$i]}|awk -F . '{print $4}'`" /sbin/ifconfig $interface ${VIP[$i]} broadcast ${VIP[$i]} netmask 255.255.255.255 down done echo "close LVS Directorserver" if [ ${#VIP[*]} -eq 1 ];then echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce fi action "Close LVS of RearServer.by old2boy" ;; *) echo "Usage: $0 {start|stop}" exit 1 esac工作中可以将lo网卡写到配置文件:db01、db02上操作 cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-lo:17 [root@db01 network-scripts]# cat /etc/sysconfig/network-scripts/ifcfg-lo:17 TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="none" DEFROUTE="yes" NAME="lo:17" DEVICE="lo:17" ONBOOT="yes" IPADDR="172.16.1.17" PREFIX="32arp抑制技术参数说明arp_ignore- INTEGER 定义对目标地址为本地IP的ARP询问不同的应答模式 0 -(默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求。 1 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求。 2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内。 3 -不回应该网络界面的arp请求，而只对设置的唯一和连接地址做出回应。 4-7 -保留未使用。 8 -不回应所有（本地地址）的arp查询。 arp_announce - INTEGER 对网络接口上，本地IP地址的发出的，ARP回应，作出相应级别的限制: 确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口 0 -(默认) 在任意网络接口（eth0,eth1，lo）上的任何本地地址 1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一。如果该来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理. 2 -对查询目标使用最适当的本地地址，在此模式下将忽略这个IP数据包的源地址并尝试选择能与该地址通信的本地地址，首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址。如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.限制了使用本地的vip地址作为优先的网络接口场景2：实现LVS+keepalved L4 mysql集群高可用配置lb4-01/02[root@lb4-01 ~]# cat /etc/keepalived/keepalived.conf global_defs { router_id lb4-01 } vrrp_instance VI_1 { state MASTER #state BACKUP interface eth1 virtual_router_id 52 priority 150 #priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.1.17/24 dev eth1 label eth1:17 } } #MySQL port 3306 virtual_server 172.16.1.17 3306 { delay_loop 6 lb_algo wrr lb_kind DR persistence_timeout 20 protocol TCP real_server 172.16.1.51 3306 { weight 1 TCP_CHECK { connect_timeout 5 ##nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } real_server 172.16.1.52 3306 { weight 1 TCP_CHECK { connect_timeout 5 ## nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } } 配置完重启keepalived完成 [root@lb4-01 ~]# systemctl restart keepalived 检查 [root@lb4-01 ~]# ifconfig |grep 'eth1:17' #在web01上测试 mysql -h 172.16.1.17 -uroot -poldboy123 #停掉db01上的mariadb [root@db01 ~]# systemctl stop mariadb #在测试web01测试 mysql -h 172.16.1.17 -uroot -poldboy123 use test; show tables;场景3：实现Web4层负载及配合后端7层反向代理+web节点环境说明 2.L4+L7+WEB 大规模web负载均衡 L4: 192.168.238.15 172.16.1.15 LVS调度器（Director） 对外提供服务的VIP为192.168.238.17 192.168.238.16 172.16.1.16 LVS调度器（Director） 对外提供服务的VIP为192.168.238.17 L7: 192.168.238.5 172.16.1.5 nginx lb01 测好了。 192.168.238.6 172.16.1.6 nginx lb02 192.168.238.7 172.16.1.7 RS1（真实服务器） web01 192.168.238.8 172.16.1.8 RS2（真实服务器） web02 [root@lb4-02 keepalived]# curl -H "host:www.yunwei.com" 172.16.1.7 web01 [root@lb4-02 keepalived]# curl -H "host:www.yunwei.com" 172.16.1.8 web02配置keepalived lb4-01/02[root@lb4-01 ~]# vi /etc/keepalived/keepalived.conf global_defs { router_id lb4-01 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 53 priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.17/24 dev eth0 label eth0:17 } } #web config virtual_server 192.168.238.17 80 { delay_loop 6 lb_algo wrr lb_kind DR persistence_timeout 20 protocol TCP real_server 192.168.238.5 80 { weight 1 TCP_CHECK { connect_timeout 5 #nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 192.168.238.6 80 { weight 1 TCP_CHECK { connect_timeout 5 # nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } =============================================== vrrp_instance VI_2 { state MASTER #state BACKUP interface eth1 virtual_router_id 52 priority 150 #priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.1.17/24 dev eth1 label eth1:17 } } #MySQL config virtual_server 172.16.1.17 3306 { delay_loop 6 lb_algo wrr lb_kind DR persistence_timeout 20 protocol TCP real_server 172.16.1.51 3306 { weight 1 TCP_CHECK { connect_timeout 5 #nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } real_server 172.16.1.52 3306 { weight 1 TCP_CHECK { connect_timeout 5 # nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } }lb01、lb02配置VIP绑定,和抑制ARP(脚本)[root@lb01 conf.d]# mkdir /server/scripts -p [root@lb01 conf.d]# cd /server/scripts/ [root@lb01 scripts]# vim ipvs.sh #!/bin/bash # Written by oldboy # description: Config realserver lo and apply noarp VIP=( 192.168.238.17 ) . /etc/rc.d/init.d/functions case "$1" in start) for ((i=0; i<`echo ${#VIP[*]}`; i++)) do interface="lo:`echo ${VIP[$i]}|awk -F . '{print $4}'`" /sbin/ifconfig $interface ${VIP[$i]} broadcast ${VIP[$i]} netmask 255.255.255.255 up done echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce action "Start LVS of RearServer.by old1boy" ;; stop) for ((i=0; i<`echo ${#VIP[*]}`; i++)) do interface="lo:`echo ${VIP[$i]}|awk -F . '{print $4}'`" /sbin/ifconfig $interface ${VIP[$i]} broadcast ${VIP[$i]} netmask 255.255.255.255 down done echo "close LVS Directorserver" if [ ${#VIP[*]} -eq 1 ];then echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce fi action "Close LVS of RearServer.by old2boy" ;; *) echo "Usage: $0 {start|stop}" exit 1 esac [root@lb01 scripts]# sh ipvs.sh start Start LVS of RearServer.by old1boy [ 确定 ] #检查 [root@lb01 scripts]# ifconfig |grep 'lo:17'获取lvs+nginx+web前端用户真实IP#测试，需要把proxy_protocol给注释掉，不然访问报错。 upstream www { server 172.16.1.7:80; server 172.16.1.8:80; } server { listen 80; #listen 80 proxy_protocol; #注释 server_name www.yunwei.com; set_real_ip_from 172.16.1.0/24; #添加七层负载前经过的代理IP地址 real_ip_header proxy_protocol; #将proxy_protocol获取的IP赋值给$remote_addr location / { proxy_pass http://www; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_protocol_addr; #将proxy_protocol真实客户端的IP地址赋值给X-Forwarded-For变量携带至后端 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_headers_hash_max_size 51200; proxy_headers_hash_bucket_size 6400; } } proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这个开启 客户端访问LVS是携带源IP的，LVS仅仅是转发，DR修改目的MAC，并没有改变源IP。所以客户源IP可以被nginx lb01获取到，然后通过x-forward-for传给web节点 #查看日志 [root@web01 conf.d]# tail -f /var/log/nginx/access.log 172.16.1.6 - - [03/Mar/2023:16:14:53 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54" "192.168.238.1" 172.16.1.6 - - [03/Mar/2023:16:14:54 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54" "192.168.238.1" 172.16.1.6 - - [03/Mar/2023:16:14:54 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54" "192.168.238.1" 172.16.1.6 - - [03/Mar/2023:16:14:55 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54" "192.168.238.1" 最后一位是192.168.238.1是真实IP
集群架构学习整理 - Nginx四层负载均衡配置（九）
lb4-01、lb4-02 服务器场景1：实现MySQL数据库负载均衡实践1）环境 lb4-01 192.168.238.15 lb4-02 192.168.238.16 2）安装nginx+keepalived 3）生产场景1：实现MySQL数据库负载均衡 四层代理：192.168.238.15 172.16.1.15 DB节点：172.16.1.51 172.16.1.52 步骤： 1.克隆192.168.238.15 2.检查负载的节点正常172.16.1.51 172.16.1.52 3.配置lb4-01 192.168.238.15 4.测试 [root@lb4-01 ~]# vim /etc/nginx/nginx.conf +12 注意要在http标签外面加上如下几行 stream { include /etc/nginx/stream_conf.d/*.conf; } [root@lb4-01 nginx]# mkdir /etc/nginx/stream_conf.d/ [root@lb4-01 nginx]# cd /etc/nginx/stream_conf.d/ [root@lb4-01 stream_conf.d]# cat 01_lb4-mysql.conf upstream mysql { server 172.16.1.51:3306; server 172.16.1.52:3306; } server { listen 3306; proxy_pass mysql; } nginx -t systemctl restart nginx 注意：此场景用于代理各类tcp应用，比如，k8s集群，数据库集群，中间件应用服务器集群。 注意： 1.nginx.conf里不允许多个stream标签。 2.stream标签配置为主配置文件nginx.conf main区段。 3.可以在主配置的stream标签里嵌入include /etc/nginx/stream_conf.d/*.conf; 4.nginx.conf 里的 include /etc/nginx/conf.d/*.conf; 这个要注释掉，不然跟stream 80冲突，要不然stream里的80通过192.168.238.15:80监听 #安装Navicat for MySQL或使用Phpmyadmin进行测试场景2：实现nginx4层+Nginx多七层代理+多Web节点大并发： www:192.168.238.15----->192.168.238.5/192.168.238.6----->172.16.1.7/172.16.1.8 不需要高并发：blog:192.168.238.5/192.168.238.6----->172.16.1.7/172.16.1.8 四层代理：192.168.238.15 172.16.1.15 四层代理：192.168.238.16 172.16.1.16 L7层代理：172.16.1.5 172.16.1.5 L7层代理：172.16.1.6 172.16.1.6 Web节点：172.16.1.7 172.16.1.8 ==1）四层负载均衡(lb4-01) 192.168.238.15： 完整配置如下： [root@lb4-01 stream_conf.d]# cat /etc/nginx/stream_conf.d/06_web.conf upstream proxy_7 { server 192.168.238.5:80; server 192.168.238.6:80; } server { listen 80; proxy_pass proxy_7; #注意，不带HTTP。 #proxy_protocol on; #开启proxy_protocol协议 } 注意别忘了： 1.stream里的监听80端口不能和7层的监听80冲突。 因此，注释结尾 #include /etc/nginx/conf.d/*.conf; 2.指定VIP (keepalived配置) 192.168.238.17:80; nginx -t systemctl restart nginx七层负载均衡(lb01,lb02) #lb01 [root@lb01 conf.d]# cat /etc/nginx/conf.d/05_www.conf upstream www { server 172.16.1.7 weight=1; #默认80端口 server 172.16.1.8 weight=1; } server { listen 80; server_name www.yunwei.com; location / { proxy_pass http://www; proxy_set_header Host $http_host; } } nginx -t systemctl restart nginx #lb02 [root@lb02 conf.d]# cat /etc/nginx/conf.d/05_www.conf upstream www { server 172.16.1.7 weight=1; server 172.16.1.8 weight=1; } server { listen 80; server_name www.yunwei.com; location / { proxy_pass http://www; proxy_set_header Host $http_host; } } nginx -t systemctl restart nginx部署web01,web02相同 [root@web01 conf.d]# cat /etc/nginx/conf.d/05_www.conf server { listen 80; server_name www.yunwei.com; root /data/www; location / { index index.html; } } nginx -t systemctl restart nginx #在7层lb01上测试 [root@lb01 conf.d]# curl -H "host:www.yunwei.com" 172.16.1.7 web01 [root@lb01 conf.d]# curl -H "host:www.yunwei.com" 172.16.1.8 web02必要测试步骤;测试早前配置的7层代理情况 #在4层lb4-01测试 [root@lb4-01 nginx]# curl -H "host:www.yunwei.com" 192.168.238.5 web01 [root@lb4-01 nginx]# curl -H "host:www.yunwei.com" 192.168.238.5 web02 [root@lb4-01 nginx]# curl -H "host:www.yunwei.com" 192.168.238.6 web01 [root@lb4-01 nginx]# curl -H "host:www.yunwei.com" 192.168.238.6 web02 #测试L4(15)---L7(5,6)--->Web(7,8) [root@web02 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.15 web01 [root@web02 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.15 web01 [root@web02 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.15 web02 [root@web02 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.15 web02场景3：实现nginx4层+Nginx多七层代理+多Web节点【获取真实用户IP地址】四层负载均衡 http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_protocol 开启proxy_protocol协议 proxy_protocol on; 语法 Syntax: proxy_protocol on | off; Default: proxy_protocol off; Context: stream, server This directive appeared in version 1.9.2. Enables the PROXY protocol for connections to a proxied server. http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt https://www.nixops.me/articles/PROXY_protocol_pass_client_ip.html 使用PROXY protocol获取客户IP 获取客户IP是常见的需求，对于大流量的项目都会使用反向代理、负载均衡等，甚至多重代理，导致架构和网络都比较复杂，在这种情况下获取IP就不那么容易了。七层代理可以通过添加头信息来实现，如http协议的X-Forword-For，还比较方便；四层代理基本无法简单的获取到客户端IP地址，像LVS的FULLNAT模式，前端LVS把真实IP写在TCP option里面，后端服务器用内核toa模块获取客户IP；haproxy配合TPROXY也是类似的方式实现，两者都需编译内核非常麻烦，这种情况下就可以考虑使用代理协议 一、代理协议简介 代理协议即 PROXY protocol,是haproxy的作者Willy Tarreau于2010年开发和设计的一个Internet协议，通过为tcp添加一个很小的头信息，来方便的传递客户端信息（协议栈、源IP、目的IP、源端口、目的端口等)，在网络情况复杂又需要获取客户IP时非常有用。如： 多层NAT网络 TCP代理（四层）或多层tcp代理 https反向代理http(某些情况下由于Keep-alive导致不是每次请求都传递x-forword-for) 代理协议分为v1和v2两个版本，v1人类易读，v2是二进制格式，方便程序处理。Proxy protocol是比较新的协议，但目前已经有很多软件支持，如haproxy、nginx、apache、squid、mysql等等，要使用proxy protocol需要两个角色sender和receiver,sender在与receiver之间建立连接后，会先发送一个带有客户信息的tcp header,因为更改了tcp协议，需receiver也支持proxy protocol，否则不能识别tcp包头，导致无法成功建立连接。#配置开启proxy_protocol，lb4-01(192.168.238.15) [root@lb4-01 stream_conf.d]# cat /etc/nginx/stream_conf.d/06_web.conf upstream proxy_7 { server 172.16.1.5:80; server 172.16.1.6:80; } server { listen 80; proxy_pass proxy_7; #注意，不带HTTP。 proxy_protocol on; #开启proxy_protocol协议================== } nginx -t systemctl reload nginx #七层负载均衡(lb01,lb02) 192.168.238.5/6 [root@web01 conf.d]# cat /etc/nginx/conf.d/05_www.conf upstream www { server 172.16.1.7:80; server 172.16.1.8:80; } server { listen 80 proxy_protocol; #添加proxy_protocol server_name www.yunwei.com; set_real_ip_from 172.16.1.0/24; #添加七层负载前经过的代理IP地址 real_ip_header proxy_protocol; #将proxy_protocol获取的IP赋值给$remote_addr location / { proxy_pass http://www; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_protocol_addr; #将proxy_protocol真实客户端的IP地址赋值给X-Forwarded-For变量携带至后端 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #不加下面两条，可能会报错nginx: [warn] could not build optimal proxy_headers_hash, you should increase either proxy_headers_hash_max_size: 512 or proxy_headers_hash_bucket_size: 64; ignoring proxy_headers_hash_bucket_size proxy_headers_hash_max_size 51200; proxy_headers_hash_bucket_size 6400; } } #在web01上查看访问结果 [root@web01 nginx]$tail -f /var/log/nginx/access.log 172.16.1.5 - - [26/Dec/2022:16:38:25 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" "192.168.238.1, 192.168.238.15" 172.16.1.5 - - [26/Dec/2022:16:38:26 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" "192.168.238.1, 192.168.238.15" 172.16.1.5 - - [26/Dec/2022:16:38:27 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" "192.168.238.1, 192.168.238.15" 最后面显示用户真实和代理ip"192.168.238.1, 192.168.238.15"Nginx多级代理，获取客户端真实请求ip以及每级代理iphttps://blog.csdn.net/simonchi/article/details/53944308haproxy + nginx + proxy protocol 获得客户真实IP方法https://www.cnblogs.com/hh2737/p/8951872.html场景4：测试众多nginx http变量值[root@web01 conf.d]# cat 05_www.conf server { listen 80; server_name www.yunwei.com; root /data/www; location / { return 200 "web01，老男孩Linux77最优班级\n remote_addr: $remote_addr\n proxy_add_x_forwarded_for:$proxy_add_x_forwarded_for\n proxy_protocol_addr: $proxy_protocol_addr\n http_x_forwarded_for:$http_x_forwarded_for\n"; } }从DB01访问：192.168.238.51---192.168.238.15----172.16.1.5----172.16.1.7[root@db01 ~]# curl -H "host:www.yunwei.com" 192.168.238.15 web01，老男孩Linux77最优班级 remote_addr: 172.16.1.5 proxy_add_x_forwarded_for:192.168.238.51, 172.16.1.5 http_x_forwarded_for:192.168.238.51 更改web01主配置日志测试： log_format access '-$proxy_protocol_addr-,--$remote_addr--,---$http_x_forwarded_for---,----$proxy_add_x_forwarded_for----,$remote_user,$time_local,$host,$request,$status,$http_referer,$HTTP_X_UP_CALLING_LINE_ID,$request_time,$http_user_agent $upstream_addr $upstream_response_time $upstream_cache_status'; access_log /var/log/nginx/access.log access; ---,--172.16.1.5--,---192.168.238.51, 192.168.238.15---,----192.168.238.51, 192.168.238.15, 172.16.1.5---- -$proxy_protocol_addr-,--$remote_addr--,---$http_x_forwarded_for---,----$proxy_add_x_forwarded_for----日志结果：[root@web01 conf.d]# tail /var/log/nginx/access.log ---,--172.16.1.5--,---192.168.238.1---,----192.168.238.1, 172.16.1.5----,-,03/Mar/2023:16:20:49 +0800,www.yunwei.com,GET / HTTP/1.0,304,-,-,0.000,Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54 - - - ---,--172.16.1.5--,---192.168.238.1---,----192.168.238.1, 172.16.1.5----,-,03/Mar/2023:16:20:49 +0800,www.yunwei.com,GET / HTTP/1.0,200,-,-,0.000,Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54 - - - nginx多层代理获取客户端的真实ip总结： 1、要有http_realip_module模块支持 2、在nginx.conf文件中 proxy_pass http://www; #添加下面三行 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 3、在每一层nginx日志中的打印的"$http_x_forwarded_for"就是真实客户端的ip地址。 4、后台服务器获取真实的客户端ip地址： headers中的X-Forwarded-For选项中逗号前第一个ip就是真实客户端ip 日志中获取真实ip: $http_x_forwarded_for 就是获取真实ip的变量 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; 提示： 1、set_real_ip_from 是指接受从哪个信任前代理处获得真实用户ip 2、real_ip_header 是指从接收到报文的哪个http首部去获取前代理传送的用户ip 3、real_ip_recursive 是否递归地排除直至得到用户ip（默认为off） 首先，real_ip_header 指定一个http首部名称，默认是X-Real-Ip，假设用默认值的话，nginx在接收到报文后，会查看http首部X-Real-Ip。 （1）如果有1个IP，它会去核对，发送方的ip是否在set_real_ip_from指定的信任ip列表中。如果是被信任的，它会去认为这个X-Real-Ip中的IP值是前代理告诉自己的，用户的真实IP值，于是，它会将该值赋值给自身的$remote_addr变量；如果不被信任，那么将不作处理，那么$remote_addr还是发送方的ip地址。 （2）如果X-Real-Ip有多个IP值，比如前一方代理是这么设置的：proxy_set_header X-Real-Ip $proxy_add_x_forwarded_for; 得到的是一串IP，那么此时real_ip_recursive的值就至关重要了。nginx将会从ip列表的右到左，去比较set_real_ip_from 的信任列表中的ip。 如果real_ip_recursive为off，那么，当最右边一个IP，发现是信任IP，即认为下一个IP（右边第二个）就是用户的真正IP； 如果real_ip_recursive为on，那么将从右到左依次比较，知道找到一个不是信任IP为止。 然后同样把IP值复制给$remote_addr。http_proxy_module相关参数 相关重要参数 参数说明 proxy_pass http://server_pools; 通过proxy_pass功能把用户的请求转向到反向代理定义的upstream服务器池 proxy_set_header Host $host; 在代理向后端服务器发送的http请求头中加入host字段信息，用于当后端服务器配置有多个虚拟主机时，可以识别代理的是哪个虚拟主机。这是节点服务器多虚拟主机时的关键配置 proxy_set_header X-Forwarded-For $remote_addr; 在代理向后端服务器发送的http请求头中加入X-Forwarded-For字段信息，用于后端服务器程序、日志等接收记录真实用户的IP，而不是代理服务器IP。 这是反向代理时，节点服务器获取用户真实IP的必要功能配置 [root@web02 conf.d]# tail -f /var/log/nginx/access.log 172.16.1.5 - - [02/Aug/2021:16:45:59 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-" 172.16.1.5 - - [02/Aug/2021:16:46:00 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-" log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; 结果： $remote_addr 172.16.1.5 $http_x_forwarded_for - 3. 经过7层反向代理后的节点服务器记录用户IP企业案例 [root@lb01 conf.d]# cat 03_www.yunwei.com.conf upstream www { server 172.16.1.7 weight=1 ; #默认80端口 server 172.16.1.8 weight=1; #默认80端口 } server { listen 80; server_name www.yunwei.com; location / { proxy_pass http://www; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $remote_addr; <==在代理向后端服务器发送的http请求头中加入X-Forwarded-For字段信息，用于后端服务器程序、日志等接收记录真实用户的IP，而不是代理服务器的IP。 } } [root@lb01 conf.d]# nginx -t [root@lb01 conf.d]# systemctl restart nginx 测试：使用DB01或者浏览器测试 [root@db01 ~]# curl -H"host:www.yunwei.com" 172.16.1.5 web01 [root@db01 ~]# curl -H"host:www.yunwei.com" 172.16.1.5 web02 [root@web02 conf.d]# tail -f /var/log/nginx/access.log 172.16.1.5 - - [02/Aug/2021:16:45:59 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-" 172.16.1.5 - - [02/Aug/2021:16:46:00 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-" 172.16.1.5 - - [02/Aug/2021:16:51:21 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "172.16.1.5" 172.16.1.5 - - [02/Aug/2021:16:51:52 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "172.16.1.51" 172.16.1.5 - - [02/Aug/2021:16:52:23 +0800] "GET /favicon.ico HTTP/1.0" 404 555 "http://www.yunwei.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "192.168.238.1" 172.16.1.5 - - [02/Aug/2021:16:52:25 +0800] "GET /favicon.ico HTTP/1.0" 404 555 "http://www.yunwei.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "192.168.238.1" 172.16.1.5 - - [02/Aug/2021:16:52:28 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "192.168.238.1" 172.16.1.5 - - [02/Aug/2021:16:52:28 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "192.168.238.1" 看结尾$http_x_forwarded_for列如果出现访问的客户的真实IP就对了 浏览器访问的结果，真实IP是192.168.238.1，如果通过db01访问真实IP就是172.16.1.51 结果： $remote_addr依然是172.16.1.5，上级代理IP $http_x_forwarded_for 192.168.238.1 nginx反向代理的若干参数说明： fastcgi_pass http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html proxy_pass http://nginx.org/en/docs/http/ngx_http_proxy_module.html uwsgi_pass http://nginx.org/en/docs/http/ngx_http_uwsgi_module.html 扩展：搭建nginx cache服务 作为静态web服务的前端缓存。 https://blog.csdn.net/dengjiexian123/article/details/53386586
lb01、lb02服务器规划：HOSTNAME IP 说明lb01 192.168.238.5 Keepalived主服务器（Nginx主负载均衡器）lb02 192.168.238.6 Keepalived备服务器（Nginx辅负载均衡器）web01 192.168.238.7 web01服务器web02 192.168.238.8 web02服务器#部署web01 [root@web01 conf.d]# cat /etc/nginx/conf.d/05_www.conf server { listen 80; server_name www.yunwei.com; root /data/www; location / { index index.html; } } [root@web01 conf.d]# mkdir -p /data/www [root@web01 conf.d]# echo web01 >/data/www/index.html [root@web01 conf.d]# nginx -t [root@web01 conf.d]# systemctl restart nginx [root@web01 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.7 web01#部署web01 [root@web01 conf.d]# cat /etc/nginx/conf.d/05_www.conf server { listen 80; server_name www.yunwei.com; root /data/www; location / { index index.html; } } [root@web01 conf.d]# mkdir -p /data/www [root@web01 conf.d]# echo web02 >/data/www/index.html [root@web01 conf.d]# nginx -t [root@web01 conf.d]# systemctl restart nginx [root@web01 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.8 web02#部署lb01、lb02 [root@lb01 conf.d]# cat /etc/nginx/conf.d/05_www.conf upstream www { server 172.16.1.7 weight=1; server 172.16.1.8 weight=1; } server { listen 80; server_name www.yunwei.com; location / { proxy_pass http://www; proxy_set_header Host $http_host; } } nginx -t systemctl restart nginx #测试 [root@lb01 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.5 web01 [root@lb01 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.5 web02 [root@lb01 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.6 web01 [root@lb01 conf.d]# curl -H "host:www.yunwei.com" 192.168.238.6 web02#安装keepalived #lb01、lb02分别安装keepalived yum install keepalived -y systemctl start keepalived #先不启动，修改过配置文件后在启动#Keepalived配置文件说明 TOP HIERACHY GLOBAL CONFIGURATION VRRPD CONFIGURATION LVS CONFIGURATION(管理LVS的，nginx此处删掉) #Master配置说明。 [root@lb01 keepalived]# cat keepalived.conf global_defs { router_id lb01 #<==id为lb01，不同的keepalived.conf此ID要唯一。 } vrrp_instance VI_1 { #<==实例名字为VI_1，相同实例的备节点名字要和这个相同。 state MASTER #<==状态为MASTER，备节点状态需要为BACKUP。 interface eth0 #<==通信接口为eth0，此参数备节点设置和主节点相同。 virtual_router_id 51 #<==实例ID为51，keepalived.conf里唯一。 priority 150 #<==优先级为150，备节点的优先级必须比此数字低。 advert_int 1 #<==通信检查间隔时间1秒。 authentication { auth_type PASS #<==PASS认证类型，此参数备节点设置和主节点相同。 auth_pass 1111 #<==密码是1111，此参数备节点设置和主节点相同。 } virtual_ipaddress { 192.168.238.3/24 dev eth0 label eth0:3 #<==虚拟IP，即VIP，子网掩码为24位，绑定接口为eth0，别名为eth0:3，此参数备节点设置和主节点相同。 } } #提示：此处设置的虚拟IP为192.168.238.3，即网站域名绑定的IP。配置 lb（单实例）#配置 lb01 keepalved.conf [root@lb01 ~]# cp /etc/keepalived/keepalived.conf{,.ori} [root@lb01 ~]# vi /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id lb01 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.3/24 dev eth0 label eth0:3 } } #启动 systemctl start keepalived systemctl enable keepalived ps -ef|grep keepalived ifconfig|grep '192.168.238.3'#配置 lb02 keepalved.conf [root@lb02 ~]# cp /etc/keepalived/keepalived.conf{,.ori} [root@lb02 ~]# vi /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id lb02 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.3/24 dev eth0 label eth0:3 } } #启动 systemctl start keepalived systemctl enable keepalived ps -ef|grep keepalived ifconfig|grep '192.168.238.3' 停止一端服务器。看另一端IP接管情况配置 lb（多实例）#配置 lb01 keepalved.conf [root@lb01 conf.d]$cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id lb01 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.3/24 dev eth0 label eth0:3 } } vrrp_instance VI_2 { state BACKUP interface eth0 virtual_router_id 52 priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.4/24 dev eth0 label eth0:4 } } #启动 systemctl start keepalived systemctl enable keepalived ps -ef|grep keepalived ifconfig|egrep '192.168.238.3|192.168.238.4'#配置 lb02 keepalved.conf [root@lb02 conf.d]$cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id lb02 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.3/24 dev eth0 label eth0:3 } } vrrp_instance VI_2 { state MASTER interface eth0 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.4/24 dev eth0 label eth0:4 } } #启动 systemctl start keepalived systemctl enable keepalived ps -ef|grep keepalived ifconfig|egrep '192.168.238.3|192.168.238.4'说明：单实例和多实例场景对比单实例hosts lb01: 192.168.238.3 www.yunwei.com blog.yunwei.com lb02:热备 浪费机器 多实例hosts 两边跑服务; lb01: 192.168.238.3 www.yunwei.com lb02: 192.168.238.4 blog.yunwei.com 某一台宕机，总流量能被撑住即可。LB配置脚本配置如下脚本【参考】[root@lb01 scripts]# cat /server/scripts/chk_nginx_proxy.sh #!/bin/sh if [ `netstat -lntup|grep nginx|wc -l` -ne 1 ];then systemctl stop keepalived fi [root@lb01 scripts]# chmod +x chk_nginx_proxy.sh [root@lb01 scripts]# /server/scripts/chk_nginx_proxy.sh ##要可以执行 测试： [root@lb01 scripts]# pkill nginx [root@lb01 scripts]# sh chk_nginx_proxy.sh [root@lb01 scripts]# ps -ef|egrep "nginx|keep" [root@lb01 scripts]# cat /etc/keepalived/keepalived.conf global_defs { router_id lb01 } vrrp_script chk_nginx_proxy { #<==定义vrrp脚本，检测HTTP端口。 script "/server/scripts/chk_nginx_proxy.sh" #<==执行脚本，当nginx服务有问题，就停掉keepalived服务。 interval 2 #<==间隔2秒。 weight 2 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 53 priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.3/24 dev eth0 label eth0:3 } track_script { chk_nginx_proxy #<==触发检查。 } } vrrp_instance VI_2 { state MASTER interface eth0 virtual_router_id 52 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.4/24 dev eth0 label eth0:4 } } [root@lb02 scripts]# cat /etc/keepalived/keepalived.conf global_defs { router_id lb02 } vrrp_script chk_nginx_proxy { #<==定义vrrp脚本，检测HTTP端口。 script "/server/scripts/chk_nginx_proxy.sh" #<==执行脚本，当nginx服务有问题，就停掉keepalived服务。 interval 2 #<==间隔2秒。 weight 2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 53 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.3/24 dev eth0 label eth0:3 } track_script { chk_nginx_proxy #<==触发检查。 } } vrrp_instance VI_2 { state BACKUP interface eth0 virtual_router_id 52 priority 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.238.4/24 dev eth0 label eth0:4 } }
集群架构学习整理 - Nginx负载均衡配置（七）
lb01、lb02 服务器#web01 & web02创建测试 [root@web01 conf.d]# cat 03_test.conf server { listen 80; server_name test.yunwei.com; charset utf-8; root /data/test; location / { index index.html; } } nginx -t systemctl reload nginx mkdir -p /data/test echo 'web01' > /data/test/index.html #注：web02服务器替换web02 chown www.www /data/test -R ll /data/test/index.html 测试 [root@web02 conf.d]# curl -H "host:test.yunwei.com" 172.16.1.7 web01 [root@web02 conf.d]# curl -H "host:test.yunwei.com" 172.16.1.8 web02 #在web01上配置phpmyadmin [root@web01 conf.d]# cat /etc/nginx/conf.d/04_phpmyadmin.conf server { listen 80; server_name phpmyadmin.yunwei.com; root /data/phpmyadmin; index index.php index.html; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } nginx -t systemctl reload nginx ### mkdir /data/phpmyadmin -p cd /server/tools wget https://files.phpmyadmin.net/phpMyAdmin/5.1.1/phpMyAdmin-5.1.1-all-languages.zip unzip phpMyAdmin-5.1.1-all-languages.zip -d /data/phpmyadmin/ cd /data/phpmyadmin/ mv phpMyAdmin-5.1.1-all-languages/* . rmdir phpMyAdmin-5.1.1-all-languages cp config.sample.inc.php config.inc.php vim +30 /data/phpmyadmin/config.inc.php 改为 $cfg['Servers'][$i]['host'] = 'db01.yunwei.com'; #复制程序到web02并添加配置文件 rsync -avz -e "ssh -p 22" /data/phpmyadmin/ root@172.16.1.8:/data/phpmyadmin/ #在web02上配置phpmyadmin [root@web01 conf.d]# cat /etc/nginx/conf.d/04_phpmyadmin.conf server { listen 80; server_name phpmyadmin.yunwei.com; root /data/phpmyadmin; index index.php index.html; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } nginx -t systemctl reload nginx #部署lb01 phpmyadmin.yunwei.com虚拟主机反向代理lb01配置 [root@lb01 conf.d]# cat /etc/nginx/conf.d/04_phpmyadmin.conf upstream backend { server 172.16.1.7 weight=1; #默认80端口 server 172.16.1.8 weight=1; #默认80端口 } server { listen 80; server_name phpmyadmin.yunwei.com; location / { proxy_pass http://backend; proxy_set_header Host $http_host; } } #测试浏览器打开phpmyadmin.yunwei.com 登录到数据库，然后刷新感受请求到不同节点后，出现未登录状态。 可以通过谷歌f12查看请求报文和响应报文。 登录172.16.1.51部署redis缓存 采用Redis共享方式来实现会话保持： #配置lb01 & lb02 安装nginx，参考上面，安装好nginx，然后配置 vi /etc/nginx/conf.d/01_lb_test.conf server { listen 80; server_name test.yunwei.com; location / { proxy_pass http://172.16.1.7:80; proxy_set_header Host $http_host; } } nginx -t systemctl reload nginx tail -f /var/log/nginx/access.log 基于动静分离：参考day59笔记基于设备区分：参考day59笔记根据不同业务做负载均衡#web01配置 [root@web01 ~]# cat /etc/nginx/conf.d/05_www.conf server { listen 80; server_name www.yunwei.com; root /data/www; location / { index index.html; } } [root@web01 ~]# mkdir /data/www [root@web01 ~]# echo "register_web01..." > /data/www/index.html [root@web01 ~]# nginx -t [root@web01 ~]# systemctl reload nginx#web02配置 [root@web02 ~]# cat /etc/nginx/conf.d/05_www.conf server { listen 80; server_name www.yunwei.com; root /data/www; location / { index index.html; } } [root@web02 ~]# mkdir /data/www [root@web02 ~]# echo "login--web02.." >> /data/www/index.html [root@web01 ~]# nginx -t [root@web01 ~]# systemctl reload nginx#负载均衡lb01配置 [root@lb01 conf.d]# cat /etc/nginx/conf.d/05_www.conf upstream register { server 172.16.1.7:80; } upstream login { server 172.16.1.8:80; } server { listen 80; server_name www.yunwei.com; location /register { proxy_pass http://register/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr; } location /login { proxy_pass http://login/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr; } } [root@lb01 ~]# nginx -t [root@lb01 ~]# systemctl reload nginx
db01服务器[root@db01 ~]$ yum install mariadb-server mariadb -y 启动Mariadb数据库, 并加入开机启动 [root@db01 ~]$ systemctl start mariadb [root@db01 ~]$ systemctl enable mariadb #检查 [root@db01 ~]$lsof -i :3306 [root@db01 ~]$ps -ef|grep mariadb [root@db01 blog]$ mysql #直接进去 给Mariadb配置登陆密码,并设置新密码进行登录数据库 [root@db01 ~]$ mysqladmin -uroot password oldboy123 [root@db01 ~]$ mysql -uroot -poldboy123 [root@db01 ~]$ mysqladmin -uroot -poldboy123 password oldboy #有密码更改密码 #登录MySQL，删除无用的用户 drop user root@'::1'; delete from mysql.user where user=''; delete from mysql.user where host='db01'; delete from mysql.user where host='127.0.0.1'; grant all on *.* to root@'172.16.1.%' identified by 'oldboy123'; select user,host from mysql.user; flush privileges;#php测试,配置hosts文件 #Nginx连接Fastcgi服务器配置如下 [root@web01 blog]$cat /etc/nginx/conf.d/01_blog.conf server { listen 80; server_name blog.yunwei.com; root /data/blog; index index.php index.html; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } 在/data目录下创建test_php.php文件 [root@web01 ~]$ mkdir /data/blog -p [root@web01 ~]$ cat /data/blog/test_php.php <?php phpinfo(); ?> [root@web01 ~]$ chown -R www.www /data/blog #浏览器测试 http://blog.yunwei.com//test_php.php #mariadb测试 [root@web01 ~]$ cat /data/blog/test_mysql.php <?php $servername = "172.16.1.51"; $username = "root"; $password = "oldboy123"; // 创建连接 $conn = mysqli_connect($servername, $username, $password); // 检测连接 if (!$conn) { die("Connection failed: " . mysqli_connect_error()); } echo "php连接MySQL数据库成功。"; ?> [root@web01 ~]$ chown -R www.www /data/blog #浏览器测试 http://blog.yunwei.com/test_mysql.php 扩展:企业级应用实战案例：科学授权站点目录权限和属组方法 #（1）生产授权方案（新手可不用）： [root@web01 blog]# chown -R root.root /data/blog [root@web01 blog]# mkdir -p /data/blog/uploads [root@web01 blog]# chown -R www.www /data/blog/uploads #此目录可能没有。 [root@web01 blog]# ll wp-content/ plugins ##blog增加功能 root.root themes ##blog主题皮肤 root.root uploads ##上传目录www.www #（2）LNMP企业级核心安全优化思想： chown -R www.www /data/blog/uploads/ #安全隐患很大。 #黑客会放Webshell.php木马到/data/blog/upload/来遍历文件插入广告 或者提权root。 #执行放的webshell,http://xx/upload/webshell.php ##轮询站点， 改所有站点文件，嵌入它的广告 #网站安全防护露点： 对外：http,https（控制这里），没办法白名单。 对内：ssh(禁止对外访问)，可以白名单。 # (3)#针对80端口安全防护限制： 1.php程序控制，上传的程序扩展名不能是.php,.sh等等 2.访问/data/blog/upload/（*.php return 403） location /upload/ \.php$ { return 403 } 3.挂载NFS mount,noexec,nosuid 4.通过架构，限制动态请求方法 location /upload/ 禁止GET，不能浏览。 解决方法：动静分离 动态：location /upload/ 禁止GET，不能浏览。 静态：没有PHP环境 location /upload/ 5.配置waf防火墙或者开发第三方安全模块（比如还可以控制sql语句执行等） 6.永远确保站点权限最优 #工作启动Nginx脚本：start_nginx.sh chown -R root.root /data/blog chown -R www.www /data/blog/uploads #启动前做站点目录，权限和用户做检查。 #检测：权限、用户和组不对，自测、报警。。省略检测脚本100行。提供思路 systemctl reload nginx # (4) 因blog需要使用数据库, 所以需要建立blog数据库，并授予指定权限 [root@web01 ~]# mysql -uroot -poldboy123 mysql> create database blog; mysql> exit;企业级应用实战案例：采用异地db01.yunwei.com方式访问数据库，而不是本机localhost#db01上操作 MariaDB [(none)]> create database blog; #创建blog数据库 MariaDB [(none)]> show databases; #查看 MariaDB [(none)]> grant insert,delete,update,select,create,alter on blog.* to blog@'172.16.1.%' identified by 'oldboy123'; #MariaDB [(none)]> grant all privileges on blog.* to blog@'172.16.1.%' identified by 'oldboy123';#创建用户密码并 授权。 MariaDB [(none)]> flush privileges; Query OK, 0 rows affected (0.00 sec) ##### all privileges为所有权限： 本次科学权限：select,delete,insert,update,create,alter 工作中生产线应该：select,delete,insert,update 针对数据内容 create,alter 表结构，库结构。 #一定一定由DBA或运维控制。 企业故障案例： 表结构被开发修改了，导致运维背锅。 最终比对备份的表结构和上线数据库表结构，发现开发改了表结构。 解决办法：收回select,delete,insert,update以外的权限由DBA控制。 #测试 [root@db01 blog]# mysql -ublog -poldboy123 -h172.16.1.51 MariaDB [(none)]> #修改/etc/hosts为如下 [root@web01 blog]# grep db01 /etc/hosts 172.16.1.51 db01 db01.yunwei.com #db01.yunwei.com为连 接数据库的域名。#部署WordPress博客 5) 通过浏览器访问http://blog.yunwei.com/, 并部署该产品 数据库名blog 账户名blog 密码oldboy123 数据库主机db01.yunwei.com 表前缀oldboy_ 部署知乎软件Wecenter 知乎产品官方：https://www.wecenter.com/downloads/ 配置Nginx虚拟主机站点，域名为zh.yunwei.com [root@web01 ~]# cat /etc/nginx/conf.d/02_zh.conf server { listen 80; server_name zh.yunwei.com; root /data/zh; index index.php index.html; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } #重启nginx服务 [root@web01 ~]# nginx -t [root@web01 ~]# systemctl reload nginx 下载Wecenter产品，部署并授权 [root@web01 ~]# cd /server/tools [root@web01 tools]# rz #回车上传知乎软件 [root@web01 tools]# unzip WeCenter_3-6-0.zip -d /data/zh [root@web01 tools]# chown -R www.www /data/zh/ #部署完需要 优化目录权限 #db01上操作 wecenter产品也需要使用数据库, 所以需要手动建立数据库 [root@db01 tools]# mysql -uroot -poldboy123 #登陆数据库 MariaDB [(none)]> create database zh; #创建zh数据库 MariaDB [(none)]> grant all on zh.* to zh@'localhost' identified by 'oldboy123'; #先给全部，安装后，在给下面的权限，不然安装出错 MariaDB [(none)]> grant select,insert,update,delete on zh.* to 'zh'@'172.16.1.%' identified by 'oldboy123'; #异地 数据库用户，只授权增删改查。 MariaDB [(none)]> flush privileges; MariaDB [(none)]> quit 通过浏览器访问zh.yunwei.com，并通过网页配置，最终结果 产品优化 #权限优化 chown -R root.root /data/zh chown -R www.www /data/zh/uploads /data/zh/cache/ /data/zh/tmp/ #限制目录下php被访问 location ~* /(?:uploads|cache|tmp)/.*\.php$ { deny all; } #前后台分离（独立后台服务器） <==生产场景方案 #动静分离（独立静态服务器） <==生产场景方案拆分静态资源至独立存储服务器NFS#为什么拆分静态资源至独立存储服务器 当后端的web节点出现多台时，会导致用户上传的图片、视频附件等内容仅上传至一台web服务器，那么其他的web服务器则无法访问到该图片。 #新增一台nfs存储解决了什么问题 1.保证了多台web节点静态资源一致。 2.有效节省多台web节点的存储空间。 3.统一管理静态资源，便于后期推送至CDN进行静态资源加速 快速扩展一台web节点环境规划 nfs服务端，操作步骤如下 useradd -u1111 www -s /sbin/nologin -M 安装并配置nfs [前面已配置] [root@nfs01 ~]# rpm -qa nfs-utils nfs-utils-1.3.0-0.68.el7.x86_64 [root@nfs01 ~]# yum install nfs-utils -y [root@nfs01 ~]# cat /etc/exports /data/blog 172.16.1.0/24(rw,sync,all_squash,anonuid=1111,anongid=1111) /data/zh 172.16.1.0/24(rw,sync,all_squash,anonuid=1111,anongid=1111) [root@nfs01 ~]# systemctl reload nfs 创建共享目录，并进行授权 useradd -u 1111 -s /sbin/nologin -M [root@nfs01 ~]# mkdir /data/{blog,zh} -p [root@nfs01 ~]# chown -R www.www /data/ 启动nfs服务，并加入开机自启 [root@nfs01 ~]# systemctl restart rpcbind nfs [root@nfs01 ~]# systemctl enable rpcbind nfs web01节点安装nfs，然后使用showmount查看服务端共享的资源 [root@web01 ~]# yum install nfs-utils -y [root@web01 ~]# showmount -e 172.16.1.31 Export list for 172.16.1.31: /data/zh 172.16.1.0/24 /data/blog 172.16.1.0/24 如何查找blog静态资源存放的位置 浏览器->右键->检查->Network->选择左上角的Select按钮->点击对应的图 片，然后能获取到对应的url地址，如下 http://blog.yunwei.com/wp-content/uploads/2021/07/ 备份web01服务器上blog的静态资源，因为该服务器上的资源资源最全 [root@web01 blog]# scp -rp /data/blog/wp-content/uploads/* root@172.16.1.31:/data/blog/wp-content/uploads web01客户端执行挂载操作 [root@web01 blog]# mount -t nfs 172.16.1.31:/data/blog/wp-content/uploads /data/blog/wp-content/uploads/ [root@web01 blog]# df -h 将挂载信息加入开机自启 [root@web01 blog]# tail -1 /etc/fstab 172.16.1.31:/data/blog/wp-content/uploads /data/blog/wp-content/uploads nfs defaults 0 0 172.16.1.31:/data/zh/uploads /data/zh/uploads nfs defaults 0 0 [root@web01 blog]# umount 172.16.1.31:/data/blog/wp-content/uploads [root@web01 blog]# df -h|grep uploads [root@web01 blog]# mount -a [root@web01 blog]# df -h ###fstab延迟启动nfs [root@web01 blog]# systemctl list-unit-files|grep remote-fs remote-fs.target disabled [root@web01 blog]# systemctl enable remote-fs.target [root@web01 blog]# systemctl list-unit-files|grep remote-fs remote-fs.target enabled web02 web02客户端直接挂载nfs即可 [root@web02 zh]# mount -t nfs 172.16.1.31:/data/blog/wp-content/uploads /data/blog/wp-content/uploads/ [root@web02 zh]# df -h 将挂载信息加入开机自启 [root@web02 zh]# vi /etc/fstab 172.16.1.31:/data/blog/wp-content/uploads /data/blog/wp-content/uploads nfs defaults 0 0 172.16.1.31:/data/zh/uploads /data/zh/uploads nfs defaults 0 0 [root@web02 zh]# umount /data/blog/wp-content/uploads [root@web02 zh]# df -h|grep uploads [root@web02 zh]# mount -a [root@web02 zh]# df -h ###fstab延迟启动nfs [root@web01 zh]# systemctl list-unit-files|grep remote-fs remote-fs.target disabled [root@web01 zh]# systemctl enable remote-fs.target [root@web01 zh]# systemctl list-unit-files|grep remote-fs remote-fs.target enabled 定时任务（web01,web02）备份到backup #web01,web02配置rsync密码文件 echo 'oldboy123' > /etc/rsync.password chmod 600 /etc/rsync.password ll /etc/rsync.password [root@web01 /]# cat /server/scripts/bak.sh #!/bin/bash backup=/backup Path="$backup/$(hostname -i)" [ -f $Path ]||mkdir -p $Path if [ $(date +%w) -eq 2 ];then date="$(date +%F -d "-1day")_week1" else date="$(date +%F -d "-1day")" fi #备份 cd $Path &&\ tar zcfh conf_${date}.tar.gz /var/spool/cron/root /server/scripts /etc 2>/dev/null tar zcf www_${date}.tar.gz /data --exclude=/data/blog/wp-content/uploads --exclude=/data/zh/uploads 2>/dev/null tar zcf logs_${date}.tar.gz /var/log/nginx 2>/dev/null #获取原始指纹 find $Path -type f -name "*_${date}.tar.gz"|xargs md5sum >$Path/$(hostname -i)_${date}.flag #推送 rsync -az $backup/ rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password #删除7天前的数据 find $backup/ -type f -name "*.tar.gz" -mtime +7|xargs rm -f #检查nfs01的sersync，检查backup的rsync。 #定时任务 #bak 01 00 * * * /bin/sh /server/scripts/bak.sh &>/dev/null #db01 sqlbak [root@db01 ~]# cat /server/scripts/sqlbak.sh backup=/backup Path="$backup/$(hostname -i)" [ -f $Path ]||mkdir -p $Path if [ $(date +%w) -eq 2 ];then date="$(date +%F -d "-1day")_week1" else date="$(date +%F -d "-1day")" fi #备份 cd $Path &&\ /usr/bin/mysqldump -uroot -poldboy123 -A -B |gzip > allsql_${date}.sql.gz #获取原始指纹 find $Path -type f -name "*_${date}.sql.gz"|xargs md5sum >$Path/$(hostname -i)_${date}.sql.flag #推送 rsync -az $backup/ rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password #删除7天前的数据 find $backup/ -type f -name "*.tar.gz" -mtime +7|xargs rm -f [root@db01 ~]# #定时任务 #sqlbak 01 00 * * * /bin/sh /server/scripts/sqlbak.sh &>/dev/null #backup服务器要配置定时删除日志脚本，此处忽略解决会话共享，安装redisyum install epel-release -y yum install redis -y sed -i '/^bind/c bind 127.0.0.1 172.16.1.51' /etc/redis.conf grep "^bind" /etc/redis.conf systemctl start redis systemctl enable redis systemctl status redis #查看服务状态 systemctl stop redis #停止服务 systemctl restart redis #重启服务 ps -ef | grep redis #查看reids服务信息 systemctl enable redis #redis开机启动 ##### cd /etc/opt/remi/php74 修改php.ini session.save_handler = redis session.save_path = "tcp://172.16.1.51:6379" cd /etc/opt/remi/php74/php-fpm.d/www.conf 注释 ;php_value[session.save_handler] = files ;php_value[session.save_path] = /var/opt/remi/php74/lib/php/session systemctl restart php74-php-fpm.service
集群架构学习整理 - 动态web服务器配置（五）
web01、web021、使用官方仓库安装 Nginx#检查/etc/fstab 有没有挂载/data目录，记得先注释，后面会重新指定静态文件目录挂载 #可能优先使用epel里的源，怎么确保我们配置的 官方优先。 [root@web01 ~]$yum -y install yum-plugin-priorities [root@web01 ~]$ rpm -qa yum-plugin-priorities yum-plugin-priorities-1.1.31-54.el7_8.noarch [root@web01 ~]$ cat /etc/yum.repos.d/nginx.repo [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=0 priority=1 #增加优先参数，使得官方源优先epel源。 #安装Nginx [root@web01 ~]$ yum install nginx -y2、配置Nginx进程运行的用户[root@web01 ~]$ useradd -u1111 www -s /sbin/nologin -M [root@web01 ~]$ sed -i '/^user/c user www;' /etc/nginx/nginx.conf [root@web01 ~]$ grep "^user" /etc/nginx/nginx.conf3、启动Nginx，并将Nginx加入开机自启[root@web01 ~]$ systemctl start nginx [root@web01 ~]$ systemctl enable nginx [root@web01 ~]$ lsof -i:80 #查看端口对应的服务 [root@web01 ~]$ nginx -v #查看版本 nginx version: nginx/1.22.1 [root@web01 ~]$curl 192.168.238.5 # Welcome to nginx!表示正常4、使用第三方扩展源安装php7.4#安装PHP7.4 安装php第三方官方yum源 yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm -y yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm -y #安装yum-tools管理工具 yum -y install yum-utils #启用PHP 7.4 Remi存储库 yum-config-manager --enable remi-php74 #安装php扩展服务包 rpm -e $(rpm -qa|grep php) yum install php74-php php74-php-cli php74-php-common php74-php-devel php74-php-embedded php74-php-gd -y yum install php74-php-mcrypt php74-php-mbstring php74-php-pdo php74-php-xml php74-php-fpm php74-php-mysqlnd -y yum install php74-php-opcache php74-php-pecl-memcached php74-php-pecl-redis php74-php-pecl-mongodb -y [root@web02 ~]# php74 -v PHP 7.4.21 (cli) (built: Jun 29 2021 15:17:15) ( NTS ) [root@web02 ~]# rpm -ql php74-php-fpm /etc/logrotate.d/php74-php-fpm /etc/opt/remi/php74/php-fpm.conf /etc/opt/remi/php74/php-fpm.d /etc/opt/remi/php74/php-fpm.d/www.conf # 配置php-fpm用户与Nginx的运行用户保持一致 [root@web01 ~]# sed -i '/^user/c user = www' /etc/opt/remi/php74/php-fpm.d/www.conf [root@web01 ~]# sed -i '/^group/c group = www' /etc/opt/remi/php74/php-fpm.d/www.conf [root@web01 ~]# egrep "^user|^group" /etc/opt/remi/php74/php-fpm.d/www.conf user = www group = www # 启动 systemctl start php74-php-fpm systemctl enable php74-php-fpm ps -ef|grep php #授权/data目录 chown -R www.www /data/ ll -d /data
集群架构学习整理 - 备份服务器配置（四）
backup服务器1)服务端配置[root@backup ~]#yum -y install rsync [root@backup ~]#cp /etc/rsyncd.conf{,.ori} [root@backup ~]#ll /etc/rsyncd.conf{,.ori} cat > /etc/rsyncd.conf<<EOF #rsync_config----start #created by oldboy #site:https://www.shnne.com uid = rsync gid = rsync use chroot = no fake super = yes max connections = 200 timeout = 600 pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log ignore errors read only = false list = false hosts allow = 172.16.1.0/24 hosts deny = 0.0.0.0/32 auth users = rsync_backup secrets file = /etc/rsync.password [backup] comment = welcome to oldboyedu backup! path = /backup/ [data] path = /data/ EOF2)创建用户和目录[root@backup ~]$mkdir -p /backup [root@backup ~]$ls -d /backup [root@backup ~]useradd -s /sbin/nologin -M rsync [root@backup ~]$id rsync [root@backup ~]$chown -R rsync.rsync /backup/ [root@backup ~]$ll -d /backup/ [root@backup ~]$mkdir -p /data [root@backup ~]$chown rsync.rsync data/ -R3)添加配置文件[root@backup ~]$echo "rsync_backup:oldboy123" >/etc/rsync.password [root@backup ~]$cat /etc/rsync.password rsync_backup:oldboy123 [root@backup ~]$chmod 600 /etc/rsync.password [root@backup ~]$ll /etc/rsync.password4)启动服务C6启动 rsync --daemon C7启动 [root@backup ~]$systemctl start rsyncd [root@backup ~]$systemctl enable rsyncd [root@backup ~]$systemctl status rsyncd [root@backup ~]$netstat -lntup|grep 873 [root@backup ~]$lsof -i :873客户端配置【NFS服务器上配置】第一种方法（推荐吧）[root@nfs01 ~]$echo "oldboy123" > /etc/rsync.password [root@nfs01 ~]$cat /etc/rsync.password oldboy123 [root@nfs01 ~]$chmod 600 /etc/rsync.password [root@nfs01 ~]$ll /etc/rsync.password第二种方法[root@nfs01 ~]$echo 'export RSYNC_PASSWORD=oldboy123' >> /etc/bashrc [root@nfs01 ~]$tail -1 /etc/bashrc export RSYNC_PASSWORD=oldboy123 [root@nfs01 ~]$. /etc/bashrc [root@nfs01 ~]$echo $RSYNC_PASSWORD oldboy123测试拉取实践 [root@nfs01 ~]$rsync -avz rsync_backup@172.16.1.41::backup /data --password-file=/etc/rsync.password [root@nfs01 ~]$rsync -avz rsync://rsync_backup@172.16.1.41/backup /data --password-file=/etc/rsync.password推送实践 [root@nfs01 ~]$rsync -avz /data rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password [root@nfs01 ~]$rsync -avz /data rsync://rsync_backup@172.16.1.41/backup --password-file=/etc/rsync.passwordinotify-tools工具安装过程【NFS服务器上配置】[root@nfs01 ~]# yum install epel-release -y #如已装，请忽略 [root@nfs01 ~]# yum install inotify-tools -y [root@nfs01 ~]# rpm -ql inotify-tools|head -2 /usr/bin/inotifywait /usr/bin/inotifywatch inotifywait命令参数 -m 始终保持事件监听状态***** -d 类似于-m ***** -r 递归监控根目录数据信息变化***** -e 监听的事件实践#测试create事件 inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e create /data #再开一个窗口测试 touch {1..5}.txt #测试delete inotifywait -mrq -e delete /data #多个参数监控 inotifywait -mrq -e delete,create,close_write /data inotifywait -mrq -e delete,close,move /data inotify-tools软件部署项目实战inotifywait -mrq --format '%w%f' -e close_write,delete /data inotifywait -mrq -e close_write,delete /data生产脚本nfs01创建执行执行【建议用sersync的方式】[root@nfs01 scripts]$cat monitor.sh #!/bin/bash cmd="/usr/bin/inotifywait" $cmd -mrq -e close_write,create,delete --format '%w%f' /data | \ while read line do cd /data &&\ rsync -az --delete ./ rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password done #测试 sh -x monitor.sh #bacup服务器检查 ls /backup #放到/etc/rc.local /bin/sh /server/scripts/monitor.sh &>/dev/null & inotify-tools优化#放到/etc/rc.local下 echo "50000000" > /proc/sys/fs/inotify/max_user_watches #单进程可以监控的文件数量 echo "50000000" > /proc/sys/fs/inotify/max_queued_events #队列容纳的事件数量sersync+rsync项目实践在nfs01上安装配置sersyncmkdir /server/tools cd /server/tools/ #wget https://github.com/wsgzao/sersync/blob/master/sersync2.5.4_64bit_binary_stable_final.tar.gz wget https://www.shnne.com/zb_users/upload/2022/11/sersync_oldboy_64bit_20160928.tar.gz [root@nfs01 tools]# tar xf sersync_oldboy_64bit_20160928.tar.gz [root@nfs01 tools]# mv application/sersync /application/启动sersync#帮助 /application/sersync/bin/sersync -h #确定好配置文件里的内容,把backup改为data <sersync> <localpath watch="/data"> <remote ip="172.16.1.41" name="data"/> <remote ip="172.16.1.41" name="oldboy"/> <!--<remote ip="192.168.8.39" name="tongbu"/>--> <!--<remote ip="192.168.8.40" name="tongbu"/>--> </localpath> #启动 [root@nfs01 ~]# /application/sersync/bin/sersync -r -d -o /application/sersync/conf/confxml.xml结束进程[root@nfs01 ~]# pkill sersync配置systemd启动配置：systemctl start sersync启动方案 https://blog.51cto.com/oldboy/2155931 [root@nfs01 /data]# tail -1 /etc/rc.local /application/sersync/bin/sersync -d 配置：systemctl start sersync启动方案 https://blog.51cto.com/oldboy/2155931 [root@nfs01 /data]# cat /etc/rc.d/init.d/sersync #!/bin/bash # chkconfig: 2345 21 81 # description: rsync service start and stop scripts # Author: oldboy # Organization: www.oldboyedu.com start(){ /application/sersync/bin/sersync -d -o /application/sersync/conf/confxml.xml &>/dev/null } stop(){ killall sersync 2>/dev/null } case "$1" in start) start ;; stop) stop ;; restart) stop sleep 2 start ;; *) echo $"Usage:$0 {start|stop|restart}" exit 1 esac chmod +x /etc/rc.d/init.d/sersync [root@nfs01 /data]# cat /usr/lib/systemd/system/sersync.service [Unit] Description=sersyncd service After=network.target [Service] Type=forking ExecStart=/etc/rc.d/init.d/sersync start ExecReload=/etc/rc.d/init.d/sersync restart ExecStop=/etc/rc.d/init.d/sersync stop PrivateTmp=true [Install] WantedBy=multi-user.target chmod +x /usr/lib/systemd/system/sersync.service [root@nfs01 /data]# systemctl enable sersync.service Created symlink from /etc/systemd/system/multi-user.target.wants/sersync.service to /usr/lib/systemd/system/sersync.service. [root@nfs01 /data]# systemctl status sersync.service sersync.service - sersyncd service Loaded: loaded (/usr/lib/systemd/system/sersync.service; enabled; vendor preset: disabled) Active: inactive (dead) [root@nfs01 /data]# systemctl stop sersync [root@nfs01 /data]# ps -ef|grep sersync|grep -v grep [root@nfs01 /data]# systemctl start sersync
nfs01服务器服务端安装 yum -y install nfs-utils rpcbind rpm -qa nfs-utils rpcbind启动RPC systemctl start rpcbind systemctl enable rpcbind 查看注册端口 rpcinfo -p 127.0.0.1 启动nfs systemctl start nfs systemctl enable nfs实践： [root@nfs01 ~]$tail /etc/exports /data 172.16.1.0/24(rw,sync) [root@nfs01 ~]$mkdir -p /data重新加载nfs [root@nfs01 ~]$systemctl reload nfs 或者 [root@nfs01 ~]$exportfs -rv授权 [root@nfs01 ~]$chown -R nfsnobody.nfsnobody /data/ [root@nfs01 ~]$ll -d /data/检查 [root@nfs01 ~]$showmount -e 172.16.1.31 Export list for 172.16.1.31: /data 172.16.1.0/24服务本地挂载（测试） mount -t nfs 172.16.1.31:/data /mntweb01、web02挂载安装 yum -y install nfs-utils rpcbind rpm -qa nfs-utils rpcbind启动RPC即可systemctl start rpcbind systemctl enable rpcbind[root@web01 ~]$showmount -e 172.16.1.31 Export list for 172.16.1.31: /data 172.16.1.0/24挂载mount -t nfs 172.16.1.31:/data /mntNFS客户端开机自启动1.放在/etc/rc.local chmod +x /etc/rc.local echo "/bin/mount -t nfs 172.16.1.31:/data /mnt" >> /etc/rc.local tail -2 /etc/rc.local2.放在/etc/fstab（坑） 加载/etc/fstab >> 加载防火墙 >> 加载网卡 添加以下内容 172.16.1.31:/data /mnt nfs defaults 0 0 延迟启动 systemctl list-unit-files |grep remote-fs.target systemctl enable remote-fs.target reboot 测试好，记得删除，后面部署web网站的时候，重新指定路径挂载3.在/etc/fstab 挂载的时候添加一个_netdev参数 172.16.1.31:/data /mnt nfs defaults,_netdev 0 0 #说明 _netdev The filesystem resides on a device that requires network access (used to prevent the system from attempting to mount these filesystems until the network has been enabled on the system).项目实践2：NFS共享匿名用户用www，使得客户端上传的图片都是www用户，而不是匿名nfsnobodyweb01、web02客户端实现挂载nfsNFS下面共享/data,允许web01、web02客户端对/backup可读写web01上传图片，web02上可以删除web01上传的图片NFS下面贡献/data1，允许web01、web02客户端192.168.238.0/24网段只读（data1）实现开机挂载操作：1，所有主机（web01、web02、nfs01）上创建www用户，指定uid为1111useradd -u 1111 -s /sbin/nologin -M www id www2.NFS01特殊配置[root@nfs01 data]$cat /etc/exports /data 172.16.1.0/24(rw,sync,all_squash,anonuid=1111,anongid=1111) /data1 192.168.238.0/24(ro)3.创建目录并检查[root@nfs01 /]$mkdir -p /data /data1 [root@nfs01 /]$chown -R www.www /data [root@nfs01 /]$ll -d /data drwxr-xr-x 2 www www 166 Nov 8 23:38 /data4，服务端重新加载（平滑重启）[root@nfs01 /]$systemctl reload nfs5.web01、web02配置挂载客户端分别安装：yum -y install rpc-bind nfs-utils systemctl start rpcbind systemctl enable rpcbind检查showmount -e 172.16.1.31 Export list for 172.16.1.31: /data1 192.168.238.0/24 /data 172.16.1.0/24web01、web02客户端分别创建/data 目录mkdir /data 挂载 mount -t nfs 172.16.1.31:/data /data客户端只读/data1配置mkdir /data1 mount -t nfs 192.168.238.31:/data1 /data1NFS客户端开机自启动放在/etc/fstab（坑） 添加以下内容 172.16.1.31:/data /mnt nfs defaults 0 0 延迟启动 systemctl list-unit-files |grep remote-fs.target systemctl enable remote-fs.target reboot查看nfs挂载情况cat /proc/mountsNFS共享权限有两部分控制1.配置文件的rw,ro控制2.本地目录和文件权限NFS强耦合，服务端有问题，NFS客户端容易夯住
集群架构学习整理 - 集群服务器配置（二）
1.IP规划表服务器名称公网IP内网IP主机名L4层负载服务器01192.168.238.15172.16.1.15lb4-01L4层负载服务器02192.168.238.16172.16.1.16lb4-02L7负载服务器01192.168.238.5172.16.1.5lb01L7负载服务器02192.168.238.6172.16.1.6lb02web服务器1（动态）192.168.238.7172.16.1.7web01web服务器2（动态）192.168.238.8172.16.1.8web02web服务器1（静态）192.168.238.9172.16.1.9sweb01web服务器2（静态）192.168.238.10172.16.1.10sweb02NFS存储服务器192.168.238.31172.16.1.31nfs01rsync备份服务器192.168.238.41172.16.1.41backupmysql数据库服务器01192.168.238.51172.16.1.51db01mysql数据库服务器02192.168.238.52172.16.1.52db02管理服务器+监控192.168.238.61172.16.1.61m012.规范目录mkdir -p /server/tools mkdir -p /server/scripts mkdir -p /application mkdir -p /application/nginx mkdir -p /application/nginx/html mkdir -p /application/nginx/logs mkdir -p /application/mysql mkdir -p /backup mkdir -p /datacat >> /etc/hosts<<EOF 172.16.1.5 lb01 172.16.1.6 lb02 172.16.1.7 web01 172.16.1.8 web02 172.16.1.9 sweb01 172.16.1.10 sweb02 172.16.1.31 nfs01 172.16.1.41 backup 172.16.1.51 db01 172.16.1.61 m01 EOF sudo su - hostnamectl set-hostname moban sed -i 's#128#7#g' /etc/sysconfig/network-scripts/ifcfg-eth0 sed -i 's#128#7#g' /etc/sysconfig/network-scripts/ifcfg-eth1 systemctl restart network #可以写个通用脚本，每次新加一台，就用脚本改下，参考 [root@moban ~]# cat net.sh #!/bin/bash echo "./net.sh ip hostname" sed -i "s#128#$1#g" /etc/sysconfig/network-scripts/ifcfg-eth* hostnamectl set-hostname $2 systemctl restart network3.内网卡配置lan区段，虚拟机添加172.16.1.04.做快照
集群架构学习整理 - 基础环境配置优化（一）
Vmware新建一台1核1G的虚拟机，当做镜像模板，装好CentOS7系统，然后再做基础优化1.添加一个普通用户useradd oldboy echo 123456 | passwd --stdin oldboy2.加到sudo管理visudo #100行左右 oldboy ALL=(ALL) NOPASSWD: ALL grep -w oldboy /etc/sudoers提示：如果在系统安装时候添加普通用户，其实是将oldboy添加到到wheel组里了，在/etc/sudoers里的wheel是管理员组。3.禁用root远程登陆，改为oldboy用户登陆企业场景，修改默认端口22为52113，优化远程ssh配置vim /etc/ssh/sshd_config PermitEmptyPasswords no UseDNS no GSSAPIAuthentication no #38行改为 PermitRootLogin no ListenAddress 172.16.1.7:52113 systemctl restart sshd测试ssh root连接root@oldboy ~]$ssh root@192.168.238.128 root@192.168.238.128's password: Permission denied, please try again.以后登陆通过oldboy登陆，通过sudo su -切换root4.更新yum源配置yum源-阿里云mv /etc/yum.repos.d/CentOS-Base.repo{,.backup} wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo curl -s -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo第三方源wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo curl -s -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo5.安装常用软件yum -y update #更新所有软件到最新,可以不装 yum -y install tree nmap dos2unix lrzsz nc lsof wget tcpdump htop iftop iotop sysstat nethogs rsync yum -y install psmisc net-toos bash-completion vim-enhanced yum -y install lrzsz openssh-clients telnet gcc gcc-c++ wget sysstat net-tools nss nss-devel unix2dos dos2unix unzip bc yum -y update bash glibc glibc-devel glibc-common glibc-headers yum -y install ncurses-devel make cmake bison automake autoconf openssl openssl-devel libtirpc libtirpc-devel yum -y install gd gd-devel libjpeg libjpeg-devel libpng libpng-devel zlib zlib-devel freetype freetype-devel libxml2 libxml2-devel curl curl-devel libxslt libxslt-devel pcre pcre-devel libtool6.安全优化a.关闭selinuxsed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config grep 'SELINUX=disabled' /etc/selinux/config setenforce 0 getenforceb.暂时关闭防火墙systemctl stop firewalld systemctl disable firewalld systemctl status firewalld|grep inactive8.手工添加管理员帐帐号（可选）useradd oldgirl -G wheel id oldgirl echo 111111|passwd --stdinoldgirl9.设置字符集（可选）方法1cp /etc/locale.conf{,.ori} echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf source /etc/locale.conf echo $LANG方法2cp /etc/locale.conf{,.ori} localectl set-locale LANG="zh_CN.UTF-8" cat /etc/locale.conf9.时间同步yum -y install ntpdate /sbin/ntpdate ntp3.aliyun.com echo "*/5 * * * * /sbin/ntpdate ntp3.aliyun.com &>/dev/null" >> /var/spool/cron/root crontab -l10.基础优化操作项：提升命令安全（可选）echo 'export TMOUT=300' >> /etc/profile echo 'export HISTSIZE=5' >> /etc/profile echo 'export HISTFILESIZE=5' >> /etc/profile tail -3 /etc/profile . /etc/profile11.加大文件描述符echo '* - nofile 65535' >> /etc/security/limits.conf tail -1 /etc/security/limits.conf ulimit -SHn 65535 ulimit -n12.基础优化操作，优化系统内核cat >>/etc/sysctl.conf<<EOF #BASE net.ipv4.tcp_fin_timeout = 2 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 #建议设置为0，因为涉及到NAT的网络访问问题 net.ipv4.tcp_syncookies= 1 net.ipv4.tcp_keepalive_time = 600 net.ipv4.ip_local_port_range = 4000 65000 net.ipv4.tcp_max_syn_backlog = 16384 net.ipv4.tcp_max_tw_buckets = 36000 net.ipv4.route.gc_timeout = 100 net.ipv4.tcp_syn_retries = 1 net.ipv4.tcp_synack_retries = 1 net.core.somaxconn = 16384 net.core.netdev_max_backlog = 16384 net.ipv4.tcp_max_orphans = 16384 #以下是ip防火墙,防火墙不开，可以忽略 net.nf_conntrack_max = 25000000 net.netfilter.nf_conntrack_tcp_timeout_established = 180 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60 net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120 #NFS共享优化 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.wmem_max = 16777216 net.core.rmem_max = 16777216 EOF sysctl -p13.修改yum配置文件/etc/yum.conf 里的keepcache=0改为keepcache=1 sed -i.bak 's#keepcache=0#keepcache=1#g' /etc/yum.conf grep 'keepcache=1' /etc/yum.conf14.锁定关键文件chattr +i /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/inittab lsattr /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/inittab15.清空/etc/issue /etc/issue.net[root@oldboy ~]$ > /etc/issue && > /etc/issue.net16.清理虚拟帐号（可选）17.grup菜单加密（可选）grub2-setpassword18.禁止ping（内核参数）#/etc/sysctl.conf添加禁ping参数 net.ipv4.icmp_echo_ignore_all = 119.精简开机自启动保留sshd|crond|sysstat|rsyslog|NetworkManager|irqbalance