---
title: "HAProxy로 고가용성과 부하 분산 구성하기: 완벽 가이드"
description: "HAProxy는 고가용성과 부하 분산을 위한 무료 오픈소스 소프트웨어 로드 밸런서로, TCP 및 HTTP 기반 애플리케이션에 적합하다. HAProxy의 설치 및 설정 방법, 각 섹션의 구조와 주요 옵션을 설명하며, SSL 인증서 적용 및 설정 파일 검증 방법도 다룬다. 적절한 설정을 통해 서비스의 가용성과 성능을 향상시킬 수 있다."
date: "2025-06-23"
last_modified: "2026-05-15T08:36:00.000Z"
type: "Post"
tags:
  - "haproxy"
  - "High Availability"
  - "load balancing"
  - "Docs"
  - "openstack"
  - "network"
categories:
  - "📗 Docs"
canonical_url: "https://blog.pieroot.xyz/haproxy-ha-guide"
markdown_url: "https://blog.pieroot.xyz/haproxy-ha-guide.md"
---

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

HAProxy는 고가용성과 부하 분산을 위한 무료 오픈소스 소프트웨어 로드 밸런서로, TCP 및 HTTP 기반 애플리케이션에 적합하다. HAProxy의 설치 및 설정 방법, 각 섹션의 구조와 주요 옵션을 설명하며, SSL 인증서 적용 및 설정 파일 검증 방법도 다룬다. 적절한 설정을 통해 서비스의 가용성과 성능을 향상시킬 수 있다.

## 들어가며

HAProxy(High Availability Proxy)는 **무료 오픈소스 소프트웨어 로드 밸런서**로, TCP 및 HTTP 기반 애플리케이션에 대한 고가용성, 부하 분산, 프록시 기능을 제공합니다. 특히 대규모 트래픽을 처리해야 하는 웹 서비스에서 널리 사용되며, GitHub, Twitter, Instagram 등 대형 서비스에서도 활용되고 있습니다.[\[1\]](https://velog.io/@wanny328/Linux-HAproxy-%EC%82%AC%EC%9A%A9%EB%B2%95)

이전 포스팅에서 언급했듯이, 저희 OpenStack 환경에서는 컨트롤러를 이중화하여 구성했습니다. 이 이중화 구성의 핵심 역할을 담당하는 것이 바로 HAProxy입니다. HAProxy가 **리버스 프록시(Reverse Proxy)** 역할을 수행하여 여러 백엔드 서버로 트래픽을 분산시켜 줍니다.

이번 글에서는 HAProxy의 기본 개념부터 실제 설정 방법까지 상세히 다뤄보겠습니다.

![HAProxy 리버스 프록시와 로드 밸런싱 구조](https://blog.pieroot.xyz/api/image-proxy?id=280a8401-27de-437a-a8ec-658dcfbd6d91&kind=s3&pageId=21b067c0-15d0-80c8-bf6f-c06e53130ef0&source=block&blockId=17b652eb-c8a2-475d-abc7-258de6526ea5)

---

### HAProxy란?

HAProxy는 **Scale-out을 위한 소프트웨어 로드 밸런서**입니다.[\[1\]](https://velog.io/@wanny328/Linux-HAproxy-%EC%82%AC%EC%9A%A9%EB%B2%95)

> **Scale-out이란?**
> 
> 서버를 횡으로 확장하여 부하를 분산하는 방식입니다. 동일한 사양의 서버를 여러 대 추가하여 처리량을 늘리는 것을 의미합니다. 반대로 **Scale-up**은 단일 서버의 사양(CPU, 메모리 등)을 높이는 방식입니다.

#### 기존 하드웨어 로드 밸런서와의 비교

HAProxy는 **L4(TCP)와 L7(HTTP) 레벨**에서 모두 동작할 수 있어 다양한 사용 사례에 유연하게 대응할 수 있습니다.

---

### HAProxy 설치

먼저 시스템 패키지를 업데이트합니다.

```shell
sudo apt update
```

HAProxy 패키지를 설치합니다.

```shell
sudo apt install haproxy -y
```

설치가 완료되면 기본 설정 파일이 `/etc/haproxy/haproxy.cfg` 경로에 생성됩니다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=0b7fc9cf-8def-4944-9436-adeb59985c0e&kind=s3&pageId=21b067c0-15d0-80c8-bf6f-c06e53130ef0&source=block&blockId=21b067c0-15d0-801f-94a6-e3b4f334baf3)

---

### 설정 파일 구조

![HAProxy 설정 파일 섹션 구조](https://blog.pieroot.xyz/api/image-proxy?id=2360a4f4-8390-4bbd-bf86-85601e2013f3&kind=s3&pageId=21b067c0-15d0-80c8-bf6f-c06e53130ef0&source=block&blockId=d76600cf-ab21-4cff-9d7c-127a3f0d8f0b)

HAProxy 설정 파일은 크게 **5가지 섹션**으로 구성됩니다.

일반적으로 `global`과 `defaults`는 기본값을 유지하고, `frontend`, `backend`, `listen` 섹션만 수정하여 프록시 규칙을 설정합니다.

OpenStack 환경에서의 HAProxy 설정은 아래 공식 문서를 참고하시기 바랍니다.

[OpenStack High Availability Guide &#8212; openstackhaguide 0.0.1.dev853 documentation](https://docs.openstack.org/ha-guide/)

[Configuring stateless services &#8212; openstackhaguide 0.0.1.dev853 documentation](https://docs.openstack.org/ha-guide/control-plane-stateless.html#load-balancer)

---

### 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 공식 문서](https://docs.haproxy.org/3.1/configuration.html#3)를 참고하세요.

[HAProxy Enterprise Documentation  version 3.3r1 (1.0.0-375.869) - Configuration Manual](https://www.haproxy.com/documentation/haproxy-configuration-manual/latest/#3)

---

### 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**

통신 프로토콜을 정의합니다.

**balance**

로드 밸런싱 알고리즘을 지정합니다. `backend` 섹션에만 상속됩니다.

---

### frontend 섹션

`frontend` 섹션은 **클라이언트가 연결할 엔드포인트**를 정의합니다. IP 주소, 포트, SSL 인증서, 라우팅 규칙 등을 설정합니다.[\[2\]](https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/configuration-basics/frontends/)

#### 기본 구조

```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
```

#### 주요 옵션 설명

#### 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\]](https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/configuration-basics/backends/)

#### 기본 구조

```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 옵션

---

### listen 섹션

`listen` 섹션은 **frontend와 backend를 하나로 결합**한 간편 설정입니다. 단순한 프록시 구성에 적합합니다.[\[4\]](https://stackoverflow.com/questions/39209917/difference-between-frontend-backend-and-listen-in-haproxy)

```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\]](https://puffinknight.tistory.com/260)

```bash
listen stats
  bind :8404
  mode http
  stats uri /stats           # 대시보드 접속 경로
  stats enable               # 대시보드 활성화
  stats refresh 3s           # 자동 새로고침 간격
  stats show-modules         # 모듈 정보 표시
  stats auth admin:admin     # 기본 인증 설정 (사용자:비밀번호)
```

#### 주요 옵션 설명

설정 후 브라우저에서 [`http://서버IP:8404/stats`](http://xn--ip-v41jw5m:8404/stats)로 접속하면 대시보드를 확인할 수 있습니다.

---

### 실제 설정 예시

저희 환경에서는 [dmslab.xyz](http://dmslab.xyz/) 도메인을 사용하고 있습니다. 서브도메인별로 다른 서비스로 라우팅하면서 SSL도 적용하는 설정 예시입니다.

![HAProxy frontend와 backend 라우팅 흐름](https://blog.pieroot.xyz/api/image-proxy?id=be233571-0b72-40d3-8815-130b6228c6b6&kind=s3&pageId=21b067c0-15d0-80c8-bf6f-c06e53130ef0&source=block&blockId=7e355ddc-6c2b-4608-88ef-49b2434816f5)

```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`](http://s3.dmslab.xyz/) 형태의 URL을 처리해야 합니다.
```bash
{ ssl_fc_sni -i -m reg ^(([a-z0-9-]+\.)?s3\.dmslab\.xyz)$ }
```
이 정규표현식은 [`s3.dmslab.xyz`](http://s3.dmslab.xyz/) 앞에 어떤 버킷 이름이 오더라도 매칭됩니다.

1. **디렉토리 기반 SSL 인증서**: `crt /etc/haproxy/certs/` 처럼 디렉토리를 지정하면 내부의 `.pem` 파일들이 도메인과 자동 매칭됩니다.

#### SSL 인증서 파일 구조

![image](https://blog.pieroot.xyz/api/image-proxy?id=beb075a9-35b6-4348-b2e1-2360bc970cb5&kind=s3&pageId=21b067c0-15d0-80c8-bf6f-c06e53130ef0&source=block&blockId=30765039-3f9b-4137-9088-3190499c0c10)

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

- [`openstack.dmslab.xyz`](http://openstack.dmslab.xyz/)`.pem` → [openstack.dmslab.xyz](http://openstack.dmslab.xyz/)

- [`wildcard.s3.dmslab.xyz`](http://wildcard.s3.dmslab.xyz/)`.pem` → \*.[s3.dmslab.xyz](http://s3.dmslab.xyz/) (와일드카드)

#### SSL 인증서 결합

HAProxy는 인증서(cert)와 개인키(key)가 **하나의 ****`.pem`**** 파일로 결합**된 형태를 사용합니다.

```bash
cat fullchain.pem privkey.pem > domain.pem
```

> **팁**: Let's Encrypt(Certbot)로 발급받은 인증서를 사용하는 경우, 인증서 갱신 후 자동으로 `.pem` 파일을 생성하는 스크립트를 crontab에 등록해두면 관리가 편리합니다.

자세한 SSL 설정 방법은 아래 문서를 참고하세요.

![image](https://blog.pieroot.xyz/api/image-proxy?id=f1d8aaea-9b3e-4380-a0ca-2c352476ffed&kind=s3&pageId=21b067c0-15d0-80c8-bf6f-c06e53130ef0&source=block&blockId=d885edb7-8e34-4fe8-98de-99b99ae7d6fa)

[https://blog.pieroot.xyz/ssl-setting](https://blog.pieroot.xyz/ssl-setting)

---

### 설정 파일 검증

![HAProxy 운영 점검 흐름](https://blog.pieroot.xyz/api/image-proxy?id=734e2f5e-58c5-4398-b824-003e26b0aea3&kind=s3&pageId=21b067c0-15d0-80c8-bf6f-c06e53130ef0&source=block&blockId=4c7915b1-3f8a-438b-99f1-c4cb03b43be9)

HAProxy는 설정 파일의 문법 오류를 사전에 검사하는 기능을 제공합니다.

```shell
sudo haproxy -f /etc/haproxy/haproxy.cfg -c
```

![image](https://blog.pieroot.xyz/api/image-proxy?id=0fc6ed1c-3517-4fcc-b519-d70ef0a8fccd&kind=s3&pageId=21b067c0-15d0-80c8-bf6f-c06e53130ef0&source=block&blockId=aba332ac-6061-4f80-9f53-c093eda03f9b)

**`Configuration file is valid`** 메시지가 출력되면 설정에 문법 오류가 없다는 의미입니다. 이제 HAProxy 서비스를 재시작해도 안전합니다.

```shell
sudo systemctl restart haproxy
```

---

### 마치며

HAProxy는 강력하고 유연한 로드 밸런서로, 적절히 설정하면 서비스의 가용성과 성능을 크게 향상시킬 수 있습니다. 이 글에서 다룬 기본 설정을 바탕으로 실제 환경에 맞게 커스터마이징하여 사용하시기 바랍니다.

문제가 발생했을 때는 다음 순서로 점검해보세요:

1. **설정 파일 검증**: `haproxy -c` 옵션으로 문법 오류 확인

1. **로그 분석**: `/var/log/haproxy.log` 확인

1. **대시보드 확인**: stats 페이지에서 서버 상태 점검

다음 포스팅에서는 HAProxy를 활용한 고가용성(HA) 구성에 대해 더 자세히 다뤄보겠습니다.
