#!/bin/bash
# BLOG : //renwole.com
now_time=$(date -u -d"+8 hour" +'%Y-%m-%d %H:%M:%S')
# 获取域名
hostnamelist=$(hostname)
# 当cpu使用率大于设置的阀值触发报警
cpu_warn="60"
# 当内存仅剩余2048MB时触发报警
mem_warn="2048"
# 当磁盘使用率大于设置的阀值触发报警
disk_warn="80"
# 每执行一次都会在机器上生成对应的日志
renwole_check_log="/tmp/renwole_check_mem_cpu_disk.log"
# 钉钉报警Token
dingtalk_openapi="//oapi.dingtalk.com"
dingtalk_openapi_token="Token"
# 获取CPU使用率
item_cpu () {
cpu_idle=$(top -b -n 1 | grep Cpu | awk '{print $2}' | cut -f 1 -d ".")
echo "$now 当前cpu使用率为 $cpu_idle" >> $renwole_check_log
if [[ "$cpu_idle" -gt "$cpu_warn" ]]; then
curl ''$dingtalk_openapi'/robot/send?access_token='$dingtalk_openapi_token'' \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text",
"text": {
"content": "警告:当前机器'$hostnamelist'CPU使用率达到60%,请知晓."
}
}'
else
echo "CPU健康状态正常"
fi
}
# 获取内存消耗情况
item_mem () {
mem_free=$(free -m | grep "Mem" | awk '{print $4+$6}')
echo "$now 当前内存剩余空间为 ${mem_free}MB" >> $renwole_check_log
if [[ "$mem_free" -lt "$mem_warn" ]]; then
curl ''$dingtalk_openapi'/robot/send?access_token='$dingtalk_openapi_token'' \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text",
"text": {
"content": "警告:当前机器'$hostnamelist'内存使用率不足2048MB,请知晓."
}
}'
else
echo "内存使用率正常,放心使用"
fi
}
# 获取磁盘使用情况
item_disk () {
disk_use=$(df -P | grep /dev/sdb1 | grep -v -E '(tmp|boot)' | awk '{print $5}' | cut -f 1 -d "%")
echo "$now 当前磁盘使用率为 $disk_use" >> $renwole_check_log
if [[ "$disk_use" -gt "$disk_warn" ]]; then
curl ''$dingtalk_openapi'/robot/send?access_token='$dingtalk_openapi_token'' \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text",
"text": {
"content": "警告:当前机器'$hostnamelist'磁盘使用率达到80%,请知晓."
}
}'
else
echo "硬盘使用率未超过80%,放心使用"
fi
}
item_cpu
item_mem
item_disk
Author Archives: Node
Zabbix Agent Remotely Install Shell(batch & Single)
批量安装:
#!/bin/sh
Server=10.16.8.8
ServerActive=10.16.8.8:10050
ip_array=("hostnamerenwole1" "hostnamerenwole2")
for ip in ${ip_array[*]}
do
zabbix=$(ssh $ip 'find /etc -name zabbix_agentd.conf')
if [ -f $zabbix ];then
ssh $ip 'rpm -ivh //repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm ; yum -y install zabbix-agent'
else
echo "Already exist, no need to install"
fi
ssh $ip '
sed -i "s#Server=.*#Server='$Server'#" /etc/zabbix/zabbix_agentd.conf
sed -i "s#ServerActive=.*#ServerActive='$ServerActive'#" /etc/zabbix/zabbix_agentd.conf
sed -i "s#Hostname=.*#Hostname='$ip'#" /etc/zabbix/zabbix_agentd.conf
sed -i "s/# UserParameter=/UserParameter=/g" /etc/zabbix/zabbix_agentd.conf
sed -i "s#UserParameter=.*#UserParameter=pro.check,sh /renwole/Apps/check.sh|wc -c#" /etc/zabbix/zabbix_agentd.conf
chmod -R 777 /etc/zabbix/zabbix_agentd.conf
systemctl restart zabbix-agent
'
done
交互式安装:
#cat /renwole/bin/Zabbix_Agent_Single.sh #!/bin/sh read -p "Please enter the HostName:" HostName Server=10.16.8.8 ServerActive=10.16.8.8:10050 zabbix=$(ssh $HostName 'find /etc -name zabbix_agentd.conf') if [ -f $zabbix ];then ssh $HostName 'rpm -ivh //repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm ; yum -y install zabbix-agent' else echo "Already exist, no need to install" fi ssh $HostName ' sed -i "s#Server=.*#Server='$Server'#" /etc/zabbix/zabbix_agentd.conf sed -i "s#ServerActive=.*#ServerActive='$ServerActive'#" /etc/zabbix/zabbix_agentd.conf sed -i "s#Hostname=.*#Hostname='$HostName'#" /etc/zabbix/zabbix_agentd.conf sed -i "s/# UserParameter=/UserParameter=/g" /etc/zabbix/zabbix_agentd.conf sed -i "s#UserParameter=.*#UserParameter=pro.check,sh /renwole/Apps/check.sh|wc -c#" /etc/zabbix/zabbix_agentd.conf systemctl restart zabbix-agent '
PHP 7.3 configure: error: Please reinstall the libzip distribution
问题解决:
$ yum remove -y libzip
$ wget -P /mnt/renwolecom //nih.at/libzip/libzip-1.2.0.tar.gz
$ tar -zxvf libzip-1.2.0.tar.gz
$ cd libzip-1.2.0
$ ./configure
$ make && make install
Q:问题描述:configure: error: off_t undefined; check your library configuration
问题解决:
$ echo '/usr/local/lib64
/usr/local/lib
/usr/lib
/usr/lib64'>>/etc/ld.so.conf
$ ldconfig -v
Q:问题描述:/usr/local/include/zip.h:59:21: fatal error: zipconf.h: No such file or dire
问题解决:
$ cp /usr/local/lib/libzip/include/zipconf.h /usr/local/include/zipconf.h
Shell脚本变量判断参数命令学习篇
最近在深度学习shell脚本,先温习下最基础的,若长时间不碰,可能会忘记些许参数,所以这里笔记下来,以备后续翻阅。
1.系统变量
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2 $? 上个命令的退出状态,或函数的返回值。成功返回0,失败返回1 $# 传递给脚本或函数的参数个数 $* 所有这些参数都被双引号引住。若一个脚本接收两个参数,$*等于$1$2 $0 正在被执行命令的名字。对于shell脚本而言,这是被激活命令的路径 $@ 被双引号(” “)包含时,与 $* 稍有不同。若一个脚本接收到两个参数,$@等价于$1$2 $$ 当前shell的进程号。对于shell脚本,这是其正在执行时的进程ID $! 前一个后台命令的进程号
2.文件或目录判断
-b file 若文件存在且是一个块特殊文件,则为真 -c file 若文件存在且是一个字符特殊文件,则为真 -d file 若文件存在且是一个目录,则为真 -e file 若文件存在,则为真 -f file 若文件存在且是一个规则文件,则为真 -g file 若文件存在且设置了SGID位的值,则为真 -h file 若文件是软链接,则为真 -k file 若文件存在且设置了”sticky”位的值 -L file 若文件为符号链接,则为真 -p file 若文件存在且为一已命名管道,则为真 -r file 若文件可读,则为真 -s file 判断文件是否存在,且是否为非空,不为空,则为真 -S file 判断文件是否存在,且是否为套接字文件 -t file 文件描述符(默认为1)指定的设备为终端时为真 -u file 若文件存在且设置了SUID位,则为真 -w file 若文件可写,则为真 -x file 若文件可执行,则为真 [ file1 -nt file2 ] 若file1比file2新,或file1存在但file2不存在,则为真 [ file1 -ot file2 ] 若file1比file2老,或file2存在但file1不存在,则为真 [ file1 -ef file2 ] 若file1和file2指向相同的设备和节点号则返回,为真
3.整数判断
-eq 两数相等,则为真 例:if [ "$a" -eq "$b" ]
-ne 两数不相等,则为真 例:if [ "$a" -ne "$b" ]
-gt a大于b,则为真 例:if [ "$a" -gt "$b" ]
-ge 大于或等于,则为真 例:if [ "$a" -ge "$b" ]
-lt a小于b,则为真 例:if [ "$a" -lt "$b" ]
-le a小于或等于b,则为真 例:if [ "$a" -le "$b" ]
< 小于(需双括号) 例:(("$a" < "$b"))
<= 小于等于(需双括号) 例:(("$a" <= "$b"))
> 大于(需双括号) 例:(("$a" > "$b"))
>= 大于等于(需双括号) 例:(("$a" >= "$b"))
小数据比较可使用AWK。
4.逻辑运算判断符
! [ ! false ] 返回true 逻辑否,条件为假,结果为真 -a [ $a -lt 2 -a $b -gt 5 ] 返回true 逻辑与,两个表达式都为真,则为真 -o [ $a -lt 2 -o $b -gt 5 ] 返回true 逻辑或,只要有一个表达式为true,则为真 [ ] || [ ] 用OR来合并两个条件 [ ] && [ ] 用AND来合并两个条件
5.字符串判断
== 若两个字符串相同则为真,与=等价 例:[ "str1" = "str2" ] != 若字符串不相同则为真 例:[ "str1" != "str2" ] < 若str1字典排序在str2前则为真 例:[[ "str1" < "str2" ]] > 若str1字典排序在str2后则为真 例:[ "str1" \> "str2" ] -n 若str长度非零则为真,即非空 例:[ -n "str1" ] -z 若file长度为零,即空,则为真 例:[ -z "str1" ]
注意:在[]结构中”<“需要被转义,例如:[ "str1" /< "str2" ],在双中括号中则无需转义。
总结:
使用-n在[]结构中测试,必须要用""把变量引起来,使用一个未被""的字符串,请使用 ! -z ,如果使用未被双引号变量,虽然可以工作,但这并不安全,习惯于使用双引号括住变量测试字符串是一种良好的习惯。
另外,[[ ]] 结构比[ ]结构更加通用。
Centos 7利用内存优化磁盘缓存读写速度
Linux中的/dev/shm目录不属于磁盘,而是内存,如果使用/dev/shm/目录作为Linux中的磁盘文件读写缓存,可想效率是非常惊人的。
默认/dev/shm目录没有挂载,需要手动进行挂载。
在以下文件尾端添加以下内容:
$ vim /etc/fstab
tmps /dev/shm tmpfs defaults,size=1G 0 0
请根据自己的物理内存大小添加,一般是物理内存的10-50%左右。
挂载/dev/shm/目录:
$ mount -o remount /dev/shm/ $ mkdir /dev/shm/tmp $ chmod 755 /dev/shm/tmp $ mount -B /dev/shm/tmp /tmp
注意:
/dev/shm/tmp在系统重启后会丢失挂载,需要重新设置挂载,下面有个shell脚本,你加入开机自启即可:
$ vim /etc/init.d/shmtmp.sh
#!/bin/bash mkdir /dev/shm/tmp chmod 755 /dev/shm/tmp mount -B /dev/shm/tmp/ /tmp
之后再以下文件末尾添加如下内容:
$ vim /etc/rc.local
sh /etc/init.d/shmtmp.sh
这样就实现了重启自动挂载。你就可以利用内存提高读写性能,例如:将php的session,以及其他的缓存放在/tmp目录下,速度效率成倍提升。
Let’s Encrypt SSL证书续期失败 ascii编解码器不能编码
今天复查服务器SSL证书,发现Let’s Encrypt证书就快要到期了,查看crontab定时任务计划日志,也是正常执行的。例如:
$ cat /var/log/cron
...
CROND[31471]: (root) CMD (/usr/bin/certbot renew --quiet && /bin/systemctl restart nginx)
CROND[31470]: (root) MAIL (mailed 375 bytes of output but got status 0x004b#012)
CROND[31482]: (root) CMD (run-parts /etc/cron.hourly)
...
奇怪的是,证书并没有正常续期,什么个原因呢,后来手动执行证书更新:
$ /usr/bin/certbot renew --quiet
Attempting to renew cert from /etc/letsencrypt/renewal/renwole.com.conf produced an unexpected error: 'ascii' codec can't encode characters in position 247-248: ordinal not in range(128). Skipping.
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/renwole.com.conf/fullchain.pem (failure)
1 renew failure(s), 0 parse failure(s)
更新失败,提示“ascii”编解码器不能编码字符。
经过分析研究发现,开发人员修改了网站根目录,导致LetsEncrypt找不到相关配置文件。
PS:唉,出了问题,都是运维的锅哈。
解决方案
修改以下配置文件中的网站根目录:
$ vim /etc/letsencrypt/renewal/renwole.com.conf
...
# Options used in the renewal process
[renewalparams]
authenticator = webroot
installer = None
account = a07a7160ea489g586aeaada1368ce0d6
[[webroot_map]]
renwole.com = /apps/data/www/renwolecom
...
修改蓝色部分为Nginx指定的根目录,其他默认,然后保存即可。
再次更新证书成功。
使用以下命令查看续期状态:
$ certbot certificates
运行环境正常 织梦DedeCMS验证码无法显示
在环境一切OK的情况下,DedeCMS的验证码无法显示。
解决方案一:
在include目录下打开vdimgck.php文件,查找 if(function_exists(“imagejpeg”)) 在上方添加 ob_clean(); 问题解决。
这个问题很奇怪,有时候不加也没问题,当然我的是运行有问题了加上就没事,之前没事,突然就不行了。
添加过后的具体代码如下:
ob_clean();
if(function_exists(“imagejpeg”))
{
header(“content-type:image/jpeg\r\n”);
imagejpeg($im);
}
else
{
header(“content-type:image/png\r\n”);
imagepng($im);
}
解决方案二:
将织梦后台登录验证码取消。
具体操作如下:
找到以下文件:
/data/safe/inc_safe_config.php
在该文件中查找 $safe_gdopen = ’1,2,3,5,6,7′; 删除6数字即可取消验证码功能。
Centos 7如何备份和还原Redis数据
何为Redis?
Redis是内存中的键值缓存和存储(即数据库),也可以永久保存到磁盘。在本文中,你将了解,如何在Centos 7上备份还原您的redis数据库。
备份还原说明
默认情况下,Redis数据将保存到磁盘中的.rdb文件中,该文件是Redis数据集的时间点快照。快照是按照指定的时间间隔进行的,所以对于备份来说是完美的。
1.数据备份篇
在Centos 7和其他Linux发行版中,Redis数据库目录默认是/var/lib/redis。但是,如果您更改了redis存储位置,则可以通过键入以下命令查找:
[root@renwolecom ~]# find / -name *rdb
使用redis-cli管理工具进入数据库:
[root@renwolecom ~]# redis-cli
由于大部分数据都运行在内存中,redis只会每隔一段时间保存一次,为获取最新副本,请执行以下命令:
10.10.204.64:6379> save OK (1.02s)
另外,如果Redis设置了用户认证,就需要先验证,再保存,例如:
10.10.204.64:6379> auth RenwoleQxl5qpKHrh9khuTW 10.10.204.64:6379> save
之后进行备份即可,例如:
[root@renwolecom ~]# cp /var/lib/redis/dump.rdb /apps/redis-backup-20180129
2.数据还原篇
恢复备份需要您使用恢复文件替换现有的Redis数据库文件。为保证原始数据文件不被破坏,我们建议尽可能恢复到新的Redis服务器。
停止Redis数据库,一旦停止,Redis数据库处于脱机状态。
[root@renwolecom ~]# systemctl stop redis
如果恢复到原始Redis服务器,请重命名当前数据文件,之后再进行恢复:
[root@renwolecom ~]# mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.old [root@renwolecom ~]# cp -p /apps/redis-backup-20180129/dump.rdb /var/lib/redis/dump.rdb
设置dump.rdb文件权限,拷贝过来的数据文件,可能不具备Redis用户及读取权限,需要手动赋予:
[root@renwolecom ~]# chown redis:redis /var/lib/redis/dump.rdb [root@renwolecom ~]# chmod 660 /var/lib/redis/dump.rdb
启动redis
[root@renwolecom ~]# systemctl start redis
大功告成!现在你可以登录redis核实数据了。
注意说明:
根据需求,关闭AOF,AOF跟踪每个写操作到Redis数据库。由于我们试图从时间点备份中恢复,所以我们不希望Redis重新创建存储在其AOF文件中的操作。
是否开启AOF可以通过查看文件获悉:
[root@renwolecom ~]# ls /var/lib/redis/
如果看到.aof后缀的文件,说明你启用了AOF。
重命名.aof文件,
[root@renwolecom ~]# mv /var/lib/redis/*.aof /var/lib/redis/appendonly.aof.old
如果有多个.aof文件,请单独命名。
编辑你的Redis配置文件暂时关闭AOF:
[root@renwolecom ~]# vim /etc/redis/redis.conf appendonly no
如果备份期间有任何疑问,欢迎留言。
Centos 7添加删除Swap交换分区
Swap介绍:
Linux 将物理内存分为内存段,叫做页面。交换是指内存页面被复制到预先设定好的硬盘空间(叫做交换空间)的过程,目的是释放对于页面的内存。物理内存和交换空间的总大小是可用的虚拟内存的总量。
Swap即:交换分区,类似于Windows的虚拟内存,但物理内存不足时,把部分硬盘空间当成虚拟内存使用,从而解决了物理内存容量不足。
优点:节省成本。
缺点:性能不足。
此方法不局限于Centos 7,Linux系统均可使用。
操作用户:root。
1.添加swap交换分区空间
使用dd命令创建swap交换分区文件/dev/mapper/centos-swap,大小为2G:
$ dd if=/dev/zero of=/dev/mapper/centos-swap bs=1024 count=2048000
格式化swap分区:
$ mkswap /dev/mapper/centos-swap
设置交换分区:
$ mkswap -f /dev/mapper/centos-swap
激活swap分区:
$ swapon /dev/mapper/centos-swap
设为开机自动启用:
$ vim /etc/fstab
在该文件底部添加如下内容:
/dev/mapper/centos-swap swap swap default 0 0
2.删除swap交换分区
停止正在使用的swap分区:
$ swapoff /dev/mapper/centos-swap
删除swap分区文件:
$ rm /dev/mapper/centos-swap
删除或注释在/etc/fstab文件中的以下开机自动挂载内容:
/dev/mapper/centos-swap swap swap default 0 0
大功告成!
Keepalived Nginx双网络(内外网)故障非同步漂移双活双主模式(实战)
介绍:
有了keepalived+Lvs这样的高性能组合,为什么还需keepalived+Nginx呢。keepalived是为了Lvs而设计。Lvs是一个四层的负载均衡设备,虽然有着高性能的优势,但它无后端服务器的健康检查机制。keepalived为lvs提供一系列的健康检查机制,例如:TCP_CHECK,UDP_CHECK,HTTP_GET等。同时lvs也可以自己写健康检查脚脚本。或者结合ldirectory来实现后端健康检测。但LVS始终无法摆脱它是一个四层设备,无法对上层协议进行解析。而Nginx就不一样了,Nginx是一个七层的设备可以对七层协议进行解析,可以对一些请求进行过滤,还可以对请求结果进行缓存。这些都是Nginx独有的优势。但是keepalived并没有为Nginx提供健康检测。需要自己去写一些脚步来进行健康检测。
下面主要讲解Keepalived+Nginx的模式,不包含lvs。如果不是大型负载,一般用不到LVS,当然你也可以参阅:《Keepalived LVS-DR Nginx单网络双活双主配置模式(实战)》篇。
准备四台服务器或虚拟机:
Web Nginx 内网:10.16.8.8/10.16.8.9
Keepalived 内网:10.16.8.10(ka67)/10.16.8.11(ka68)
Keepalived 公网:172.16.8.10/172.16.8.11Keepalived 内网VIP:10.16.8.100/10.16.8.101
Keepalived 公网VIP:172.16.8.100/172.16.8.101OS:CentOS Linux release 7.4.1708 (Core)
先决条件:
安装keepalived。
时间同步。
设置SELinux和防火墙。
互相之间/etc/hosts文件添加对方主机名(可选)。
确认网络接口支持多播(组播)新网卡默认支持。
以上部署请参阅:《keepalived 安装及配置文件讲解》。
1.ka67配置文件
global_defs {
notification_email {
root@localhost
}
notification_email_from ka@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
vrrp_mcast_group4 224.0.0.111
}
vrrp_instance External_1 {
state MASTER
interface eth1
virtual_router_id 171
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass renwole0
}
virtual_ipaddress {
10.16.8.100
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_fault "/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
vrrp_instance External_2 {
state BACKUP
interface eth1
virtual_router_id 172
priority 95
advert_int 1
authentication {
auth_type PASS
auth_pass renwole1
}
virtual_ipaddress {
10.16.8.101
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_fault "/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
vrrp_instance Internal_1 {
state MASTER
interface eth0
virtual_router_id 191
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass renwole2
}
virtual_ipaddress {
172.16.8.100
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_fault "/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
vrrp_instance Internal_2 {
state BACKUP
interface eth0
virtual_router_id 192
priority 95
advert_int 1
authentication {
auth_type PASS
auth_pass renwole3
}
virtual_ipaddress {
172.16.8.101
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_fault "/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
2.ka68配置文件
global_defs {
notification_email {
root@localhost
}
notification_email_from ka@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
vrrp_mcast_group4 224.0.0.111
}
vrrp_instance External_1 {
state BACKUP
interface eth1
virtual_router_id 171
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass renwole0
}
virtual_ipaddress {
10.16.8.100
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_fault "/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
vrrp_instance External_2 {
state MASTER
interface eth1
virtual_router_id 172
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass renwole1
}
virtual_ipaddress {
10.16.8.101
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_fault "/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
vrrp_instance Internal_1 {
state BACKUP
interface eth0
virtual_router_id 191
priority 95
advert_int 1
authentication {
auth_type PASS
auth_pass renwole2
}
virtual_ipaddress {
172.16.8.100
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_fault "/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
vrrp_instance Internal_2 {
state MASTER
interface eth0
virtual_router_id 192
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass renwole3
}
virtual_ipaddress {
172.16.8.101
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_fault "/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
3.创建检测通用脚本
$ vim /usr/local/keepalived/etc/keepalived/notify.sh
#!/bin/bash
#
contact='root@localhost'
notify() {
local mailsubject="$(hostname) to be $1, vip floating"
local mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
;;
backup)
notify backup
systemctl start nginx # 此处配置后,Nginx服务挂了能自动启动
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
4.启动keepalived服务并测试
启动ka67后查看其网卡状态:
[root@ka67 ~]# systemctl start keepalived
[root@ka67 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:15:5d:ae:02:78 brd ff:ff:ff:ff:ff:ff
inet 172.16.8.10/24 brd 172.16.8.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.16.8.100/32 scope global eth0
valid_lft forever preferred_lft forever
inet 172.16.8.101/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::436e:b837:43b:797c/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:15:5d:ae:02:84 brd ff:ff:ff:ff:ff:ff
inet 10.16.8.10/24 brd 10.16.8.255 scope global eth1
valid_lft forever preferred_lft forever
inet 10.16.8.100/32 scope global eth1
valid_lft forever preferred_lft forever
inet 10.16.8.101/32 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::1261:7633:b595:7719/64 scope link
valid_lft forever preferred_lft forever
在ka68没有启动时,ka67添加了4个VIP,分别是:
公网eth0:
172.16.8.100/32
172.16.8.101/32
内网eth1:
10.16.8.100/32
10.16.8.101/32
启动ka68后查看其网卡状态:
[root@ka68 ~]# systemctl start keepalived
[root@ka68 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:15:5d:ae:02:79 brd ff:ff:ff:ff:ff:ff
inet 172.16.8.11/24 brd 103.28.204.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.16.8.101/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::3d2c:ecdc:5e6d:70ba/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:15:5d:ae:02:82 brd ff:ff:ff:ff:ff:ff
inet 10.16.8.11/24 brd 10.16.8.255 scope global eth1
valid_lft forever preferred_lft forever
inet 10.16.8.101/32 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::4fb3:d0a8:f08c:4536/64 scope link
valid_lft forever preferred_lft forever
ka68添加了2个VIP,分别是:
公网eth0:
172.16.8.101/32
内网eth1:
10.16.8.101/32
再次查看ka67的网卡状态信息:
[root@ka67 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:15:5d:ae:02:78 brd ff:ff:ff:ff:ff:ff
inet 172.16.8.10/24 brd 172.16.8.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.16.8.100/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::436e:b837:43b:797c/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:15:5d:ae:02:84 brd ff:ff:ff:ff:ff:ff
inet 10.16.8.10/24 brd 10.16.8.255 scope global eth1
valid_lft forever preferred_lft forever
inet 10.16.8.100/32 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::1261:7633:b595:7719/64 scope link
valid_lft forever preferred_lft forever
注意到 172.16.8.101/10.16.8.101 已经被移除了,此时无论停掉任意一台服务器,4个VIP都不会停止通信。
另外可以在ka67/ka68通过如下命令查看组播地址的心跳状态:
[root@ka67 ~]# tcpdump -nn -i eth1 host 224.0.0.111
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes 02:00:15.690389 IP 10.16.8.10 > 224.0.0.111: VRRPv2, Advertisement, vrid 171, prio 100, authtype simple, intvl 1s, length 20 02:00:15.692654 IP 10.16.8.11 > 224.0.0.111: VRRPv2, Advertisement, vrid 172, prio 100, authtype simple, intvl 1s, length 20 02:00:16.691552 IP 10.16.8.10 > 224.0.0.111: VRRPv2, Advertisement, vrid 171, prio 100, authtype simple, intvl 1s, length 20 02:00:16.693814 IP 10.16.8.11 > 224.0.0.111: VRRPv2, Advertisement, vrid 172, prio 100, authtype simple, intvl 1s, length 20 02:00:17.692710 IP 10.16.8.10 > 224.0.0.111: VRRPv2, Advertisement, vrid 171, prio 100, authtype simple, intvl 1s, length 20
到目前为止,vrrp的高可用配置&测试已完成,接下来我们继续配置Web Nginx服务。
5.安装并配置Nginx
分别在后端服务器 10.16.8.8/10.16.8.9 安装Nginx:
关于Nginx请参阅:《Centos 7源码编译安装 Nginx》。
或通过以下方式yum安装Nginx;简单快速:
$ yum install epel-release -y $ yum install nginx -y
测试环境为区分机器的不同,故将web页面设置服务器IP地址,但在生产环境中获取的内容是一致的。
分别在10.16.8.8/10.16.8.9执行如下命令:
$ echo "Server 10.16.8.8" > /usr/share/nginx/html/index.html $ echo "Server 10.16.8.9" > /usr/share/nginx/html/index.html
测试是否访问正常:
$ curl //10.16.8.8 Server 10.16.8.8
分别在ka67/ka68上安装Nginx,我这里用yum安装:
$ yum install nginx psmisc -y
说明:psmisc包含了:fuser,killall,pstree等命令。
在ka67/ka68上配置Nginx:
备份默认配置文件:
$ mv /etc/nginx/conf.d/default.conf{,.bak}
$ mv /etc/nginx/nginx.conf{,.bak}
分别在ka67/ka68将nginx主配置文件中添加如下内容:
$ vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
upstream webserverapps {
server 10.16.8.8:80;
server 10.16.8.9:80;
#server 127.0.0.1:8080 backup;
}
server {
listen 80;
server_name _;
location / {
proxy_pass //webserverapps;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
add_header Access-Control-Allow-Origin *;
}
}
}
注意:以上配置主要添加了蓝色部分,其他默认,仅为测试使用。生产环境请根据自己需求调整配置。
在ka67/ka68重启Nginx服务:
$ systemctl restart nginx
分别在ka67/ka68上测试:
[root@ka67 ~]# for i in `seq 10`; do curl 10.16.8.10; done Server 10.16.8.8 Server 10.16.8.9 Server 10.16.8.8 Server 10.16.8.9 Server 10.16.8.8 Server 10.16.8.9 Server 10.16.8.8 Server 10.16.8.9 Server 10.16.8.9 Server 10.16.8.9
到目前为止,Nginx反代功能也已实现,下面我们将把Nginx与Keepalived结合起来,使Nginx支持高可用。
6.配置Keepalived Nginx高可用
分别在ka67/ka68配置文件/usr/local/keepalived/etc/keepalived/keepalived.conf的全局配置块global_defs下方添加vrrp_script配置块:
vrrp_script chk_nginx {
script "killall -0 nginx"
interval 2
weight -10
fall 2
rise 2
}
在所有vrrp_instance实例块里,添加track_script块:
track_script {
chk_nginx
}
例如:
...
vrrp_instance External_1 {
state BACKUP
interface eth1
virtual_router_id 171
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass renwole0
}
virtual_ipaddress {
10.16.8.100
}
track_script {
chk_nginx
}
notify_master "/usr/local/keepalived/etc/keepalived/notify.sh master"
notify_backup "/usr/local/keepalived/etc/keepalived/notify.sh backup"
notify_"/usr/local/keepalived/etc/keepalived/notify.sh fault"
}
...
配置完以后,重启ka67/ka68的keepalived服务:
$ systemctl stop keepalived $ systemctl start keepalived
总结:
在配置过程中出现了无法漂移的情况,跨网段问题。解决通道,还是要多看日志,多分析判断,最终还是能解决问题的。无论在何种情况下,既然选择了keepalived,就要坚信自己的初心。
如你在配置过程中出现任何问题,欢迎留言,共同解决问题。