HAProxy (django 3tier app host locally)
트래픽 부하 분산을 위한 프록시 서버 구성 및 서버 이중화 구성
# HAproxy 및 중요 요소들 설치 ( 컴파일, Systemd 등록, SSL 구성 )
yum -y install gcc openssl openssl-devel systemd-devel
# HAproxy 디렉터리 생성 후 이동
mkdir /HAproxy
cd /HAproxy
# wget 명령으로 Web Server로 부터 haproxy 파일 다운로드
wget http://www.haproxy.org/download/2.3/src/haproxy-2.3.10.tar.gz
# tar 명령으로 haproxy-2.3.10 파일 압축 해제
tar xvfz haproxy-2.3.10.tar.gz
# 압축 해제한 디렉토리 안으로 이동
cd haproxy-2.3.10/
# 소스파일 다운로드 및 사용할 기능 선택 후 컴파일 작업을 수행
make TARGET=linux-glibc USE_OPENSSL=1 USE_SYSTEMD=1
# 컴파일 작업이 완료 될 경우 서버프로그램 생성
make install
# HAproxy 운영을 위한 작업 디렉터리 생성
mkdir /etc/haproxy
mkdir /etc/haproxy/certs
mkdir /etc/haproxy/errors
mkdir /var/log/haproxy
# Error 발생시 표시할 페이지 형식을 복사하여 Error 디렉터리로 붙여넣기
cd ./examples/errorfiles/
cp ./*.http /etc/haproxy/errors/
ls -l /etc/haproxy/errors/
합계 28
-rw-r--r-- 1 root root 188 8월 24 20:50 400.http
-rw-r--r-- 1 root root 189 8월 24 20:50 403.http
-rw-r--r-- 1 root root 213 8월 24 20:50 408.http
-rw-r--r-- 1 root root 205 8월 24 20:50 500.http
-rw-r--r-- 1 root root 205 8월 24 20:50 502.http
-rw-r--r-- 1 root root 213 8월 24 20:50 503.http
-rw-r--r-- 1 root root 195 8월 24 20:50 504.http
# HAproxy Daemon을 운영할 서비스용 계정 생성
# UID/GID는 1000번 이하로 지정사용 가능, 다른 서비스랑 겹칠 수 있으므로 주의
cd ~
useradd -c "HAproxy Daemon User" -s /sbin/nologin haproxy
tail -1 /etc/passwd
haproxy:x:1001:1001:HAproxy Daemon User:/home/haproxy:/sbin/nologin
# HAproxy 서버프로그램에서 발생하는 로그기록을 Binding 하기위한 설정값 정의
# HAproxy 로그 발생 > rsyslogd 데몬이 로그을 가져와 지정 된 파일에 로그기록을 작성
vi /etc/rsyslog.d/haproxy.conf
$ModLoad imudp
$UDPServerAddress 127.0.0.1
$UDPServerRun 514
local0.* /var/log/haproxy/haproxy-traffic.log
# 방화벽 설정 > 514/UDP Port 추가
firewall-cmd --permanent --add-port=514/udp
success
firewall-cmd --reload
success
# HAproxy 로그기록 Rotate 정의
vi /etc/logrotate.d/haproxy
/var/log/haproxy/*.log {
daily
rotate 30
create 0600 root root
compress
notifempty
missingok
sharedscripts
postrotate
/bin/systemctl restart rsyslog.service > /dev/null 2>/dev/null || true
endscript
}
# Haproxy Main 설정파일 편집
vi /etc/haproxy/haproxy.cfg
global
daemon
maxconn 4000
user haproxy
group haproxy
log 127.0.0.1:514 local0
defaults
mode http
option redispatch
retries 3
log global
option httplog
option dontlognull
option dontlog-normal
option http-server-close
option forwardfor
maxconn 3000
timeout connect 10s
timeout http-request 10s
timeout http-keep-alive 10s
timeout client 1m
timeout server 1m
timeout queue 1m
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
listen stats
bind *:9000
stats enable
stats realm Haproxy Stats Page
stats uri /
stats auth admin:haproxy1
frontend proxy
bind *:80
default_backend WEB_SRV_list
backend WEB_SRV_list
balance roundrobin
option httpchk HEAD /
http-request set-header X-Forwarded-Port %[dst_port]
cookie SRVID insert indirect nocache maxlife 10m
server WEB_01 10.1.3.10:80 cookie WEB_01 check inter 3000 fall 5 rise 3
server WEB_02 10.1.3.20:80 cookie WEB_02 check inter 3000 fall 5 rise 3
# 설정파일 확인
haproxy -f /etc/haproxy/haproxy.cfg -c
Configuration file is valid
# Haporxy 시작 및 자동시작 등록 ( systemd 등록작업을 완료했으므로, systemctl 작업이 가능 )
systemctl start haproxy
systemctl enable haproxy
Created symlink from /etc/systemd/system/multi-user.target.wants/haproxy.service to /etc/systemd/system/haproxy.service.
# 방화벽 설정 > http service 추가, 9000/tcp port 추가
firewall-cmd --permanent --add-service=http
success
firewall-cmd --permanent --add-port=9000/tcp
success
firewall-cmd --reload
success# HA-01 서버와 설정값은 동일하며, SSL/TLS 키파일 이름만 ha02로 변경하여 작업을 진행
# SSL 인증서를 발급하기 위한 패키지 설치 확인
rpm -qa | grep openssl
# 개인키 생성
openssl genrsa -out /etc/haproxy/certs/ha01.key 2048
# 인증요청서 생성
openssl req -new -key /etc/haproxy/certs/ha01.key -out /etc/haproxy/certs/ha01.csr
-----
Country Name (2 letter code) [XX]:KR
State or Province Name (full name) []:Seoul
Locality Name (eg, city) [Default City]:Gangnam
Organization Name (eg, company) [Default Company Ltd]:PROMET
Organizational Unit Name (eg, section) []:CloudTeam
Common Name (eg, your name or your server's hostname) []:www.promet.com
Email Address []:root@promet.com
A challenge password []: (Enter)
An optional company name []: (Enter)
# 공개키 인증서 생성
openssl x509 -req -days 365 -in /etc/haproxy/certs/ha01.csr -signkey /etc/haproxy/certs/ha01.key -out /etc/haproxy/certs/ha01.crt
Signature ok
subject=/C=KR/ST=Seoul/L=Gangnam/O=KGITBANK ...
Getting Private key
# 개인키와 공개키 인증서의 내용을 병합하여 하나의 파일로 생성
cd /etc/haproxy/certs
cat ha01.crt ha01.key > ha01_ssl.crt
# 개인키와 공개키 인증서를 별도의 디렉터리에 백업을 진행
mv ha01.* /backup
ls /backup
ha01.crt ha01.csr ha01.key
# 병합한 인증서 파일 내용 확인
cd ~
cat /etc/haproxy/certs/ha01_ssl.crt
-----BEGIN CERTIFICATE-----
MIIDpDCCAowCCQDtJvryO8s8TjANBgkqhkiG9w0BAQsFADCBkzELMAkGA1UEBhMC
S1IxDjAMBgNVBAgMBVNlb3VsMRAwDgYDVQQHDAdHYW5nbmFtMREwDwYDVQQKDAhL
R0lUQkFOSzESMBAGA1UECwwJQ2xvdWRUZWFtMRkwFwYDVQQDDBB3d3cua2dpdGJh
....
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAw9CdQpJgKITnapH9EHlgxD5wATMKxLS+cPrw517Q0XNyrMD2
0mryl9lDJv+JynU3TDvoNTMcR2cv87G5PqgbDOKvCAWLLKuHaMC19zzgqQFU6T3d
h2Kj5GKmURNvoPxvR1m7Tbz8eXR0fmBuF36ieT3ZkLe0cXI2rOfyv2pAQAtR5FRJ
....
-----END RSA PRIVATE KEY-----
vi /etc/haproxy/haproxy.cfg
# Global 영역에 추가작성
# SSL/TLS연결시 사용할 협상 Ciphers Set(암호화/해시 프로토콜) 지정 [ 가이드에서 권장하는 Ciphers Set을 사용 ]
ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
# TLSv1.2이상의 연결만 허용 [ 일반 SSL 연결거부 ]
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
# Frontend 영역에 추가작성
bind *:443 ssl crt /etc/haproxy/certs/ha01_ssl.crt # https 연결 Binding 설정 및 사이트 공개키 절대경로값 명시
http-request redirect scheme https code 308 unless { ssl_fc } # http 연결 요청이 들어올 경우 상태코드값 308번을 사용하여 https로 Redirect 설정
# 설정파일 확인, 방화벽 설정 > https 서비스 추가, haproxy 데몬 재실행
haproxy -f /etc/haproxy/haproxy.cfg -c
firewall-cmd --permanent --add-service=https
success
firewall-cmd --reload
success0
systemctl restart haproxy
※ VRRP 설정 > Keepalived > Virtual Router 구성 > HA-01, HA-02 두대의 서버에서 동일하게 작업
# HA-01 VRRP 구성 작업
# nonlocal_bind 파라미터 값을 사용 상태로 변경
echo net.ipv4.ip_nonlocal_bind=1 >> /etc/sysctl.conf
# 구성파일 설정 Load
sysctl -p
net.ipv4.ip_nonlocal_bind = 1
# keepalived 패키지 설치
yum -y install keepalived-*
# keepalived.conf 설정파일 편집
vi /etc/keepalived/keepalived.conf
global_defs {
router_id HA_01
}
vrrp_script HA_Check {
script "killall -0 haproxy"
rise 3
fall 3
weight 2
}
vrrp_instance HAGroup_1 {
state MASTER
interface ens32
garp_master_delay 5
virtual_router_id 51
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass test123
}
virtual_ipaddress {
10.1.5.50
}
track_script {
HA_Check
}
}
# firewall-cmd 명령어를 이용하여 직접 VRRP에 관한 방화벽 규칙을 정의 후 적용
firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -i ens32 -d 224.0.0.18 -p vrrp -j ACCEPT
firewall-cmd --direct --add-rule ipv4 filter OUTPUT 1 -o ens32 -d 224.0.0.18 -p vrrp -j ACCEPT
firewall-cmd --runtime-to-permanent
firewall-cmd --direct --get-all-rules
ipv4 filter OUTPUT 1 -o ens32 -d 224.0.0.18 -p vrrp -j ACCEPT
ipv4 filter INPUT 1 -i ens32 -d 224.0.0.18 -p vrrp -j ACCEPT
# keepalived 데몬 활성화, 시작
systemctl start keepalived
systemctl enable keepalived
# HA-02 VRRP 구성 작업
# HA-01 구성작업과 동일, 아래 내용만 수정
# priority 값과 state를 설정
vi /etc/keepalived/keepalived.conf
router_id HA_02
state BACKUP
priority 100
# VRRP 구성확인
# HA-01에서 명령어 입력
ip address list | grep 10.1.5.50
inet 10.1.5.50/32 scope global ens32
# HA-02에서 명령어 입력
ip address list | grep 10.1.5.50
# 현재 Master장비인 HA-01에서만 10.1.5.50 VIP 주소를 점유하고 있는지 확인
# 둘다 동일한 VIP를 점유하는 경우 VRRP Member구성에 문제가 있는 상태
# HA-01에서 명령어 입력
systemctl stop keepalived
ip address list | grep 10.1.5.50
# HA-02에서 명령어 입력
ip address list | grep 10.1.5.50
inet 10.1.5.50/32 scope global ens32
# Master 장비에서 Keepalived 데몬을 중지할 경우 Backup 장비에서 해당 VIP를 점유하는 것을 확인
# 다시 Start를 진행하여 기존 Master 장비가 다시 VIP를 점유하는지까지 확인