Markdown Preview
HAProxy로 고가용성과 부하 분산 구성하기: 완벽 가이드
Frontmatter
HAProxy는 무료 오픈소스 로드밸런서로, TCP·HTTP 기반 애플리케이션에 고가용성과 부하 분산을 제공하며, 설치·설정·통계 대시보드 활용 방법을 상세히 안내한다.
들어가며
HAProxy(High Availability Proxy)는 무료 오픈소스 소프트웨어 로드 밸런서로, TCP 및 HTTP 기반 애플리케이션에 대한 고가용성, 부하 분산, 프록시 기능을 제공합니다. 특히 대규모 트래픽을 처리해야 하는 웹 서비스에서 널리 사용되며, GitHub, Twitter, Instagram 등 대형 서비스에서도 활용되고 있습니다.[1]
이전 포스팅에서 언급했듯이, 저희 OpenStack 환경에서는 컨트롤러를 이중화하여 구성했습니다. 이 이중화 구성의 핵심 역할을 담당하는 것이 바로 HAProxy입니다. HAProxy가 리버스 프록시(Reverse Proxy) 역할을 수행하여 여러 백엔드 서버로 트래픽을 분산시켜 줍니다.
이번 글에서는 HAProxy의 기본 개념부터 실제 설정 방법까지 상세히 다뤄보겠습니다.
HAProxy란?
HAProxy는 Scale-out을 위한 소프트웨어 로드 밸런서입니다.[1]
Scale-out이란?
서버를 횡으로 확장하여 부하를 분산하는 방식입니다. 동일한 사양의 서버를 여러 대 추가하여 처리량을 늘리는 것을 의미합니다. 반대로 Scale-up은 단일 서버의 사양(CPU, 메모리 등)을 높이는 방식입니다.
기존 하드웨어 로드 밸런서와의 비교
유형 | 동작 계층 | 로드 밸런싱 기준 | 프로토콜 |
L2 스위치 | 2계층 | MAC 주소 | Ethernet |
L3 스위치 | 3계층 | IP 주소 | IP |
L4 스위치 | 4계층 | IP + Port | TCP, UDP |
L7 스위치 | 7계층 | 애플리케이션 데이터 | HTTP, HTTPS, FTP |
HAProxy는 L4(TCP)와 L7(HTTP) 레벨에서 모두 동작할 수 있어 다양한 사용 사례에 유연하게 대응할 수 있습니다.
HAProxy 설치
먼저 시스템 패키지를 업데이트합니다.
sudo apt updateHAProxy 패키지를 설치합니다.
sudo apt install haproxy -y설치가 완료되면 기본 설정 파일이
/etc/haproxy/haproxy.cfg 경로에 생성됩니다.설정 파일 구조
HAProxy 설정 파일은 크게 5가지 섹션으로 구성됩니다.
섹션 | 설명 |
global | HAProxy 프로세스 전체에 적용되는 설정 |
defaults | frontend, backend에 상속되는 기본값 |
frontend | 클라이언트 요청을 수신하는 엔드포인트 정의 |
backend | 실제 요청을 처리할 서버 풀 정의 |
listen | frontend + backend를 하나로 결합한 간편 설정 |
일반적으로
global과 defaults는 기본값을 유지하고, frontend, backend, listen 섹션만 수정하여 프록시 규칙을 설정합니다.OpenStack 환경에서의 HAProxy 설정은 아래 공식 문서를 참고하시기 바랍니다.
global 섹션
global 섹션은 HAProxy 프로세스 전체에 영향을 미치는 설정을 정의합니다. 설정 파일 최상단에 위치하며, 최대 연결 수, 로그 설정, 실행 사용자 등을 지정합니다.global
maxconn 60000 # 최대 동시 연결 수
log 127.0.0.1 local0 # 로그 출력 설정
log 127.0.0.1 local1 notice
user haproxy # 실행 사용자
group haproxy # 실행 그룹
chroot /var/empty # chroot 경로 (보안 강화)주요 옵션 설명
- maxconn: HAProxy가 동시에 처리할 수 있는 최대 연결 수입니다. 서버 사양에 맞게 조절합니다.
- log: syslog 서버로 로그를 전송하는 설정입니다.
- user/group: HAProxy 프로세스가 실행될 사용자와 그룹을 지정합니다.
- chroot: 보안을 위해 HAProxy 프로세스를 특정 디렉토리로 격리합니다.
더 상세한 global 옵션은 HAProxy 공식 문서를 참고하세요.
defaults 섹션
defaults 섹션은 frontend와 backend에 공통으로 적용되는 기본 설정을 정의합니다. 중복 설정을 줄이고 설정 파일을 간결하게 유지할 수 있습니다.defaults
mode http # 기본 통신 모드
balance roundrobin # 기본 로드 밸런싱 알고리즘
# mode 상속받음
frontend website
bind :80
default_backend web_servers
# mode, balance 상속받음
backend web_servers
server s1 192.168.1.25:80
server s2 192.168.1.26:80
# mode 덮어쓰기
frontend mysql
mode tcp
bind :3306
default_backend mysql_servers
# mode, balance 덮어쓰기
backend mysql_servers
mode tcp
balance leastconn
server db1 192.168.1.29:3306
server db2 192.168.1.30:3306주요 옵션 설명
mode
통신 프로토콜을 정의합니다.
모드 | 설명 |
http | HTTP 프로토콜 처리 (L7) |
tcp | TCP 연결 프록시 (L4) |
balance
로드 밸런싱 알고리즘을 지정합니다.
backend 섹션에만 상속됩니다.알고리즘 | 설명 |
roundrobin | 서버에 순차적으로 요청 분배 (기본값) |
leastconn | 연결 수가 가장 적은 서버에 분배 |
source | 클라이언트 IP 기반 해시로 동일 서버 연결 유지 |
uri | 요청 URI 기반 해시 |
hdr | HTTP 헤더 기반 해시 |
frontend 섹션
frontend 섹션은 클라이언트가 연결할 엔드포인트를 정의합니다. IP 주소, 포트, SSL 인증서, 라우팅 규칙 등을 설정합니다.[2]기본 구조
frontend my_frontend
mode http
bind 192.168.1.5:80 # 특정 IP:Port에서 수신
bind 192.168.1.6:80 # 여러 bind 설정 가능
default_backend web_serversSSL 적용 예시
frontend ssl_frontend
mode http
bind :80
bind :443 ssl crt /etc/haproxy/certs/site.pem # SSL 인증서 적용
# HTTP → HTTPS 리다이렉트
http-request redirect scheme https unless { ssl_fc }
# 호스트명 기반 라우팅
use_backend foo_servers if { req.hdr(host) -i foo.com }
default_backend bar_serversIPv4/IPv6 동시 지원
frontend ipv4_v6_all
bind [::]:18080 v4v6 # IPv4와 IPv6 모두 수신
default_backend web_servers주요 옵션 설명
옵션 | 설명 |
bind | 수신할 IP:Port를 지정합니다. 여러 개 설정 가능합니다. |
use_backend | 조건에 따라 특정 backend로 라우팅합니다. |
default_backend | 기본으로 사용할 backend를 지정합니다. |
http-request redirect | HTTP 요청을 리다이렉트합니다. |
TCP 모드 사용 예시
MySQL이나 SSH 같은 TCP 기반 프로토콜도 프록시할 수 있습니다.
frontend foo.com
mode http
bind 192.168.1.5:80
default_backend foo_servers
frontend db.foo.com
mode tcp # TCP 모드 사용
bind 192.168.1.15:3306
default_backend db_servers주의: frontend와 backend의
mode는 반드시 일치해야 합니다. HTTP frontend는 HTTP backend로, TCP frontend는 TCP backend로 연결되어야 정상 동작합니다.backend 섹션
backend 섹션은 실제 요청을 처리할 서버 풀을 정의합니다.[3]기본 구조
backend web_servers
mode http
balance roundrobin
server s1 192.168.1.25:80 check # check: 헬스체크 활성화
server s2 192.168.1.26:80 check
server s3 192.168.1.27:80 check다중 backend 라우팅
frontend foo_and_bar
mode http
bind :80
use_backend foo_servers if { req.hdr(host) -i foo.com }
use_backend bar_servers if { req.hdr(host) -i bar.com }
backend foo_servers
mode http
balance roundrobin
server foo1 192.168.1.25:80 check
server foo2 192.168.1.26:80 check
server foo3 192.168.1.27:80 check
backend bar_servers
mode http
balance leastconn # 다른 알고리즘 사용
server bar1 192.168.1.35:80 check
server bar2 192.168.1.36:80 check
server bar3 192.168.1.37:80 checkserver 옵션
옵션 | 설명 |
check | 헬스체크를 활성화하여 비정상 서버를 자동 제외 |
weight N | 서버 가중치 설정 (기본값: 1) |
backup | 백업 서버로 지정 (다른 서버 장애 시에만 사용) |
maxconn N | 해당 서버의 최대 연결 수 제한 |
listen 섹션
listen 섹션은 frontend와 backend를 하나로 결합한 간편 설정입니다. 단순한 프록시 구성에 적합합니다.[4]listen load_balancer_cluster
mode tcp
bind :80
option tcplog
balance roundrobin
server lb1 192.168.1.25:80 check
server lb2 192.168.1.26:80 check언제 listen을 사용할까요?
- 단순한 TCP 포워딩
- 별도의 라우팅 규칙이 필요 없는 경우
- 설정을 간결하게 유지하고 싶을 때
복잡한 웹 서비스나 다중 도메인 라우팅이 필요한 경우에는 frontend + backend 조합을 사용하는 것이 좋습니다.
stats 대시보드
HAProxy는 서버 상태와 트래픽 지표를 실시간으로 모니터링할 수 있는 웹 대시보드를 제공합니다.[5]
listen stats
bind :8404
mode http
stats uri /stats # 대시보드 접속 경로
stats enable # 대시보드 활성화
stats refresh 3s # 자동 새로고침 간격
stats show-modules # 모듈 정보 표시
stats auth admin:admin # 기본 인증 설정 (사용자:비밀번호)주요 옵션 설명
옵션 | 설명 |
stats enable | 통계 대시보드를 활성화합니다. |
stats refresh | 브라우저에서 자동 새로고침 주기를 설정합니다. |
stats uri | 대시보드 접속 URL 경로를 지정합니다. |
stats auth | 기본 인증을 설정합니다. (운영 환경에서는 강력한 비밀번호 사용 권장) |
설정 후 브라우저에서
http://서버IP:8404/stats로 접속하면 대시보드를 확인할 수 있습니다.실제 설정 예시
저희 환경에서는 dmslab.xyz 도메인을 사용하고 있습니다. 서브도메인별로 다른 서비스로 라우팅하면서 SSL도 적용하는 설정 예시입니다.
frontend openstack_frontend
mode http
bind *:8080
bind *:8443 ssl crt /etc/haproxy/certs/
# 프록시 헤더 설정
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request add-header X-Forwarded-For %[src]
# HTTPS 리다이렉트
http-request redirect scheme https unless { ssl_fc }
# 서브도메인별 라우팅
use_backend openstack_backend if { ssl_fc_sni openstack.dmslab.xyz }
use_backend novnc_backend if { ssl_fc_sni novnc.dmslab.xyz }
use_backend s3_ceph_backend if { ssl_fc_sni -i -m reg ^(([a-z0-9-]+\.)?s3\.dmslab\.xyz)$ }
use_backend grafana_backend if { ssl_fc_sni gf.dmslab.xyz }
use_backend dashboard_backend if { ssl_fc_sni dashboard.dmslab.xyz }
default_backend openstack_backend설정 포인트 분석
- 포트 설정: 내부에서 Apache가 80/443 포트를 사용 중이므로 HAProxy는 8080/8443 포트를 사용합니다.
- 정규표현식을 활용한 라우팅: S3 호환을 위해
{버킷}.s3.dmslab.xyz형태의 URL을 처리해야 합니다.
{ ssl_fc_sni -i -m reg ^(([a-z0-9-]+\.)?s3\.dmslab\.xyz)$ }이 정규표현식은
s3.dmslab.xyz 앞에 어떤 버킷 이름이 오더라도 매칭됩니다.- 디렉토리 기반 SSL 인증서:
crt /etc/haproxy/certs/처럼 디렉토리를 지정하면 내부의.pem파일들이 도메인과 자동 매칭됩니다.
SSL 인증서 파일 구조
인증서 파일명을
도메인.pem 형태로 지정하면 해당 도메인과 자동으로 매칭됩니다.wildcard.s3.dmslab.xyz.pem→ *.s3.dmslab.xyz (와일드카드)
SSL 인증서 결합
HAProxy는 인증서(cert)와 개인키(key)가 하나의
.pem 파일로 결합된 형태를 사용합니다.cat fullchain.pem privkey.pem > domain.pem팁: Let's Encrypt(Certbot)로 발급받은 인증서를 사용하는 경우, 인증서 갱신 후 자동으로
.pem 파일을 생성하는 스크립트를 crontab에 등록해두면 관리가 편리합니다.자세한 SSL 설정 방법은 아래 문서를 참고하세요.
OpenStack 환경에서 Cloudflare DNS와 certbot을 활용한 SSL 인증서 자동 발급 및 갱신 방법
OpenStack 환경에서 Horizon 대시보드에 HTTPS를 적용하기 위해 certbot과 Cloudflare DNS 플러그인을 사용해 SSL 인증서를 자동으로 발급하고, NFS 공유와 HAProxy용 PEM 파일 병합 스크립트를 통해 두 컨트롤러에 동일하게 적용하며, Python 스크립트와 cron을 이용해 90일 만료 주기의 자동 갱신까지 완전 자동화하는 방법을 단계별로 설명한다.
/openstack-ssl
설정 파일 검증
HAProxy는 설정 파일의 문법 오류를 사전에 검사하는 기능을 제공합니다.
sudo haproxy -f /etc/haproxy/haproxy.cfg -cConfiguration file is valid 메시지가 출력되면 설정에 문법 오류가 없다는 의미입니다. 이제 HAProxy 서비스를 재시작해도 안전합니다.sudo systemctl restart haproxy마치며
HAProxy는 강력하고 유연한 로드 밸런서로, 적절히 설정하면 서비스의 가용성과 성능을 크게 향상시킬 수 있습니다. 이 글에서 다룬 기본 설정을 바탕으로 실제 환경에 맞게 커스터마이징하여 사용하시기 바랍니다.
문제가 발생했을 때는 다음 순서로 점검해보세요:
- 설정 파일 검증:
haproxy -c옵션으로 문법 오류 확인
- 로그 분석:
/var/log/haproxy.log확인
- 대시보드 확인: stats 페이지에서 서버 상태 점검
다음 포스팅에서는 HAProxy를 활용한 고가용성(HA) 구성에 대해 더 자세히 다뤄보겠습니다.