Skip to document
pieroot log
Markdown Preview

HAProxy로 고가용성과 부하 분산 구성하기: 완벽 가이드

Frontmatter

HAProxy는 무료 오픈소스 로드밸런서로, TCP·HTTP 기반 애플리케이션에 고가용성과 부하 분산을 제공하며, 설치·설정·통계 대시보드 활용 방법을 상세히 안내한다.

HAProxy로 고가용성과 부하 분산 구성하기: 완벽 가이드

들어가며

HAProxy(High Availability Proxy)는 무료 오픈소스 소프트웨어 로드 밸런서로, TCP 및 HTTP 기반 애플리케이션에 대한 고가용성, 부하 분산, 프록시 기능을 제공합니다. 특히 대규모 트래픽을 처리해야 하는 웹 서비스에서 널리 사용되며, GitHub, Twitter, Instagram 등 대형 서비스에서도 활용되고 있습니다.[1]
이전 포스팅에서 언급했듯이, 저희 OpenStack 환경에서는 컨트롤러를 이중화하여 구성했습니다. 이 이중화 구성의 핵심 역할을 담당하는 것이 바로 HAProxy입니다. HAProxy가 리버스 프록시(Reverse Proxy) 역할을 수행하여 여러 백엔드 서버로 트래픽을 분산시켜 줍니다.
이번 글에서는 HAProxy의 기본 개념부터 실제 설정 방법까지 상세히 다뤄보겠습니다.
HAProxy 리버스 프록시와 로드 밸런싱 구조
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 설치

먼저 시스템 패키지를 업데이트합니다.
shell
sudo apt update
HAProxy 패키지를 설치합니다.
shell
sudo apt install haproxy -y
설치가 완료되면 기본 설정 파일이 /etc/haproxy/haproxy.cfg 경로에 생성됩니다.
notion image

설정 파일 구조

HAProxy 설정 파일 섹션 구조
HAProxy 설정 파일 섹션 구조
HAProxy 설정 파일은 크게 5가지 섹션으로 구성됩니다.
섹션
설명
global
HAProxy 프로세스 전체에 적용되는 설정
defaults
frontend, backend에 상속되는 기본값
frontend
클라이언트 요청을 수신하는 엔드포인트 정의
backend
실제 요청을 처리할 서버 풀 정의
listen
frontend + backend를 하나로 결합한 간편 설정
일반적으로 global과 defaults는 기본값을 유지하고, frontend, backend, listen 섹션만 수정하여 프록시 규칙을 설정합니다.
OpenStack 환경에서의 HAProxy 설정은 아래 공식 문서를 참고하시기 바랍니다.

global 섹션

global 섹션은 HAProxy 프로세스 전체에 영향을 미치는 설정을 정의합니다. 설정 파일 최상단에 위치하며, 최대 연결 수, 로그 설정, 실행 사용자 등을 지정합니다.
bash
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에 공통으로 적용되는 기본 설정을 정의합니다. 중복 설정을 줄이고 설정 파일을 간결하게 유지할 수 있습니다.
bash
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]

기본 구조

bash
frontend my_frontend
  mode http
  bind 192.168.1.5:80        # 특정 IP:Port에서 수신
  bind 192.168.1.6:80        # 여러 bind 설정 가능
  default_backend web_servers

SSL 적용 예시

bash
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_servers

IPv4/IPv6 동시 지원

bash
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 기반 프로토콜도 프록시할 수 있습니다.
bash
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]

기본 구조

bash
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 라우팅

bash
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 check

server 옵션

옵션
설명
check
헬스체크를 활성화하여 비정상 서버를 자동 제외
weight N
서버 가중치 설정 (기본값: 1)
backup
백업 서버로 지정 (다른 서버 장애 시에만 사용)
maxconn N
해당 서버의 최대 연결 수 제한

listen 섹션

listen 섹션은 frontend와 backend를 하나로 결합한 간편 설정입니다. 단순한 프록시 구성에 적합합니다.[4]
bash
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]
bash
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도 적용하는 설정 예시입니다.
HAProxy frontend와 backend 라우팅 흐름
HAProxy frontend와 backend 라우팅 흐름
bash
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

설정 포인트 분석

  1. 포트 설정: 내부에서 Apache가 80/443 포트를 사용 중이므로 HAProxy는 8080/8443 포트를 사용합니다.
  1. 정규표현식을 활용한 라우팅: S3 호환을 위해 {버킷}.s3.dmslab.xyz 형태의 URL을 처리해야 합니다.
    1. bash
      { ssl_fc_sni -i -m reg ^(([a-z0-9-]+\.)?s3\.dmslab\.xyz)$ }
      이 정규표현식은 s3.dmslab.xyz 앞에 어떤 버킷 이름이 오더라도 매칭됩니다.
  1. 디렉토리 기반 SSL 인증서: crt /etc/haproxy/certs/ 처럼 디렉토리를 지정하면 내부의 .pem 파일들이 도메인과 자동 매칭됩니다.

SSL 인증서 파일 구조

notion image
인증서 파일명을 도메인.pem 형태로 지정하면 해당 도메인과 자동으로 매칭됩니다.

SSL 인증서 결합

HAProxy는 인증서(cert)와 개인키(key)가 하나의 .pem 파일로 결합된 형태를 사용합니다.
bash
cat fullchain.pem privkey.pem > domain.pem
💡
팁: Let's Encrypt(Certbot)로 발급받은 인증서를 사용하는 경우, 인증서 갱신 후 자동으로 .pem 파일을 생성하는 스크립트를 crontab에 등록해두면 관리가 편리합니다.
자세한 SSL 설정 방법은 아래 문서를 참고하세요.
notion image
OpenStack 환경에서 Cloudflare DNS와 certbot을 활용한 SSL 인증서 자동 발급 및 갱신 방법
OpenStack 환경에서 Horizon 대시보드에 HTTPS를 적용하기 위해 certbot과 Cloudflare DNS 플러그인을 사용해 SSL 인증서를 자동으로 발급하고, NFS 공유와 HAProxy용 PEM 파일 병합 스크립트를 통해 두 컨트롤러에 동일하게 적용하며, Python 스크립트와 cron을 이용해 90일 만료 주기의 자동 갱신까지 완전 자동화하는 방법을 단계별로 설명한다.

설정 파일 검증

HAProxy 운영 점검 흐름
HAProxy 운영 점검 흐름
HAProxy는 설정 파일의 문법 오류를 사전에 검사하는 기능을 제공합니다.
shell
sudo haproxy -f /etc/haproxy/haproxy.cfg -c
notion image
Configuration file is valid 메시지가 출력되면 설정에 문법 오류가 없다는 의미입니다. 이제 HAProxy 서비스를 재시작해도 안전합니다.
shell
sudo systemctl restart haproxy

마치며

HAProxy는 강력하고 유연한 로드 밸런서로, 적절히 설정하면 서비스의 가용성과 성능을 크게 향상시킬 수 있습니다. 이 글에서 다룬 기본 설정을 바탕으로 실제 환경에 맞게 커스터마이징하여 사용하시기 바랍니다.
문제가 발생했을 때는 다음 순서로 점검해보세요:
  1. 설정 파일 검증: haproxy -c 옵션으로 문법 오류 확인
  1. 로그 분석: /var/log/haproxy.log 확인
  1. 대시보드 확인: stats 페이지에서 서버 상태 점검
다음 포스팅에서는 HAProxy를 활용한 고가용성(HA) 구성에 대해 더 자세히 다뤄보겠습니다.