May 5, 2023

HAPROXY를 UBUNTU20.04에 설치

HAPROXY를 UBUNTU20.04에 설치

https://hbesthee.tistory.com/1861

https://lindarex.github.io/haproxy/ubuntu-haproxy-setting/
https://upcloud.com/community/tutorials/haproxy-load-balancer-centos/
https://www.keepalived.org/
https://findstar.pe.kr/2018/07/27/install-haproxy/

apt 를 이용한 설치

sudo apt install haproxy
haproxy -vv HA-Proxy version 2.0.13-2ubuntu0.1 2020/09/08 - https://haproxy.org/

apt를 이용하여 설치하면 Haproxy 버젼 2.0.13 이 설치 된다.

최신 버젼을 설치하기 위해서는 haproxy.org에서 최신 소스를 받아서 직접 빌드하고 설치를 해야 한다.


소스를 이용한 설치

빌드 패키지의 설치

아래와 같이 HAProxy를 빌드하는데 필요한 패키지들을 다운로드 받습니다.

sudo apt-get install -y build-essential libssl-dev libpcre2-dev libpcre3-dev  libsystemd-dev zlib1g-dev

HAProxy 최신 버젼의 소스 다운로드

haproxy.org 에서 최신 버젼과 해당 URL을 확인 후 다음과 같이 다운로드 합니다.

mkdir -p ~/work 
cd ~/work 
wget http://www.haproxy.org/download/2.4/src/haproxy-2.4.10.tar.gz

--2021-12-28 12:06:18--  http://www.haproxy.org/download/2.4/src/haproxy-2.4.10.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|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3803196 (3.6M) [application/x-tar]
Saving to: ‘haproxy-2.4.10.tar.gz’

haproxy-2.4.10.tar.g 100%[===================>]   3.63M  1.69MB/s    in 2.1s

2021-12-28 12:06:21 (1.69 MB/s) - ‘haproxy-2.4.10.tar.gz’ saved [3803196/3803196]

현재 작성 시점에서 haproxy의 최신버전은 2.4.10 LTS 이고 STABLE은 2.5.0 입니다.

2.4.10 LTS 버젼을 기준으로 작성합니다. (2026년까지 지원예정이므로 해당 버젼을 기준으로 설치합니다.)

Branch Release date End of life Latest version Changelog Links
2.6-dev ~2022-Q2 2027-Q2 (dev » LTS) 2.6-dev0 2021/11/23 git / web / dir / announce
2.5 2021-11-23 2023-Q1 (stable) 2.5.0 2021/11/23 git / web / dir / announce / bugs
2.4 2021-05-14 2026-Q2 (LTS) 2.4.10 2021/12/23 git / web / dir / announce / bugs
2.3 2020-11-05 2022-Q1 (stable) 2.3.16 2021/11/24 git / web / dir / announce / bugs
2.2 2020-07-07 2025-Q2 (LTS) 2.2.19 2021/11/29 git / web / dir / announce / bugs
2.0 2019-06-16 2024-Q2 (LTS) 2.0.26 2021/12/03 git / web / dir / announce / bugs
1.8 2017-11-26 2022-Q4 (critical fixes only) 1.8.30 2021/04/12 git / web / dir / announce / bugs
1.7 2016-11-25 2021-Q4 (critical fixes only) 1.7.14 2021/03/31 git / web / dir / announce / bugs
Hide/Show unmaintained

HAProxy 소스 빌드

다음과 같이 HAProxy 최신 소스의 압축을 풀고, 소스를 빌드합니다.

tar xf haproxy-2.4.10.tar.gz 
cd haproxy-2.4.10 
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'
install: creating directory '/usr/local/share/man/man1'
'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/proxy-protocol.txt' -> '/usr/local/doc/haproxy/proxy-protocol.txt'
'doc/seamless_reload.txt' -> '/usr/local/doc/haproxy/seamless_reload.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/linux-syn-cookies.txt' -> '/usr/local/doc/haproxy/linux-syn-cookies.txt'
'doc/SOCKS4.protocol.txt' -> '/usr/local/doc/haproxy/SOCKS4.protocol.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의 버전을 확인합니다.

root@k5w1hcd-154870:~/work/haproxy-2.4.10# /usr/local/sbin/haproxy -vv

HAProxy version 2.4.10-bedf277 2021/12/23 - 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.10.html
Running on: Linux 5.4.0-26-generic #30-Ubuntu SMP Mon Apr 20 16:58:30 UTC 2020 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 -PROCCTL +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=1).
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 mkdir -p /var/log/haproxy
sudo mkdir -p /etc/haproxy/certs
sudo mkdir -p /etc/haproxy/errors/
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'에 요청을 전송하고 있습니다.

update-rc.d haproxy remove (우분투에서는 update-rc.d 를 사용한다.)

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
sudo systemctl status haproxy

환경설정

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" 
        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
[ALERT]    (106289) : config : parsing [/etc/haproxy/haproxy.cfg:45] : unexpected keyword '[req.hdr(host),lower,map_dom(/etc/haproxy/domain2backend.map,default)]' after switching rule, only 'if' and 'unless' are allowed.
[ALERT]    (106289) : config : parsing [/etc/haproxy/haproxy.cfg:49] : 'bind :::443' : unable to stat SSL certificate from file '/etc/haproxy/ssl/' : No such file or directory.
[ALERT]    (106289) : config : parsing [/etc/haproxy/haproxy.cfg:56] : unexpected keyword '[ssl_fc_sni,lower,map_dom(/etc/haproxy/domain2backend.map,default)]' after switching rule, only 'if' and 'unless' are allowed.
[ALERT]    (106289) : config : Error(s) found in configuration file : /etc/haproxy/haproxy.cfg
[ALERT]    (106289) : config : Fatal errors found in configuration.

아직 SSL 설정과 omain2backend.map 파일 설정이 없기 때문에 에러가 난다. 이미 있는 경우 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 home1 192.168.56.204:8004 check
        server home2 192.168.56.205:8004 check 
backend backend_5
        balance roundrobin
        server home1 192.168.56.204:8005 check
        server home2 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/ ; 동적 추가에 대한 내용