Load Balancer - HAProxy

이 글에서 설명하는 서비스 구성에 필요한 가상 머신, 공인 IP, 도메인은 모두 준비되어 있음을 전제함

서비스 구성도

서버 정보

가상머신
IP
운영체제
용도

VM1

192.168.10.116

Linux (CentOS 7)

Load Balancer

VM2

192.168.10.121

WindowsServer2016

웹 서비스 (IIS)

VM3

192.168.10.122

WindowsServer2016

웹 서비스 (IIS)

VM4

192.168.10.123

WindowsServer2016

웹 서비스 (IIS)

VM5

192.168.10.125

WindowsServer2016

웹 서비스 (IIS)

HAProxy 설정

설치

sudo yum -y install haproxy

설치가 완료되면 기본적인 설정파일은 다음 경로에 있음

vi /etc/haproxy/haproxy.cfg

파일 내용 수정

백엔드 설정

backend web_main
    balance roundrobin
    server web1 192.168.10.121:80 check
    server web2 192.168.10.122:80 check
	
backend web_abc
    balance roundrobin
    server web1 192.168.10.123:80 check
	
backend web_xyz
    balance roundrobin
    server web1 192.168.10.125:80 check

HTTP 설정

frontend http_front
    bind *:80
    default_backend web_main

WEB UI 설정

listen stats
    bind *:9000
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy Statistics
    stats uri /

HAProxy 서비스

시작

systemctl start haproxy

부팅 후 자동 실행

systemctl enable haproxy

상태 확인

systemctl status haproxy

실행 오류 시 확인 방법: 루트로 포그라운드에서 수동으로 시작하고 오류 메시지를 확인

haproxy -f /etc/haproxy/haproxy.cfg -db

서비스가 시작되지 않고 아래 오류 메시지와 같이 뜰 경우

오류메시지: "Starting frontend mssql_frontend: cannot bind socket [0.0.0.0:1433]"

setsebool -P haproxy_connect_any=1

setsebool -P haproxy_connect_any=1 명령어의 역할

  • setsebool: SELinux의 boolean 값을 설정하는 명령어

  • -P: 변경 사항을 영구적으로 적용하여 시스템 재부팅 후에도 유지

  • haproxy_connect_any=1: HAProxy가 모든 네트워크 서비스에 연결할 수 있도록 허용하는 boolean 값을 활성화

방화벽 설정 (포트 및 서비스 등록)

새로운 zone 생성

firewall-cmd --permanent --new-zone=webserver

방화벽에 서비스 추가

firewall-cmd --permanent --zone=webserver --add-service=http
firewall-cmd --permanent --zone=webserver --add-service=https

방화벽에 포트 추가

firewall-cmd --permanent --zone=webserver --add-port=80/tcp
firewall-cmd --permanent --zone=webserver --add-port=443/tcp
firewall-cmd --permanent --zone=webserver --add-port=9000/tcp

firewalld 재시작 및 새로 등록한 zone 활성화

firewall-cmd --reload
firewall-cmd --set-default-zone=webserver

정상 설정 여부 확인

firewall-cmd --list-services --zone=webserver
firewall-cmd --list-ports --zone=webserver

수신중인 포트 확인

  • 방화벽에서 포트를 설정해도 해당 포트로 실제 서비스가 수신되고 있어야 나타남

  • 방화벽 오픈은 되었으나 프로세스가 안 떠 있는 것 (포트를 열고 대기하고 있지 않은 상태)

netstat -tulpn | grep LISTEN
grep -w '80/tcp' /etc/services

certbot SSL 인증서 발급

letsencrypt으로 발급하기 위해서는 certbot 프로세서로 발급할 수 있으며 CentOS7에서는 epel-release를 설치해야 다운로드가 가능

sudo yum -y install epel-release
sudo yum -y install certbot

발급하는 방법

sudo certbot certonly --standalone -d <domain>

Multi-Domain

sudo certbot certonly --standalone -d <domain1> -d <domain2> -d <domain3>

설치가 완료되면 다음 경로에 기본적으로 설치

/etc/letsencrypt/live/<domain>/

파일을 불러오는것을 간소화 하기 위해서 다음 명령어로 하나로 합친다

mkdir /etc/haproxy/certs
cat /etc/letsencrypt/live/<domain>/*.pem > /etc/haproxy/certs/ssl.pem

인증서 자동 갱신 설정

Bash 쉘 스크립트 파일 작성

vi /bin/letsencrypt.sh
#!/bin/sh

systemctl stop haproxy
/usr/bin/certbot renew > /var/log/letsencrypt/renew.log
cat /etc/letsencrypt/live/<domain>/*.pem > /etc/haproxy/certs/ssl.pem
fuser -k 80/tcp
systemctl start haproxy

스크립트 파일에 권한 부여

chmod +x /bin/letsencrypt.sh

스크립트 파일 실행하고 생성된 로그 파일 마지막 수정 일자 확인

/bin/letsencrypt.sh
ls -l /var/log/letsencrypt

crontab을 이용하여 스크립트 파일 자동 실행 설정

sudo crontab -e

매일 오전 3시 마다 실행

0 3 * * * /bin/letsencrypt.sh

crontab 서비스 시작

service crond start

HTTPS 및 도메인별 접속할 백엔드 설정

vi /etc/haproxy/haproxy.cfg

기존 정의한 80 포트 설정을 다음과 같이 변경

  • HTTP 요청을 받아들이는 프론트엔드로, 클라이언트가 HTTPS가 아닌 요청을 보낼 경우에는 redirect 지시어를 사용하여 HTTPS로 리디렉션

frontend http-in
    bind *:80
    redirect scheme https if !{ ssl_fc }

HTTPS 설정

forntend https
    bind *:433 ssl crt /etc/haproxy/certs/ssl.pem
    acl host_abc hdr_end(host) -i abc.gsti.co.kr
    acl host_xyz hdr_end(host) -i xyz.gsti.co.kr
    mode http
    use_backend web_abc if host_abc
    use_backend web_xyz if host_xyz
    default_backend web_main

여러개 인증서 파일(.pem) 세팅 방법 <참고>

frontend ft_test
    mode http
    bind 0.0.0.0:443 ssl crt /certs/haproxy1.pem crt /certs/haproxy2.pem 
    use_backend bk_cert1 if { ssl_fc_sni my.example.com } # content switching based on SNI
    use_backend bk_cert2 if { ssl_fc_sni my.example.org } # content switching based on SNI

※ 리눅스 오픈된 포트 확인 및 등록

오픈된 HTTP Port 확인방법

semanage port -l | grep http_port_t

HTTP Port 오픈하기 위해 추가해주는 방법

semanage port -a -t http_port_t -p tcp 8081

HTTP Port 닫기 위해 제거

semanage port -d -t http_port_t -p tcp 8081

기타

Last updated