본문 바로가기

OS/Linux

[Linux]Install HAProxy from source centos 7

Concept

간단하게 로드밸런서라고 생각하면 된다.

트래픽을 분산시키기 위해 사용하는 서비스로 TCP, HTTP을 제어한다. 

헬스 체크 및 트래픽양을 표현해주는 관리자 페이지도 제공하며 Keepalived와 함께 사용하여 서버 및 서비스의 HA 구성에 사용하게 된다.

Install Keepalived
2022.06.12 - [Linux] - [Linux]Install Keepalived from yum in centos 7

yum으로 설치하는 경우 최신 버전을 사용할 수 없으므로 소스 컴파일로 설치하는 것을 권장한다.


설치

소스 컴파일을 위한 패키지 설치

yum install -y gcc openssl pcre-static pcre-devel systemd-devel openssl-devel

Hapoxy 다운로드

Download HAProxy 
## version 2.4.3
wget <http://www.haproxy.org/download/2.4/src/haproxy-2.4.3.tar.gz>

## unzip
root@jv0536 [~/workspace]tar zxvf haproxy-2.4.3.tar.gz

Compile

## under 1.7 version
make TARGET=linux2628 USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1 USE_SYSTEMD=1

## over 2.0 version
make TARGET=linux-glibc USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1 USE_SYSTEMD=1

설치확인

## check compie option
root@jv0536 [~/workspace/haproxy-2.4.3]./haproxy -vv | grep -i systemd
  OPTIONS = USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1
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

## check version
root@jv0536 [~/workspace/haproxy-2.4.3]./haproxy -v
HAProxy version 2.4.3-4dd5a5a 2021/08/17 - <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.3.html>
Running on: Linux 3.10.0-1160.21.1.el7.x86_64 #1 SMP Tue Mar 16 18:28:22 UTC 2021 x86_64

서비스 등록

2022.06.10 - [Linux] - [Linux]소스 컴파일 후 systemctl 사용하기 (service 등록하기)
 

[Linux]소스 컴파일 후 systemctl 사용하기 (service 등록하기)

소스 컴파일로 Nginx, HAproxy 등의 서비스를 설치 한뒤 서비스에 등록해줘야 systemctl 명령어로 관리를 할 수 있다. Contents 서비스 파일 생성 : /usr/lib/systemd/system/서비스이름.service 서비스 파일만..

dewble.tistory.com

실행파일 복사

cp ~/haproxy-2.4.3/haproxy /usr/local/bin/

서비스파일 등록

/usr/lib/systemd/system/haproxy.service

config 참고

Description=HAProxy Load Balancer
After=network.target

[Service]
EnvironmentFile=-/etc/default/haproxy
EnvironmentFile=-/etc/sysconfig/haproxy
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "EXTRAOPTS=-S /run/haproxy-master.sock"
ExecStartPre=/usr/local/bin/haproxy -f /etc/haproxy/haproxy.cfg -c -q -S /run/haproxy-master.sock
ExecStart=/usr/local/bin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock
ExecReload=/usr/local/bin/haproxy -f /etc/haproxy/haproxy.cfg -c -q -S /run/haproxy-master.sock
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Restart=always
SuccessExitStatus=143
Type=notify

[Install]
WantedBy=multi-user.target

Config 설정 - Example

# 다음은 80 과 443 으로 haproxy 를 reverse proxy 형태로 구성하여 LB로 사용하는 설정이다.
global
    daemon

    # 연결할 수 있는 최대 connection 을 지정한다. 이걸 안하면 기본값이 2000 으로 설정된다.
    maxconn 81920

    # haproxy 프로세서를 구동할 user (gid/uid를 지정할 수도 있다.)
    user    haproxy

    # ssl 을 구성할 때 key size를 지정한다.
    tune.ssl.default-dh-param 2048

    # haproxy는 로그를 남기기 위해서 file io 를 직접 처리하지 않는다. rsyslog 로 UDP 전송을 한다.
    log 127.0.0.1 local0

    # ciphers 설정
    # WindowsXP SP3 IE7,8 호환이 필요하지 않을 경우 !3DES도 추가한다.
    ssl-default-bind-ciphers ECDH+AESGCM:ECDH+AES128:ECDH+AES256:DH+AES128:DH+AES256:DH+CAMELLIA128:DH+CAMELLIA256:DH+SEEDCBC:RSA:!aNULL:!MD5:!eNULL:!RC4

defaults

    # Haproxy 에서 log format 은 총 5가지 (default, tcp, http, clf, custom) 을 지원한다
    # 1. 기본적인 log format
    # datetime host process_name[pid]: Connect from source_ip:source_port to dest_ip:dest_port (frontend_name/mode)
    # ex) Feb  6 12:12:09 localhost haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 (www/HTTP)
    #
    # 2. `option tcplog` 가 지정된 경우
    # datetime host process_name[pid]: client_ip:client_port [accept_date] frontend_name backend_name/server_name tw/tc/tx bytes_read termination_state actionn/feconn/beconn/srv_conn/retries srv_queue/backend_queue
    # ex) Feb  6 12:12:56 localhost haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/0
    #
    # 3. `option httplog` 가 지정된 경우
    # HTTP 프록시를 구성하는 경우에 제일 많이 사용되는 로그 포맷
    # datetime host process_name[pid]: client_ip:client_port [request_date] frontend_name backend_name/server_name TR/Tw/Tc/Tr/Ta status_code bytes_read captured_request_cooie captured_response_cookie termination_state actionn/feconn/beconn/srv_conn/retries srv_queue/backend_queue {captured_request_headers} {captured_response_headers} "http_request"
    # ex)
    # Feb  6 12:14:14 localhost haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} {} "GET /index.html HTTP/1.1"
    #
    # 4. `log-format` 을 통해서 custom 구성을 한경우
    # `log-format` 을 지정하면 커스텀 로그 포맷 구성이 가능함
    # 자세한 변수는 <http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#8.2.4> 참고
    #
    # 5. clf 는 (Common Logging Format)
    #
    # 이설정파일에서는 custom log format 을 사용했다.
    log       global

## http 프로토콜을 사용하는 로드밸런싱 모드
#    mode      http
    option    httplog clf

    #Enable logging of null connections (헬스체크와 같이 시스템이 살아 있는지 확인하기 위해서 일정하게 접속하는 커넥션에 대한 로그 사용)
## Probe 같은 잡다한 기록을 log화 하지 않는다.
    option    dontlognull

    #Enable skip logging normal connection log 일반적인 http status 200 로그는 남기지 않는다.
    option    dontlog-normal

    #request-요청을 서버로 보낼 때 `X-Forwarded-For` 를 헤더에 추가한다
    option    forwardfor

    # 기본적으로 HAProxy 는 커넥션 유지 관점에서 keep-alive 모드로 동작을 하는데, 각각의 커넥션은 request-요청과 reponse-응답을 처리하고나서
    # 새로운 request을 받기까지 connection idle 상태(유휴상태)로 양쪽이 연결되어 있다.
    # 이 동작모드를 변경하려면 "option http-server-close" "option forceclose" "option httpclose" "option http-tunnel" 의 옵션이 가능한데,
    # "option http-server-close" 는 클라이언트 사이드에서 HTTP keep-alive를 유지하고 파이프라이닝을 지원하면서 서버 사이드에 커넥션을 닫는 형태를 설정한다.
    # 이는 클라이언트 사이드에서 최저 수준의 응답지연을 제공하고 "option forceclose" 와 비슷하게 서버사이드에서 리소스를 재활용할 수 있게 되어
    # backend 에서 빠르게 세션을 재사용할 수 있도록 해준다.
    option    http-server-close

    timeout   http-request  10s
    timeout   client        20s
    timeout   connect       4s
    timeout   server        30s
    timeout   http-keep-alive   10s

# haproxy 의 상태정보를 확인할 수 있는 기능을 활성화 한다. "stats"
# 이 포트는 외부에 노출되지 않도록 주의하자.
# 접근 가능한 사용자를 제한하기 위해서 auth 를 추가했다.
listen stats
    bind :9000 # Listen on localhost:9000
    stats enable  # Enable stats page
    stats realm Haproxy\\ Statistics  # Title text for popup window
    stats uri /haproxy_stats  # Stats URI
    stats auth    admin1:password1
    stats auth    admin2:password2

frontend www

    # 기본적으로 80 번을 listen 한다.
    bind *:80

    # https 지원을 위한 443 listen
    # cert 파일은 /etc/haproxy/certs 디렉토리에 넣는다.
    # 키 파일과 cert 파일을 하나로 합쳐서 넣으면 된다.
    bind *:443 ssl crt /etc/haproxy/certs

    maxconn 81920

    # 압축 알고리즘 gzip 적용
    compression algo gzip
    compression type text/plain application/json application/xml

    # ACL "deny_useragent" 선언
    # 보안취약점 스캔 툴 같은 agent 들을 막기 위한 list 파일을 구성했다.
    # -i 옵션은 대소문자 구분하지 않음
    # -f 는 파일에서 매칭
    acl deny_useragent hdr_sub(user-agent) -i -f /etc/haproxy/deny_useragent.list

    # Private Ip 대역 확인용 ACL "private-network" 선언
    # 같은 VPC 대역이라던가..
    acl private-network src 10.10.0.0/16

    http-request deny if deny_useragent

    # 모니터링을 위한 주소 설정
    monitor-uri /monitor

    # 모니터링 주소는 같은 private ip 대역이 아니라면 실패 처리
    monitor fail  if !private-network

    # log format 을 위해서 header 정보를 capture 한다. custom format %hr 에서 사용되며 delimiter : '|'로 구분된다.
    capture request header Host len 128
    capture request header User-Agent len 64
    capture request header Referrer len 64

    # 다음은 custom format 을 위한 지
    # %ci : client ip
    # %trl : local date time
    # %HM : HTTP method (ex GET)
    # %HU : HTTP request URI (ex: /foo?bar=baz)
    # %HV : HTTP version (ex: HTTP/1.1)
    # %ST : Status Code
    # %B : bytes_read
    # %hr : header values (host, agent, referrer) 위에서 capture 한 값들.
    # %s : server_name
    # %b : backend_name
    # %TR : time to receive the full request from 1st byte
    # %Tw : total time in milliseconds spent waiting in the various queues
    # %Tc : total time in milliseconds spent waiting for the connection to establish to the final server, including retries
    # %Tr : total time in milliseconds spent waiting for the server to send a full HTTP response, not counting data
    # %Ta : time the request remained active in haproxy, which is the total time in milliseconds elapsed between the first byte of the request was received and the last byte of response was sent
    # %ac : total number of concurrent connections on the process when the session was logged
    # %fc : total number of concurrent connections on the frontend when the session was logged
    # %bc : total number of concurrent connections handled by the backend when the session was logged
    # %sc : total number of concurrent connections still active on the server when the session was logged
    # %rc : the number of connection retries experienced by this session when trying to connect to the server
    log-format "%ci\\ [%trl]\\ %HM\\ \\"%HU\\"\\ \\"%HV\\"\\ %ST\\ %B\\ %hr\\ %s\\ %b\\ %TR/%Tw/%Tc/%Tr/%Ta\\ %ac/%fc/%bc/%sc/%rc"

    # 기본적으로 사용할 backend 를 지정한다.
    default_backend web-svr

backend web-svr

    # 로드 밸런싱을 라운드 로빈으로 지정한다. 이밖에도 leastconn 을 많이 지정하는것 같다.
    balance roundrobin

    # 연결할 서버들이 active health check를 지정한다. (nginx 와 가장큰 다른점이라고 생각된다. nginx 는 active health check 가 plus(유료)버전에서만 가능하다)
    option  httpchk HEAD /_health HTTP/1.1\\r\\nHost:\\ localhost

    # 에러 파일 설정
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http

    # backend 서버들로 request-요청 을 proxy 로 전달할 때 Protocol(https) 와 Port 정보를 함께 전달
    # X-Forwarded-For 는 앞의 option 으로 전달됨 (option forwardfor)
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }

    # 연결할 서버들의 리스트다. 3번 health check 가 실패하면 빼고, 2번 성공하면 다시 LB 대상에 포함시킨다.
    server  my-web-server-1-host   10.10.192.1:80  check fall 3 rise 2
    server  my-web-server-2-host   10.10.192.2:80  check fall 3 rise 2
    server  my-web-server-3-host   10.10.192.3:80  check fall 3 rise 2
    server  my-web-server-4-host   10.10.192.4:80  check fall 3 rise 2
    server  my-web-server-5-host   10.10.192.5:80  check fall 3 rise 2
    server  my-web-server-6-host   10.10.192.6:80  check fall 3 rise 2
    server  my-web-server-7-host   10.10.192.7:80  check fall 3 rise 2
    server  my-web-server-8-host   10.10.192.8:80  check fall 3 rise 2
    server  my-web-server-9-host   10.10.192.9:80  check fall 3 rise 2
    server  my-web-server-10-host   10.10.192.10:80  check fall 3 rise 2

문법체크

## 문법체크
/usr/local/bin/haproxy -f /etc/haproxy/haproxy.cfg -c
## 디버깅
/usr/local/bin/haproxy -f /etc/haproxy/haproxy.cfg

명령어 등록 (경로 상관없이 실행)

2022.06.08 - [Linux] - [Linux]경로 상관없이 명령어 실행하기
 

[Linux]경로 상관없이 명령어 실행하기

Purpose 소스코드로 설치한 서비스를 명령어를 입력하는 경로 상관없이 실행하기 위함 root@jv0535 [~]haproxy -v -bash: haproxy: command not found /root 경로에서 haproxy 명령어를 실행할 수 없다 Solution..

dewble.tistory.com

/etc/profile or ~/.bash_profile or ~/.bashrc

## haproxy 명령어 등록
PATH=$PATH:$HOME/bin:$HOME/workspace/haproxy-2.4.3

service 시작, 중지, 재시작

systemctl start haproxy

systemctl stop haproxy

## 스크립트 인식하기
systemctl daemon-reload

systemctl restart haproxy

systemctl enable haproxy
Created symlink from /etc/systemd/system/multi-user.target.wants/haproxy.service to /usr/lib/systemd/system/haproxy.service.

https://cbonte.github.io/haproxy-dconv/2.3/configuration.html