Ubuntu 20.04 호스트에 HAProxy를 설치하고 운영하는 것에 대하여 정리한 문서입니다.
HAProxy 설치하기
HAProxy를 Ubuntu에서 설치하는데는 크게 두 가지 방법이 있습니다. "apt"을 이용하는 방법과 소스를 이용하여 직접 빌드하고 설치하는 방법이 있습니다.
본 문서에서는 "HAProxy" 최신 소스를 이용하여 직접 설치하는 방법에 대하여 주로 설명합니다.
apt 를 통한 간편 설치
"apt" 명령을 이용해 haproxy 패키지를 손쉽게 설치할 수 있습니다.
$ sudo apt install haproxy
하지만 위와 같이 설치하면, 2.0.13 버전이 설치됩니다.
$ haproxy -vv
HA-Proxy version 2.0.13-2ubuntu0.1 2020/09/08 - https://haproxy.org/
가장 최신 버전을 설치하기 위해서는 "haproxy.org":http://www.haproxy.org/ 에서 최신 소스를 받아서 직접 빌드하고 설치를 해야만 합니다.
소스를 이용한 직접 빌드 설치
빌드를 위한 패키지 설치
아래와 같이 HAProxy를 빌드하는데 필요한 패키지들을 다운로드 받습니다.
$ sudo apt-get install -y build-essential \
libssl-dev \
libpcre2-dev libpcre3-dev \
libsystemd-dev \
zlib1g-dev
HAProxy 최신 소스 다운로드
"haproxy.org":http://www.haproxy.org/ 에서 최신 소스 URL을 확인하고, 아래와 같이 다운로드 받습니다.
본 문서를 작성하는 시점에서 haproxy의 최신버전은 2.4.2 입니다.
$ mkdir -p ~/work ; cd ~/work
$ wget https://www.haproxy.org/download/2.4/src/haproxy-2.4.2.tar.gz
--2021-07-27 16:46:06-- https://www.haproxy.org/download/2.4/src/haproxy-2.4.2.tar.gz
Resolving www.haproxy.org (www.haproxy.org)... 51.15.8.218, 2001:bc8:35ee:100::1
Connecting to www.haproxy.org (www.haproxy.org)|51.15.8.218|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3579220 (3.4M) [application/x-tar]
Saving to: ‘haproxy-2.4.2.tar.gz’
haproxy-2.4.2.tar.gz 100%[=================================>] 3.41M 1.93MB/s in 1.8s
2021-07-27 16:46:10 (1.93 MB/s) - ‘haproxy-2.4.2.tar.gz’ saved [3579220/3579220]
HAProxy 소스 빌드
다음과 같이 HAProxy 최신 소스의 압축을 풀고, 소스를 빌드합니다.
# tar xf haproxy-2.4.2.tar.gz && cd haproxy-2.4.2
# make TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1
HAProxy 2.0 부터는 "linux2628" 대신에 "linux-glibc" 로 "TARGET"이 변경됩니다.
빌드된 HAProxy 소스를 다음과 같이 설치합니다.
$ sudo make install
`haproxy' -> `/usr/local/sbin/haproxy'
`doc/haproxy.1' -> `/usr/local/share/man/man1/haproxy.1'
install: creating directory `/usr/local/doc'
install: creating directory `/usr/local/doc/haproxy'
`doc/configuration.txt' -> `/usr/local/doc/haproxy/configuration.txt'
`doc/management.txt' -> `/usr/local/doc/haproxy/management.txt'
`doc/architecture.txt' -> `/usr/local/doc/haproxy/architecture.txt'
`doc/peers-v2.0.txt' -> `/usr/local/doc/haproxy/peers-v2.0.txt'
`doc/regression-testing.txt' -> `/usr/local/doc/haproxy/regression-testing.txt'
`doc/cookie-options.txt' -> `/usr/local/doc/haproxy/cookie-options.txt'
`doc/lua.txt' -> `/usr/local/doc/haproxy/lua.txt'
`doc/WURFL-device-detection.txt' -> `/usr/local/doc/haproxy/WURFL-device-detection.txt'
`doc/proxy-protocol.txt' -> `/usr/local/doc/haproxy/proxy-protocol.txt'
`doc/linux-syn-cookies.txt' -> `/usr/local/doc/haproxy/linux-syn-cookies.txt'
`doc/network-namespaces.txt' -> `/usr/local/doc/haproxy/network-namespaces.txt'
`doc/DeviceAtlas-device-detection.txt' -> `/usr/local/doc/haproxy/DeviceAtlas-device-detection.txt'
`doc/51Degrees-device-detection.txt' -> `/usr/local/doc/haproxy/51Degrees-device-detection.txt'
`doc/netscaler-client-ip-insertion-protocol.txt' -> `/usr/local/doc/haproxy/netscaler-client-ip-insertion-protocol.txt'
`doc/peers.txt' -> `/usr/local/doc/haproxy/peers.txt'
`doc/close-options.txt' -> `/usr/local/doc/haproxy/close-options.txt'
`doc/SPOE.txt' -> `/usr/local/doc/haproxy/SPOE.txt'
`doc/intro.txt' -> `/usr/local/doc/haproxy/intro.txt'
기본적인 설치가 완료된 후에 다음과 같이 설치된 haproxy의 버전을 확인합니다.
$ /usr/local/sbin/haproxy -vv
HAProxy version 2.4.2-553dee3 2021/07/07 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.2.html
Running on: Linux 5.8.0-63-generic #71~20.04.1-Ubuntu SMP Thu Jul 15 17:46:08 UTC 2021 x86_64
Build options :
TARGET = linux-glibc
CPU = generic
CC = cc
CFLAGS = -O2 -g -Wall -Wextra -Wdeclaration-after-statement -fwrapv -Wno-address-of-packed-member -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered -Wno-missing-field-initializers -Wno-cast-function-type -Wtype-limits -Wshift-negative-value -Wshift-overflow=2 -Wduplicated-cond -Wnull-dereference
OPTIONS = USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1
DEBUG =
Feature list : +EPOLL -KQUEUE +NETFILTER +PCRE -PCRE_JIT -PCRE2 -PCRE2_JIT +POLL -PRIVATE_CACHE +THREAD -PTHREAD_PSHARED +BACKTRACE -STATIC_PCRE -STATIC_PCRE2 +TPROXY +LINUX_TPROXY +LINUX_SPLICE +LIBCRYPT +CRYPT_H +GETADDRINFO +OPENSSL -LUA +FUTEX +ACCEPT4 -CLOSEFROM +ZLIB -SLZ +CPU_AFFINITY +TFO +NS +DL +RT -DEVICEATLAS -51DEGREES -WURFL +SYSTEMD -OBSOLETE_LINKER +PRCTL +THREAD_DUMP -EVPORTS -OT -QUIC -PROMEX -MEMORY_PROFILING
Default settings :
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with multi-threading support (MAX_THREADS=64, default=8).
Built with OpenSSL version : OpenSSL 1.1.1f 31 Mar 2020
Running on OpenSSL version : OpenSSL 1.1.1f 31 Mar 2020
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
Built with network namespace support.
Built with zlib version : 1.2.11
Running on zlib version : 1.2.11
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE version : 8.39 2016-06-14
Running on PCRE version : 8.39 2016-06-14
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Encrypted password support via crypt(3): yes
Built with gcc compiler version 9.3.0
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|CLEAN_ABRT|HOL_RISK|NO_UPG
fcgi : mode=HTTP side=BE mux=FCGI flags=HTX|HOL_RISK|NO_UPG
<default> : mode=HTTP side=FE|BE mux=H1 flags=HTX
h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG
<default> : mode=TCP side=FE|BE mux=PASS flags=
none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG
Available services : none
Available filters :
[SPOE] spoe
[CACHE] cache
[FCGI] fcgi-app
[COMP] compression
[TRACE] trace
HAProxy 서비스를 정상적으로 실행하기 위해서는 haproxy 계정을 시스템 계정으로 등록되어 있어야 합니다.
다음과 같이 "haproxy" 계정을 등록합니다.
$ sudo groupadd --gid 980 haproxy ; \
sudo useradd --gid 980 --uid 980 -r haproxy
HAProxy 설정 파일을 초기화합니다.
$ sudo mkdir -p /etc/haproxy \
&& sudo touch /etc/haproxy/haproxy.cfg \
&& sudo touch /etc/haproxy/domain2backend.map \
&& sudo chown -R haproxy:haproxy /etc/haproxy/
HAProxy 라이브러리 디렉토리 및 상태 파일을 초기화합니다.
$ sudo mkdir -p /var/lib/haproxy \
&& sudo touch /var/lib/haproxy/stats \
&& sudo chown -R haproxy:haproxy /var/lib/haproxy
"haproxy"에 대한 심볼릭 링크를 설정합니다.
$ sudo ln -s /usr/local/sbin/haproxy /usr/sbin/haproxy
HAProxy 서비스를 설치합니다.
$ chkconfig haproxy off # 기존 설치된 설정 제거
알림: 'systemctl disable haproxy.service'에 요청을 전송하고 있습니다.
$ sudo rm -f /etc/init.d/haproxy
$ cd ~/work/haproxy-2.4.2/admin/systemd
$ make
$ sudo cp haproxy.service /lib/systemd/system/
$ sudo systemctl daemon-reload ; sudo systemctl enable haproxy
Created symlink from /etc/systemd/system/multi-user.target.wants/haproxy.service to /usr/lib/systemd/system/haproxy.service.
$ systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
Active: inactive (dead)
환경설정
HAPorxy 기본 설정
일반적으로 "home1.wb.com", "home2.wb.com"와 같이 두 도메인에 대한 매핑 설정을 위하여 아래와 같이 "haproxy.cfg" 파일을 작성합니다.
$ vi /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2 info
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
stats socket /var/run/haproxy.sock mode 666 level admin
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
#no option http-use-htx # HTTP2 표준처럼 헤더를 모두 lower로 처리하는 것 방지
option forwardfor
option httplog
option dontlognull
option http-server-close
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
listen stats
bind :::8888 v4v6
mode http
stats enable
stats hide-version
stats uri /
stats realm Haproxy\ Statistics
stats auth hunature:bns0705
frontend main
bind :::80 v4v6
option http-server-close
use_backend %[req.hdr(host),lower,map_dom(/etc/haproxy/domain2backend.map,default)]
default_backend default
frontend https-in
bind :::443 v4v6 ssl crt /etc/haproxy/ssl/ ciphers !EDH:!RC4:!ADH:!DSS:HIGH:+AES128:+AES256-SHA256:+AES128-SHA256:+SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
mode http
option forwardfor
option http-server-close
#http-response add-header Strict-Transport-Security "max-age=31536000; includeSubDomains"
#http-response add-header Strict-Transport-Security "max-age=31536000"
#http-response add-header X-Frame-Option "DENY"
use_backend %[ssl_fc_sni,lower,map_dom(/etc/haproxy/domain2backend.map,default)]
default_backend default
backend default
balance roundrobin
server home1 192.168.0.10:8080 check
server home2 192.168.0.11:8080 check
환경설정값이 유효한지 확인한다.
$ /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c
Configuration file is valid
HAProxy 서비스를 시작합니다.
$ sudo systemctl start haproxy
서비스가 정상적으로 구동하고 있는지 *:8888 포트로 접속하여 확인합니다.
동적으로 도메인 매핑 추가하는 방법
HAProxy를 이용하여 서비스해야할 backend 및 도메인이 동적으로 변경된다면 앞서 작성한 기본 설정과 같은 정적 구성으로는 불가능합니다.
동적으로 도메인을 매핑하여 처리하기 위해서는 "frontend main" 단에서 "acl" 및 "use_backend" 항목들을 다음과 같이 변경하고, 도메인에 대한 실질적인 매핑은 설정한 매핑 파일에 설정하여 동적으로 동작할 수 있도록 합니다.
frontend main
bind :::80 v4v6
option http-server-close
use_backend %[req.hdr(host),lower,map_dom(/etc/haproxy/domain2backend.map,default)]
default_backend default
하지만, 도메인에 매핑될 backend 정보가 변경되면, "haproxy.cfg" 파일에 추가해 줄 수밖에는 없습니다.
backend backend_4
balance roundrobin
server server1 192.168.56.204:8004 check
server server2 192.168.56.205:8004 check
backend backend_5
balance roundrobin
server server1 192.168.56.204:8005 check
server server2 192.168.56.205:8005 check
haproxy.cfg에서 설정한 것과 같이, 도메인별 매핑을 위한 파일(domain2backend.map)을 다음과 같이 작성합니다.
$ vi /etc/haproxy/domain2backend.map
#domainname backendname
home1.hbesthee.com backend_1
home2.hbesthee.com backend_2
test4.hbesthee.com backend_4
shop5.hbesthee.com backend_5
위와 같이 "haproxy.cfg"에 신규 backend를 추가하고 도메인별 매핑을 위한 파일(domain2backend.map)에 신규 도메인을 추가한 이후에는 HAProxy 서비스를 재시작하지 않고, 동적으로 설정 다시 읽기는 다음과 같이 수행합니다.
$ sudo systemctl reload haproxy
위와 같이 하면 서비스의 중단없이 새로운 도메인 매핑이 바로 적용되어 신규 도메인으로의 연결도 정상적으로 연결이 가능합니다.
HAProxy 설치 관련 참고글
- "[CentOS] HAProxy 설치&실습 (VirtualBox환경)":http://blog.naver.com/wideeyed/221296863845
- "CentOS - HAProxy 설치":https://sseungshin.tistory.com/77 ; 아래의 번역본
- "Getting started with HAProxy: Install from source code":https://midiroot.com/post/haproxy-getting-started/
- "How to install HAProxy load balancer on CentOS":https://upcloud.com/community/tutorials/haproxy-load-balancer-centos/
- "L4/L7 스위치의 대안, 오픈 소스 로드 밸런서 HAProxy":https://d2.naver.com/helloworld/284659
- "Web Application Name to Backend Mapping in HAProxy":https://www.haproxy.com/blog/web-application-name-to-backend-mapping-in-haproxy/
- "Web Application Name to Backend Mapping in HAProxy":https://www.haproxy.com/blog/web-application-name-to-backend-mapping-in-haproxy/ ; 하지만, backend 동적 추가에 대한 문제가 있음
- "Dynamic Scaling for Microservices with the HAProxy Runtime API":https://www.haproxy.com/blog/dynamic-scaling-for-microservices-with-runtime-api/ ; 동적 추가에 대한 내용
'Linux,Unix,BSD' 카테고리의 다른 글
[vim] 자주 사용하는 설정: 탭크기, 줄번호 등 (0) | 2021.08.11 |
---|---|
HAProxy http -> https로 전달 설정하기 (0) | 2021.08.07 |
[라즈베리파이] 라즈비안 설치 후 해야 할 작업 정리 (0) | 2021.07.28 |
HAProxy-2.4.2 설치하기 on CentOS8 (0) | 2021.07.12 |
[shell] root 권한으로 pipe 처리하기 (파일에 내용 추가하기) (0) | 2021.05.25 |