OS : Centos 7.8
Spec : CPU 4 Core / Memory 4 GB / HDD 200 GB
Network IP :
HAProxy Version : 2.2.2
Keepalived Version : 2.1.5
서버 앞단에 별도의 방화벽이 있어 서버 방화벽은 disable 했다.
> systemctl stop firewalld.service
> systemctl disable firewalld.service
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
> setenforce 0 # 끄기
> vi /etc/sysconfig/selinux # 부팅시 적용
SELINUX=disabled
> wget http://www.haproxy.org/download/2.2/src/haproxy-2.2.2.tar.gz
> tar -zxvf haproxy-2.2.2.tar.gz
> cd haproxy-2.2.2
> yum install pcre-static pcre-devel openssl-devel systemd-devel
> make TARGET=linux-glibc USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1 USE_SYSTEMD=1
> make install
> mkdir -p /etc/haproxy/certs
> mkdir -p /etc/haproxy/errors
> mkdir -p /var/log/haproxy
> mkdir /var/lib/haproxy
> useradd -r haproxy
HAProxy는 기본적으로 messages 파일에 로그를 생성한다. 별도의 로그파일로 관리하기 위해 아래 syslog 설정 진행.
로그를 통합하려는 목적이 없으면 아래는 진행하지 않아도 된다.
> vi /etc/rsyslog.conf
# Provides UDP syslog reception (haproxy가 log 전송시 127.0.0.1:514로 보내서 필요...)
$ModLoad imudp
$UDPServerRun 514
# messages 파일에 haproxy 관련 로그 쓰지 않도록 messages 설정줄에 local2.none 추가
*.info;mail.none;authpriv.none;cron.none;local2.none /var/log/messages
> vi /etc/rsyslog.d/haproxy.conf
# 모든 log
local2.* /var/log/haproxy/haproxy.log
# local2.=info info2인 등급
local2.=info /var/log/haproxy/haproxy-info.log
# local2.notice notice 등급 이상
local2.notice /var/log/haproxy/haproxy-notice.log
# syslog 서버로 전송
local2.notice @10.10.10.114
> systemctl restart rsyslog.service
별도로 관리하는 로그파일이 30일만 보관될 수 있도록 설정 진행. 이 역시 별도의 로그를 사용하지 않는다면 진행할 필요 없음.
> vi /etc/logrotate.d/haproxy
/var/log/haproxy/*.log {
daily
rotate 30
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
/bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
아래 설정은 하나의 VIP와 두개의 Service를 4대의 리얼서버로 LB 하는 구성과
HAProxy의 상태 정보를 Web UI로(9000번 포트) 확인할 수 있는 stats 환경을 포함하고 있음
> vi /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# <http://haproxy.1wt.eu/download/1.4/doc/configuration.txt>
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
#frontend main *:5000
# acl url_static path_beg -i /static /images /javascript /stylesheets
# acl url_static path_end -i .jpg .gif .png .css .js
#
# use_backend static if url_static
# default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
#backend static
# balance roundrobin
# server static 127.0.0.1:4331 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
#backend app
# balance roundrobin
# server app1 127.0.0.1:5001 check
# server app2 127.0.0.1:5002 check
# server app3 127.0.0.1:5003 check
# server app4 127.0.0.1:5004 check
#---------------------------------------------------------------------
# HAProxy Statistics Page (http://10.10.10.201:9000/haproxy_stats)
#---------------------------------------------------------------------
listen stats
bind *:9000
stats enable
stats realm HAProxy Statistics
stats uri /haproxy_stats
stats auth admin:admin
#---------------------------------------------------------------------
# TCP-in
#---------------------------------------------------------------------
listen tcp-in-33010
bind 10.10.10.203:33010
balance roundrobin
log global
mode tcp
option tcplog
server Server75 10.10.10.75:33010 check
server Server76 10.10.10.76:33010 check
listen tcp-in-33011
bind 10.10.10.203:33011
balance roundrobin
log global
mode tcp
option tcplog
server Server77 10.10.10.77:33011 check
server Server78 10.10.10.78:33011 check
이 작업을 하지 않으면 haproxy에서 지정한 Service VIP를 불러오지 못하여 기동 안됨
아래 설정을 했는데도 Service VIP를 못불러 오면 keepalived 설정이 완료 된 후에 Service VIP를 설정하고 그 전에는 자신의 IP를 설정하여 테스트를 진행 한다.
> echo 'net.ipv4.ip_nonlocal_bind=1' >> /etc/sysctl.conf
> sysctl -p
소스 파일을 컴파일 하여 설치하였기 때문에 systemctl을 통해 서비스를 시작 및 종료를 할수 없다.
소스 파일에 포함되어 있는 예제 파일을 간단히 수정하여 systemctl을 등록한다.
> cp /root/haproxy-2.2.2/contrib/systemd/haproxy.service.in /usr/lib/systemd/system/haproxy.service
> vi /usr/lib/systemd/system/haproxy.service # @SBINDIR@ 부분만 실제 디렉토리로 수정 #
[Unit]
Description=HAProxy Load Balancer
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=-/etc/default/haproxy
EnvironmentFile=-/etc/sysconfig/haproxy
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "EXTRAOPTS=-S /run/haproxy-master.sock"
ExecStartPre=/usr/local/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS
ExecStart=/usr/local/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS
ExecReload=/usr/local/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Restart=always
SuccessExitStatus=143
Type=notify
# The following lines leverage SystemD's sandboxing options to provide
# defense in depth protection at the expense of restricting some flexibility
# in your setup (e.g. placement of your configuration files) or possibly
# reduced performance. See systemd.service(5) and systemd.exec(5) for further
# information.
# NoNewPrivileges=true
# ProtectHome=true
# If you want to use 'ProtectSystem=strict' you should whitelist the PIDFILE,
# any state files and any other files written using 'ReadWritePaths' or
# 'RuntimeDirectory'.
# ProtectSystem=true
# ProtectKernelTunables=true
# ProtectKernelModules=true
# ProtectControlGroups=true
# If your SystemD version supports them, you can add: @reboot, @swap, @sync
# SystemCallFilter=~@cpu-emulation @keyring @module @obsolete @raw-io
[Install]
WantedBy=multi-user.target
> systemctl daemon-reload
> systemctl status haproxy.service
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; disabled; vendor preset: disabled)
Active: inactive (dead)
> systemctl enable haproxy.service
Created symlink from /etc/systemd/system/multi-user.target.wants/haproxy.service to /usr/lib/systemd/system/haproxy.service.
> systemctl start haproxy.service
http://10.10.10.201:9000/haproxy_stats 으로 접속하여 상태 확인
참고사이트 : https://snapcraft.io/install/keepalived/centos
Install keepalived on CentOS using the Snap Store | Snapcraft
Get the latest version of keepalived for on CentOS - High availability VRRP/BFD and load-balancing for Linux
snapcraft.io
> yum install epel-release
> yum install snapd
> systemctl enable --now snapd.socket
> ln -s /var/lib/snapd/snap /snap
> snap install keepalived --classic
> systemctl status snap.keepalived.daemon
keepalived는 기본적으로 messages 파일에 log를 남기는데, messages 파일에서 keepalived 관련 로그만 별도 파일(haproxy-notice.log)에 저장하고 외부 syslog 서버로 전송
> vi /etc/rsyslog.d/keepalived.conf
if $programname == "Keepalived_vrrp" then /var/log/haproxy/haproxy-notice.log
if $programname == "Keepalived_vrrp" then @10.10.10.114
지금까지의 상태를 VM Template으로 생성하고 HAProxy_L4_B를 만들때 불러와서 사용한다.
VM 환경이 아니라면, 지금까지의 했던 내용을 새로운 서버에 동일하게 적용하면 된다.
아래 구성은 A 장비가 Active에서 장애가 발생하여 B 장비가 Active가 된 후, A 장비가 정상화 되었을때 다시 A 장비로 Active가 전환되는 걸 방지하기 위한 구성이다.
이 구성에서 A 장비 장애시 B 장비 Active 되면, B 장비에서 keepalived를 stop 혹은 restart 하면 A 장비가 다시 Active 된다.
> vi /etc/keepalived/keepalived.conf
global_defs {
notification_email {
mail@example.net
}
notification_email_from noreply@example.net
smtp_server x.x.x.x
smtp_connect_timeout 30
router_id HAProxy_L4_A
}
# haproxy process를 체크하여 down되면 priority 값을 60 줄임 (150-60=90)
# 따라서 haproxy가 down되면 HAProxy_L4_B의 값 100 보다 10이 작게 되어 HAProxy_L4_B가 Active됨
vrrp_track_process track_haproxy {
process haproxy
weight -60
}
# nopreempt 옵션을 이용하여 자동 failback 안되도록 구성
# nopreempt 사용시 state를 `BACKUP` 으로 설정해야 함
# HAProxy_L4_A를 Active로 설정하려면 HAProxy_L4_B의 keepalived를 stop or restart 하면 됨
vrrp_instance VI_1 {
state BACKUP
interface ens192
garp_master_delay 10
smtp_alert
nopreempt
virtual_router_id 171
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass haproxy_171
}
virtual_ipaddress {
10.10.10.200
10.10.10.203
}
track_process {
track_haproxy
}
}
> systemctl restart snap.keepalived.daemon.service
위에서 작성해둔 HAProxy_L4 Template을 이용하여 HAProxy_L4_B VM 생성
> vi /etc/keepalived/keepalived.conf
global_defs {
notification_email {
mail@example.net
}
notification_email_from noreply@example.net
smtp_server x.x.x.x
smtp_connect_timeout 30
router_id HAProxy_L4_B
}
vrrp_instance VI_1 {
state BACKUP
interface ens192
garp_master_delay 10
smtp_alert
preempt
virtual_router_id 171
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass haproxy_171
}
virtual_ipaddress {
10.10.10.200
10.10.10.203
}
}
> systemctl restart snap.keepalived.daemon.service
Keepalived and high availability: Advanced topics
The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. The content published on this site are community contributions and are for informational purpose only AND ARE NOT, AND ARE NOT INTENDED TO BE, RED
www.redhat.com
> vi /etc/haproxy/haproxy.cfg
stats socket /var/run/haproxy.sock mode 600 level admin
stats timeout 2m
> socat /var/run/haproxy.sock readline
prompt
> show info
...
>
Linux 서버의 기본 System Parameter는 운영환경에서 사용하기엔 다소 부족한 면이 있어 아래와 같이 수정한다.
아래 값은 필자의 경험상 가장 안정적이고 성능도 잘 나오는 구성을 다년간 찾다가 최근에 정착한 구성이다.
> vi /etc/sysctl.conf
net.core.netdev_max_backlog = 30000
net.core.rmem_default = 253952
net.core.wmem_default = 253952
net.core.somaxconn = 1024
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 253952 253952 16777216
net.ipv4.tcp_wmem = 253952 253952 16777216
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_tw_reuse = 1
현재 필자는 이렇게 구성한 HAProxy L4를 운영환경에서 사용하고 있다.
아래 사진은 필자가 사용하고 있는 HAProxy의 상태 화면이다. 자세히 보면 꽤 많은 접속량을 보이고 있으며 1년 6개월 정도의 UP time을 유지하고 있다.
단 한번의 장애도 없었으며, 성능도 아무런 이슈가 없는 상태다.
다만 문제 발생시 해결은 오로지 본인의 몫이므로 이 글을 읽는 분들은 잘 판단해서 진행하길 바란다.
댓글 영역