HAProxy (django 3tier app host locally)

WebNetwork

트래픽 부하 분산을 위한 프록시 서버 구성 및 서버 이중화 구성

# 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를 점유하는지까지 확인

 

← back