系统版本是centos7.4的
[root@data-1-1 ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@data-1-1 ~]# uname -r
3.10.0-693.el7.x86_64
[root@data-1-1 ~]# ip ad|grep eth0 |grep -v mtu
inet 10.0.1.61/24 brd 10.0.1.255 scope global eth0
[root@data-1-1 ~]#
这次试用的haproxy版本是稳定版中的1.6.14
之所以选择这个haproxy版本
现在时间是2018年4月8日
1.6.14的稳定版版本到现在有3个月时间没更新新版本了。说明没太多bug
系统优化部分
1、修改文件描述符
默认文件描述符大小是1024
[root@data-1-1 ~]# ulimit -n
1024
[root@data-1-1 ~]#
这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听socket,进程间通讯的unix域socket等文件,那麽剩下的可用于客户端socket连接的文件数就只有大概1024-10=1014个左右。也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014个TCP并发连接,显然不符合我们的要求,改成2到3万左右,超过65535其实对于haproxy也没太多作用了,因为一个端口至少占一个文件描述符,系统总的端口是65535.
临时性一起修改硬件文件描述符和软件描述符命令如下,直接在命令行执行,立马生效
-H表示硬件资源限制
-S表示软件资源限制,它的个数不能超过硬件资源限制
-n表示个数
ulimit -SHn 32768
另外网上看到一些人一起修改了进程数限制。下面的nproc参数就是。
cat >> /etc/security/limits.conf <<EOF
# End of file
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
EOF
这里我没修改进程数限制,因为使用ulimit命令可以看到系统默认也1万多了,比较大了
其中max user processes就是表示用户的最大进程数,我的这个值很大,进程数也没有超过它。如果超过的话,可以修改最大进程数的配置
[root@data-1-1 ~]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15728
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 102400
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15728
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@data-1-1 ~]#
nproc是操作系统级别对每个用户创建的进程数的限制,在Linux下运行多线程时,每个线程的实现其实是一个轻量级的进程,对应的术语是:light weight process(LWP)。怎么知道一个用户创建了多少个进程呢,默认的ps是不显示全部进程的,需要‘-L' 才能看到所有的进程。
查看所有用户创建的进程数,使用命令:
ps h -Led -o user | sort | uniq -c | sort -n
[root@data-1-1 ~]# ps h -Led -o user | sort | uniq -c | sort -n
1 dbus
1 haproxy
6 polkitd
140 root
[root@data-1-1 ~]#
永久性修改系统文件描述符大小
cat >> /etc/security/limits.conf << EOF
* soft nofile 32768
* hard nofile 65535
EOF
2、修改系统内核参数
修改系统内核参数,下面参数追加到文件末尾,会覆盖前面相同的参数。
cat >> /etc/sysctl.conf << EOF
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_nonlocal_bind=1
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_forward=1
net.ipv4.icmp_echo_ignore_broadcasts = 1
EOF
/sbin/sysctl -p
上面参数的含义
##关闭ipv6,完全用不到ipv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1 ##避免放大攻击
net.ipv4.icmp_echo_ignore_broadcasts = 1 ##开启SYN洪水攻击保护
net.ipv4.tcp_syncookies = 1 ##允许系统打开的端口范围,因为haproxy要连后端web服务器,每次都是1个随机端口,每个用户请求都占用一个端口
net.ipv4.ip_local_port_range = 10240 65535 ##改tcp的tw端口的复用,启用reuse,新的请求可以使用haproxy连接后端的未释放的空闲链接。避免每次回收和开启新端口开销
##注意不要启用tcp_tw_recycle,它是端口的快速回收。和这个冲突
net.ipv4.tcp_tw_reuse = 1 ##打开ip_forward内核的转发功能(我测试没开启也能成功访问后端web服务器,这里开启吧,没影响)
net.ipv4.ip_forward=1 ##配置linux进程可以绑定非本地IP,后面配置Keepalived双机高可用方案的时候会用到,技术部配置高可用也不影响系统
net.ipv4.ip_nonlocal_bind=1
下面是临时修改一些参数方式。临时生效,重启后参数会失效
[root@data-1-1 ~]# echo "10240 65534" >/proc/sys/net/ipv4/ip_local_port_range
[root@data-1-1 ~]# cat /proc/sys/net/ipv4/ip_local_port_range
10240 65534
[root@data-1-1 ~]# [root@data-1-1 ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse
0
[root@data-1-1 ~]# echo "1">/proc/sys/net/ipv4/tcp_tw_reuse
[root@data-1-1 ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse
1
[root@data-1-1 ~]# ##打开ip_forward功能打开内核的转发功能
[root@data-1-1 ~]# cat /proc/sys/net/ipv4/ip_forward
0
[root@data-1-1 ~]# echo "1">/proc/sys/net/ipv4/ip_forward
[root@data-1-1 ~]# cat /proc/sys/net/ipv4/ip_forward
1
[root@data-1-1 ~]#
安装haproxy部分
安装过程如下
mkdir /tools -p
mkdir /application -p
cd /tools/
wget http://10.0.2.15:8298/soft/haproxy-1.6.14.tar.gz
tar xfz haproxy-1.6.14.tar.gz
cd haproxy-1.6.14
make TARGET=linux2628 PREFIX=/application/haproxy-1.6.14
##安装时一定要指定路径,application下面的haproxy目录不用提前创建,安装时自动创建
make install PREFIX=/application/haproxy-1.6.14 ##查看并创建软链接
cd /application/
ln -s /application/haproxy-1.6.14 /application/haproxy ##安装成功后,查看版本
/application/haproxy/sbin/haproxy -v ##复制haproxy文件到/usr/sbin下
##因为下面的haproxy.init启动脚本默认会去/usr/sbin下找,当然你也可以修改,不过比较麻烦
cp /application/haproxy/sbin/haproxy /usr/sbin/ ##复制haproxy脚本,到/etc/init.d下
cp /tools/haproxy-1.6.14/examples/haproxy.init /etc/init.d/haproxy
chmod 755 /etc/init.d/haproxy ##创建系统账号,不创建家目录,禁止ssh登录
useradd haproxy -s /sbin/nologin -M ##创建配置文件目录
mkdir /etc/haproxy -p ##创建chroot目录
mkdir /var/lib/haproxy -p
创建配置文件,路径和内容如下
[root@data-1-1 ~]# cat /etc/haproxy/haproxy.cfg
global
#设置日志
log 127.0.0.1 local3 info
chroot /var/lib/haproxy
#用户与用户组
user haproxy
group haproxy
#守护进程启动
daemon
#最大连接数
maxconn 4096 #默认配置
defaults
log global
mode http
retries 3 #连接后端服务器的失败重试次数
option httplog
option dontlognull #日志中不记录空连接,比如不记录健康检查的连接
option forwardfor #这里设置之后,下面的frontend和backend默认会继承它
timeout connect 10s
timeout client 20s
timeout server 30s
timeout check 5s #对后端服务器的检测超时时间 #前端配置,http_front名称可自定义
frontend http_front_8181
bind *:8181
mode http
option httpclose
default_backend http_back_8181 #后端配置,http_back名称可自定义
backend http_back_8181
mode http
balance source
option httpchk GET /index.html #设置健康检查页面
server node1 10.0.2.16:8080 check inter 2000 rise 3 fall 3 weight 6
server node2 10.0.2.17:8080 check inter 2000 rise 3 fall 3 weight 6 #设置管理页面
listen admin_stats
bind *:9188
mode http
log 127.0.0.1 local3 err
stats refresh 30s
stats uri /my_haproxy_status
stats realm welcome login\ Haproxy
stats auth ha_admin:ha_admin!23
stats hide-version
stats admin if TRUE
[root@data-1-1 ~]#
关于配置文件
Haproxy配置中分成五部分内容,当然这些组件不是必选的,可以根据需要选择作为配置。
•global:参数是进程级的,通常和操作系统(OS)相关。这些参数一般只设置一次,如果配置无误,就不需要再次配置进行修改;
•default:配置默认参数的,这些参数可以被利用配置到frontend,backend,listen组件;
•frontend:接收请求的前端虚拟节点,Frontend可以根据规则直接指定具体使用后端的backend(可动态选择);
•backend:后端服务集群的配置,是真实的服务器,一个Backend对应一个或者多个实体服务器;
•listen:Frontend和Backend的组合体。
配置使用系统的rsyslog服务记录haproxy日志
##配置rsyslog记录haproxy访问日志
vim /etc/rsyslog.conf ##去掉下面两行前面的#号
$ModLoad imudp
$UDPServerRun 514 ##并添加下面一行
local3.* /var/log/haproxy.log ##重启rsyslog
systemctl restart rsyslog ###查看监听,udp的514端口启动
[root@data-1-1 ~]# netstat -lntup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 837/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 917/master
tcp6 0 0 :::22 :::* LISTEN 837/sshd
tcp6 0 0 ::1:25 :::* LISTEN 917/master
udp 0 0 0.0.0.0:514 0.0.0.0:* 1543/rsyslogd
udp6 0 0 :::514 :::* 1543/rsyslogd
[root@data-1-1 ~]#
可以启动haproxy了
haproxy启动和停止命令
/etc/init.d/haproxy start
/etc/init.d/haproxy stop
补充部分
haproxy自带的启动脚本有个语法小bug
后面不跟stop或者start的时候,提示第26行有语法错误
[root@data-1-2 ~]# /etc/init.d/haproxy
/etc/init.d/haproxy: line 26: [: =: unary operator expected
Usage: haproxy {start|stop|restart|reload|condrestart|status|check}
[root@data-1-2 ~]# /etc/init.d/haproxy start
Starting haproxy (via systemctl): [ OK ]
26行这里语法报错
百度解决
https://blog.csdn.net/goodlixueyong/article/details/6564591
shell脚本报错:"[: =: unary operator expected"
在匹配字符串相等时,我用了类似这样的语句:
if [ $STATUS == "OK" ]; then
echo "OK"
fi
在运行时出现了 [: =: unary operator expected 的错误,就一直找不到原因,尝试了删除等号两侧的空格和括号里的空格都不管用,
最后baidu了一下,才找到原因。把语句改成这样就不会出错了.
if [[ $STATUS = "OK" ]];
then
echo "OK"
fi
究其原因,是因为如果变量STATUS值为空,那么就成了 [ = "OK"] ,显然 [ 和 "OK" 不相等并且缺少了 [ 符号,所以报了这样的错误。
当然不总是出错,如果变量STATUS值不为空,程序就正常了,所以这样的错误还是很隐蔽的。
最后是再加一层中括号
再次测试没问题
多个frontend配置的部分,这里是多个端口
[root@data-1-1 ~]# cat /etc/haproxy/haproxy.cfg
global
#设置日志
log 127.0.0.1 local3 info
chroot /var/lib/haproxy
#用户与用户组
user haproxy
group haproxy
#守护进程启动
daemon
#最大连接数
maxconn 4096 #默认配置
defaults
log global
mode http
retries 3 #连接后端服务器的失败重试次数
option httplog
option dontlognull #日志中不记录空连接,比如不记录健康检查的连接
option forwardfor
timeout connect 10s
timeout client 20s
timeout server 30s
timeout check 5s #对后端服务器的检测超时时间 #前端配置,http_front名称可自定义
frontend http_front_8181
bind *:8181
option httpclose
default_backend http_back_8181 #前端配置,http_front名称可自定义
frontend http_front_18181
bind *:18181
option httpclose
default_backend http_back_18181 #后端配置,http_back名称可自定义
backend http_back_8181
balance source
option httpchk GET /index.html #设置健康检查页面
server node1 10.0.2.16:8080 check inter 2000 rise 3 fall 3 weight 6
# server node2 10.0.2.17:8080 check inter 2000 rise 3 fall 3 weight 6 #后端配置,http_back名称可自定义
backend http_back_18181
balance source
option httpchk GET /index.html #设置健康检查页面
# server node1 10.0.2.16:8080 check inter 2000 rise 3 fall 3 weight 6
server node2 10.0.2.17:8080 check inter 2000 rise 3 fall 3 weight 6 listen admin_stats
bind *:9188
mode http
log 127.0.0.1 local3 err
stats refresh 30s
stats uri /my_haproxy_status
stats realm welcome login\ Haproxy
stats auth ha_admin:ha_admin!23
stats hide-version
stats admin if TRUE
[root@data-1-1 ~]#
至此haproxy安装完毕
开始Keepalived部分
选择Keepalived版本
http://www.keepalived.org/download.html
可以看到1.3.5版本过去半年左右才出现的1.3.6版本
那说明1.3.5版本没太多或者大的bug
安装tcpdump,它是个抓包工具,有时候会用到
安装psmisc包,安装之后多了 fuser, killall,pstree等命令
yum install tcpdump -y
yum install psmisc -y
安装和配置过程
下载,编译,其中fwmark模块貌似和防火墙相关的,禁用掉即可
安装完毕,创建个软链接
cd /tools/
wget http://10.0.2.15:8298/soft/keepalived-1.3.5.tar.gz
tar xfz keepalived-1.3.5.tar.gz
cd keepalived-1.3.5
./configure --prefix=/application/keepalived-1.3.5 --disable-fwmark
make && make install
ls /application/keepalived-1.3.5/
ln -s /application/keepalived-1.3.5 /application/keepalived
创建Keepalived的默认配置文件目录
拷贝配置文件
拷贝Keepalived工具到系统可执行路径中
修改记录日志的配置文件,并拷贝到sysconfig目录下
查看Keepalived服务是否已经加入到了systemd管理路径下
mkdir /etc/keepalived -p
/bin/cp /application/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
/bin/cp /application/keepalived/sbin/keepalived /usr/sbin/
sed -i s#'KEEPALIVED_OPTIONS="-D"'#'KEEPALIVED_OPTIONS="-D -d -S 0"'#g /application/keepalived/etc/sysconfig/keepalived
/bin/cp /application/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
ls -l /usr/lib/systemd/system/keepalived.service
补充说明下,其中修改sysconfig下面的Keepalived配置文件的作用
配置指定文件接收Keepalived日志
keepalived默认输出的日志在/var/log/messages
最下面添加一行
-S指定一个syslog设备接收,0表示local0设备
-D是详细日志
-d是dump配置文件内容到日志中
另外
因为启动脚本默认读取的是/application/keepalived-1.3.5/etc/sysconfig/keepalived这个文件
这里可以不用把这个文件拷贝到/etc/sysconfig目录下,这里拷贝了虽然没用到,也没关系
修改Keepalived服务配置文件
执行下面命令即可,这里是master节点,覆盖原来的配置了
采用的单播方式,而不是默认的组播(可能一些机房或者公有云禁止了组播报文)
同一集群的keepalived的主、备机的virtual_router_id 必须相同,取值0-255,这里取值80,随便取得
但是同一内网中不应有相同virtual_router_id的集群
vrrp_instance中必须有track_script部分,里面的chk_haproxy名字和是vrrp_script右边的一致,这样在haproxy服务停止之后,vip能迅速切换到备机。
少了它的话,只有Keepalived服务停止,vip才能切换过去,haproxy停止并没有迁移vip。
###keepalived config file
cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived global_defs {
notification_email {
525031638@qq.com
}
notification_email_from Haproxy_KeepAlived@163.com
smtp_server 127.0.0.1
smtp_connect_timeout 3
router_id Haproxy_1
} vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 3
} vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 80
priority 150
advert_int 5
authentication {
auth_type PASS
auth_pass ha_keep
}
track_script {
chk_haproxy
}
virtual_ipaddress {
10.0.1.63/24 dev eth0
}
unicast_src_ip 10.0.1.61
unicast_peer {
10.0.1.62
}
}
EOF
下面是backup机器的配置执行方式
###keepalived config file
cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived global_defs {
notification_email {
525031638@qq.com
}
notification_email_from Haproxy_KeepAlived@163.com
smtp_server 127.0.0.1
smtp_connect_timeout 3
router_id Haproxy_2
} vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 3
} vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 80
priority 100
advert_int 5
authentication {
auth_type PASS
auth_pass ha_keep
}
track_script {
chk_haproxy
}
virtual_ipaddress {
10.0.1.63/24 dev eth0
}
unicast_src_ip 10.0.1.62
unicast_peer {
10.0.1.61
}
}
EOF
修改rsyslog,让Keepalived的日志采用local设备记录,这样可以自定义记录路径,而不是采用默认的/var/log/message
配置完毕后需要在syslog.conf文件里添加一行,如下
上面配置文件表示syslog让local0接收,local0接收后往后面的/var/log/keepalived.log里面接收
.* 表示所有状态都接受,检查没问题重启rsyslog服务
###config rsyslog for keepalived
cat >> /etc/rsyslog.conf << EOF
#keepalived
local0.* /var/log/keepalived.log
EOF
tail -2 /etc/rsyslog.conf
systemctl restart rsyslog
修改Keepalived服务启动脚本,注意cat追加的时候有变量,需要用斜线转义下
这里只把pidfile路径改成系统通用路径下
最后需要reload系统服务
###modify keepalived.service
cat > /usr/lib/systemd/system/keepalived.service << EOF
[Unit]
Description=LVS and VRRP High Availability Monitor
After=syslog.target network-online.target [Service]
Type=forking
PIDFile=/var/run/keepalived.pid
KillMode=process
EnvironmentFile=-/application/keepalived-1.3.5/etc/sysconfig/keepalived
ExecStart=/application/keepalived-1.3.5/sbin/keepalived \$KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP \$MAINPID [Install]
WantedBy=multi-user.target
EOF ##reload service config
systemctl daemon-reload
补充说明下
一些人安装后,是复制下面路径下的启动脚本到/etc/init.d下
我的是centos7.4环境,没找到它
/bin/cp /application/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
但是locate命令查找keepalived的时候发现下面出现了它
/usr/lib/systemd/system/keepalived.service
可能centos7已经默认编译安装后自动加入到了systemd
ll -al /usr/lib/systemd/system/keepalived.service
最后启动Keepalived服务即可,可以看到3个进程
[root@data-1-2 ~]# systemctl stop keepalived
[root@data-1-2 ~]# systemctl start keepalived
[root@data-1-2 ~]# ps -ef |grep keepalived
root 6456 6300 0 15:16 pts/1 00:00:00 tail -F /var/log/keepalived.log
root 13307 1 0 19:10 ? 00:00:00 /application/keepalived-1.3.5/sbin/keepalived -D -d -S 0
root 13308 13307 0 19:10 ? 00:00:00 /application/keepalived-1.3.5/sbin/keepalived -D -d -S 0
root 13309 13307 0 19:10 ? 00:00:00 /application/keepalived-1.3.5/sbin/keepalived -D -d -S 0
root 13319 2275 0 19:10 pts/0 00:00:00 grep --colour=auto keepalived
[root@data-1-2 ~]#
至此,Keepalived主备节点都安装完毕。接下来就是测试服务能否正常切换
把Keepalived服务加入启动项
[root@data-1-1 ~]# systemctl enable keepalived
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service.
[root@data-1-1 ~]#
haproxy暂时无法用systemd管理,使用chkconfig工具管理,加入启动项
[root@data-1-1 ~]# chkconfig haproxy on
[root@data-1-1 ~]# chkconfig --list |grep haproxy Note: This output shows SysV services only and does not include native
systemd services. SysV configuration data might be overridden by native
systemd configuration. If you want to list systemd services use 'systemctl list-unit-files'.
To see services enabled on particular target use
'systemctl list-dependencies [target]'. haproxy 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@data-1-1 ~]#