이 글에서는 HAProxy를 로드 밸런서로 구성하여 두 대의 Nginx 웹 서버(Apache로 대체 가능)에 트래픽을 분산하는 방법을 소개합니다. 모든 과정은 CentOS를 호스트 운영체제 기준으로 진행합니다.
HAProxy는 TCP 및 HTTP 애플리케이션에 고가용성과 부하 분산 기능을 제공하는 서버 소프트웨어로, 들어오는 요청을 여러 백엔드 서버에 분배합니다. Twitter, Instagram, GitHub, Amazon 등 유명 서비스에서도 널리 사용되고 있습니다.
HAProxy는 별도의 서버에 설치되어 클라이언트 요청을 받아 Nginx 웹 서버들로 전달하는 역할을 담당합니다. 전체 시스템 아키텍처는 아래와 같습니다.

백엔드 서버의 Nginx 설정
먼저 부하가 분산될 웹 서버들에 Nginx를 설치하고 설정합니다. EPEL 저장소를 추가한 후 yum(RHEL/CentOS 8에서는 dnf)으로 nginx를 설치합니다.
#yum install epel-release -y
#yum install nginx -y
그다음 nginx.conf 파일에서 해당 서버들이 HAProxy 서버와 백엔드 서버의 요청만 처리하도록 지정합니다.
백엔드 서버 1:
server {
listen current_server_IP_address:80 default_server;
allow second_backend_server_IP_address;
allow IP_haproxy;
deny all;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
백엔드 서버 2:
server {
listen current_server_IP_address:80 default_server;
allow first_backend_server_IP_address;
allow IP_haproxy;
deny all;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
nginx 설정 파일은 기본값 그대로 사용하며, listen 지시문으로 접속할 IP를 지정하고 allow, deny 지시문으로 우리 서버 외의 접근을 차단했습니다.
웹 서버가 정상 동작하려면 firewalld 또는 iptables로 HTTP 포트를 열어야 합니다.
#firewall-cmd --permanent –add-service=http
#firewall-cmd –reload
백엔드 서버 중 하나에서 테스트를 진행해 봅니다.
# curl IP_of_the_second_server
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 여기서 HTML 파일이 반환됩니다
서버가 표준 nginx 인덱스 파일을 반환했습니다. 확인 작업을 더 편하게 하기 위해 각 백엔드 서버의 인덱스 파일 내용을 변경하여, 브라우저에서 어떤 서버가 현재 요청을 처리했는지 쉽게 식별할 수 있도록 했습니다.
nginx 인덱스 파일은 /usr/share/nginx/html/ 경로에 위치합니다.
HAProxy 로드 밸런서 설정
이제 로드 밸런서로 사용할 서버에 HAProxy를 설치하고 설정합니다.
HAProxy 설치:
#yum install epel-release -y
#yum install haproxy -y
Running transaction Installing : haproxy-1.5.18-9.el7.x86_64 1/1 Verifying : haproxy-1.5.18-9.el7.x86_64 1/1 Installed: haproxy.x86_64 0:1.5.18-9.el7 Complete!
HAProxy를 활성화하려면 /etc/default/haproxy 파일에 Enabled=1을 추가해야 합니다.
#nano /etc/default/haproxy

이제 HAProxy 설정으로 넘어가겠습니다. 가장 단순한 구성에서는 로드 밸런서 서버가 모든 HTTP 요청을 받아 백엔드 서버들에 순차적으로 전달합니다.
#nano /etc/haproxy/haproxy.cfg
log /dev/log local0
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode http
log global
option httplog
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
frontend www
bind balancer_IP_address:80
default_backend nginx_pool
backend nginx_pool
balance roundrobin
mode http
server web1 IP_of_the_first_backend_server:80 check
server web2 IP_of_the_second_backend_server:80 check
설정을 저장한 후 haproxy.cfg 문법을 검사합니다.
#haproxy -f /etc/haproxy/haproxy.cfg -c
정상이라면 다음과 같은 메시지가 출력됩니다.
Configuration file is valid
이제 HAProxy를 재시작하고 리눅스 시작 프로그램에 등록한 후 방화벽에서 HTTP 포트를 엽니다.
#systemctl restart haproxy
#systemctl enable haproxy
#firewall-cmd —permanent –add-service=http
#firewall-cmd –reload
이것으로 로드 밸런서 설정이 완료되었습니다. 브라우저에서 HAProxy 서버의 IP 주소를 열어 정상 동작 여부를 확인해 보겠습니다.

보시는 것처럼 두 서버가 번갈아 가며 콘텐츠를 반환하고 있으므로 로드 밸런서가 정상 작동하고 있습니다.
haproxy.cfg 설정 파일 파라미터
HAProxy의 주요 로드 밸런싱 알고리즘을 살펴보겠습니다.
roundrobin— 기본 알고리즘으로, 요청을 서버에 순차적으로 분배합니다. 본 예제에서 이 방식을 사용했습니다.leastconn— 활성 연결 수가 가장 적은 서버를 선택합니다. 세션이 오래 유지되는 프로젝트에 권장됩니다.source— 사용자 IP 주소의 해시 값을 기반으로 서버를 선택합니다. 이 모드에서는 클라이언트 IP가 변하지 않는 한 항상 같은 웹 서버에 접속합니다.
설정 파일의 주요 파라미터를 자세히 살펴보겠습니다.
global 블록:
log— local0을 객체 값으로 하여 /dev/log에 로그를 기록합니다.chroot— 보안 설정으로, HAProxy를 지정된 디렉터리에 잠급니다.maxconn— 프로세스당 최대 동시 연결 수입니다.daemon— 프로세스를 데몬 형태로 실행합니다.
defaults 블록. 이 블록은 이후에 오는 모든 섹션에 적용되는 기본 파라미터를 설정합니다.
log— 로그 엔트리가 기록될 대상을 지정합니다(여기서 global은 global 섹션에서 설정한 파라미터를 사용한다는 의미).mode— 통신 프로토콜을 설정하며 tcp, http, health 중 하나의 값을 가집니다.retries— 장애 발생 시 서버 접속을 재시도하는 횟수입니다.option httplog— HAProxy가 HTTP 요청을 프록시할 때 사용되는 로그 형식입니다.option redispatch— 서버 장애 시 세션을 종료하고 다른 서버로 재분배할 수 있도록 허용합니다.contimeout— 서버와의 연결이 성공적으로 설정될 때까지의 최대 대기 시간입니다.
그 외에도 다양한 타임아웃 관련 파라미터들이 존재합니다.
HAProxy 통계 수집
설정 파일에 stats 블록을 추가합니다.
listen stats
bind :10001
stats enable
stats uri /haproxy_stats
stats auth admin:admin
각 항목에 대한 설명입니다.
bind— 통계를 확인할 수 있는 포트입니다.stats enable— 통계 보고 기능을 활성화합니다.stats uri— 통계 페이지 주소를 설정합니다.stats auth— 접속에 필요한 로그인 계정과 비밀번호입니다.
위에서 지정한 포트가 이미 사용 중이거나 마음에 들지 않는다면 원하는 임의의 TCP 포트를 지정할 수 있습니다.
방화벽에서 해당 포트의 들어오는 연결을 허용합니다.
firewall-cmd --permanent –add-port=10001/tcp
firewall-cmd –reload
HAProxy 리포트를 확인하려면 다음 링크로 접속합니다.
https://hostname_haproxy:10001/haproxy_stats
브라우저에서 로드 밸런서 IP 주소를 열고 F5 키를 계속 누르면 HAProxy 통계가 실시간으로 변경되는 것을 확인할 수 있습니다.
이 글에서는 HAProxy의 기본적인 설정 방법을 다뤘습니다. HAProxy 모듈은 이 외에도 다양한 활용 사례가 있습니다.
참고로 현재 구성에서는 로드 밸런싱을 담당하는 HAProxy 서버가 단일 장애점(SPOF)이 됩니다. 웹 서비스의 내결함성을 높이려면 HAProxy 서버를 하나 더 추가하고 Keepalived를 활용해 고가용성 로드 밸런서 구성을 구현할 수 있습니다. 그러면 다음과 같은 구조가 완성됩니다.
