May 5, 2023

HAPROXY CONFIG 분석

HAPROXY CONFIG 분석

HAPRXY 환경설정

HAPROXY 의 설정을 처음 하다보니 제대로 되지를 않아서 정리를 하면서 하기 결정하고 하나씩 매뉴얼상의 항목들과 인터넷상의 내용들을 취합해서 정리하기로 했다.

처음 해보는 로드밸런싱이기도 하고 해서 내용자체가 이해가 안가는 부분도 있지만 로그나 그런 부분들에 대해서 알고 있다면 이해가 되는 부분들도 꽤 있다.

최우선 과제는.

  1. OvenMediaEngine과의 연동이다.

    • OME의 LB로 사용하기 위한 것이기 때문에 OME에서 사용하는 포트와 분산처리에 대한 LB 설정으로서 제대로 동작해야 한다.
  2. 동시 처리인원에 대한 설정이다.

    • 과연 동시 처리인원이 얼마나 될것이며 이것이 OME에 어떻게 영향을 줄지를 알아야 한다.
  3. 관리적인 차원의 문제이다.

    • LB의 액티브와 스탠바이 설정을 쉽게 처리할 수 있는지? 어떻게 관리가 되는지, 또한 OME의 엣지 서버들에 대한 등록을 쉽게 할 수 있는지를 알아두어야 한다. 관리자를 구성해서 config를 처리할 수 있을지도 알아두어야 한다.

우선 위의 3가지를 중점적으로 다루고 나머지는 기본적인 구성과 퍼포먼스 위주의 구성으로 구분하여 정리하기로 한다.

다음의 apt 명령을 이용하여 2.0.13 버젼을 설치했다.
apt를 이용한 최신버젼의 설치는 추후에 확인 해본다.
소스를 이용한 설치는 다른 정리노트를 활용한다.

sudo apt update
sudo apt install haproxy

위와 같이 하면 아래와 같이 haproxy.cfg 와 400,403,408,500,502,503,504등 7개의 에러로그 파일이 생성된다.

root@k5w1hcd-155566:/etc/haproxy# ll
total 16
drwxr-xr-x  3 root root 4096 Jan  7 16:52 ./
drwxr-xr-x 92 root root 4096 Jan  7 07:24 ../
drwxr-xr-x  2 root root 4096 Jan  7 16:10 errors/
-rw-r--r--  1 root root 1305 Sep  9  2020 haproxy.cfg
root@k5w1hcd-155566:/etc/haproxy/errors# ll
total 48
drwxr-xr-x 2 root root  4096 Jan  7 16:10 ./
drwxr-xr-x 3 root root  4096 Jan  7 16:52 ../
-rw-r--r-- 1 root root   188 Feb 13  2020 400.http
-rw-r--r-- 1 root root   189 Feb 13  2020 403.http
-rw-r--r-- 1 root root   213 Feb 13  2020 408.http
-rw-r--r-- 1 root root   205 Feb 13  2020 500.http
-rw-r--r-- 1 root root   205 Feb 13  2020 502.http
-rw-r--r-- 1 root root   213 Feb 13  2020 503.http
-rw-r--r-- 1 root root   195 Feb 13  2020 504.http

다음은 생성된 cfg파일의 내용이다.


global
# global section 구분 - 프로세스 전체에 적용되며, 운영체제(OS)에 따라 다를 수 있다. haproxy는 global section 외에 defaults, listen, frontend, backend 등의 proxy section으로 구성됨
           
        log /dev/log    local0
        log /dev/log    local1 notice
        # global syslog 서버(server) 설정.
        # 시작 및 종료에 대한 로그(log)와 “log global”로 구성된 proxy의 모든 log를 수신
        # /dev/log”는 주소(address) 설정이며, IPv4, IPv6, 유닉스(unix) 소켓(socket)의 경로(path) 등으로 설정할 수 있다.
        # "local0”, “local1”은 facility 설정이며, syslog facility로 설정한다.
        # “notice”는 level 설정이며, syslog severity level로 설정한다.
                
        chroot /var/lib/haproxy
        # 보안 강화를 위한 chroot 설정이며, 슈퍼 유저(superuser) 권한으로 시작될 때만 작동한.
        # “/var/lib/haproxy”는 chroot 감옥(jail) 디렉터리(directory) path 또는 샌드박스 path이며, chroot로 만들어진 격리된 공간.
        # | chroot에 대한 자세한 사항은 https://ko.wikipedia.org/wiki/Chroot 페이지를 참고 바람.
        
        
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        # socket 바인딩(bind) 설정.  
        #  - unix socket을 “path”에 bind 하거나 TCP v4/v6 address를 “address:port” 형식으로 bind 한다.
        # “/run/haproxy/admin.sock”는 “stats socket” 설정의 path.
        # “mode 660”는 unix socket 접근(access) 권한 설정.
        #  - 8진 모드로 설정하며, global section의 “unix-bind”로도 설정할 수 있다.
        # “level admin”은 socket 실행 권한 제한 설정입니다.
        #  - “user”, “operator”, “admin” 중 하나로 설정할 수 있으며, 아시다시피 “admin”은 모든 권한을 갖는다.
        # “expose-fd listeners”은 seamless reload(zero downtime reload)를 위한 설정으로, haproxy 1.8 버전부터 사용할 수 있다.
        #  - 위 설정은 리스너(listeners) FD(file descriptor)를 다른 haproxy 프로세스(process)로 전달.
        #  - 이전 process에서 file descriptor를 통해 unix socket을 사용해서 연결(connection)을 유지하고, 이를 이전 process와 새로운 process에 전달해서 connection 유실을 방지할 수 있는 설정입니다.
          
        
        stats timeout 30s
        # socket timeout 설정입니다.
        #  - 기본 시간제한은 10초이며, 밀리초(millisecond) 단위 또는 “us”, “ms”, “s”, “m”, “h”, “d” 단위로 설정합니다.  
        
        
        user haproxy
        # 시스템(system) 사용자를 unix socket 소유자로 설정한다.
        
        
        group haproxy
        # system 그룹을 unix socket 그룹으로 설정한다.
                
        
        daemon
        # process fork를 백그라운드로 만드는 권장 설정.
        # “-D” 인수(argument)와 동일하며, “-db” argument로 비활성화할 수 있다.
        # | fork에 대한 자세한 사항은 https://ko.wikipedia.org/wiki/포크_(시스템_호출) 페이지를 참고 바람.





        # Default SSL material locations
        ca-base /etc/ssl/certs
        # “ca-file” 또는 “crl-file”의 상대 경로(path) 사용 시, SSL CA 인증서(certificates) 및 CRLs의 기본 directory를 설정한.
        
        crt-base /etc/ssl/private
        # “crtfile”의 상대 경로(path) 사용 시, SSL certificates의 기본 directory를 설정한다.


        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        # SSL/TLS cipher 설정.
        # TLS v1.2까지 설정할 수 있으며, TLS v1.3 구성은 “ssl-default-bind-ciphersuites” 설정이 필요합니다.
        
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        # SSL/TLS cipher 설정.(TLS v1.3 구성)
        
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
        # 기본 SSL 설정.
        # “no-sslv3” 설정은 SSLv3 사용을 비활성화한다.  
 
 
        # SSL/TLS에 대한 자세한 사항은 https://ko.wikipedia.org/wiki/전송_계층_보안 페이지를 참고.
        # cipher에 대한 자세한 사항은 https://ko.wikipedia.org/wiki/암호_(암호학) 페이지를 참고
        # cipher suite에 대한 자세한 사항은 https://ko.wikipedia.org/wiki/암호화_스위트 페이지와 https://en.wikipedia.org/wiki/Cipher_suite 페이지를 참고
        


defaults
# defaults section
# defaults section의 설정은 모든 section에 적용됩니다.
# section 명은 선택 사항이지만, 설정하는 것을 권장.

        log     global
        # global log 설정.
        # haproxy 인스턴스(instance) 당 하나만 설정할 수 있으며, 매개 변수(parameter)가 없다.
        
        
        mode    http
        # haproxy 실행 mode 또는 프로토콜(protocol) 설정.
        # tcp, http, health mode로 설정할 수 있으며, 기본값은 tcp mode.
        #  - tcp mode는 SSL, SSSH, SMTP 등에 사용
        #  - ttp mode는 RFC를 준수하지 않는 요청은 거부되며, 서버 연결(connection) 전에 분석된다.
        
        
        option  httplog
        # HTTP 요청(request), 세션(session) 상태 및 타이머(timer) 등의 로깅(logging)을 활성화하는 설정
        # backend section에서는 사용할 수 없다.
        
        option  dontlognull
        # null connection logging 설정.
        # 이 설정은 데이터(data)가 전송되지 않는 connection을 기록하지 않는다.
        # “option” 앞에 “no” 키워드 추가로 설정을 비활성화 할 수 있다.
        # ackend section에서는 사용할 수 없다.
        
#        timeout connect 5000
        # server의 연결 제한(지연) 시간 설정
        # millisecond로 설정하며, frontend section에서는 사용할 수 없다.
        
#        timeout client  50000
        # 클라이언트(client)의 최대 비활성 시간 설정
        # millisecond로 설정하며, backend section에서는 사용할 수 없
        
#        timeout server  50000
        # server의 최대 비활성 시간 설정
        # millisecond로 설정하며, frontend section에서는 사용할 수 없다.

####################################################################
# default section 에 추가되는 환경 설정값
# Start of ADDED
####################################################################

        # ADDED
        option http-server-close
        # 클라이언트(client)에서 HTTP 연결(connection) 유지(keep-alive) 및 파이프 라이닝 기능을 유지하면서 서버(server)에서 HTTP connection을 닫을 수 있는 설정.
        # 이 설정은 client에서 가장 낮은 대기 시간(latency)을 제공하고 server에서 가장 빠른 세션(session) 재사용을 제공하여 리소스(resource)를 절약한다.
        # “option” 앞에 “no” 키워드 추가로 설정을 비활성화 할 수 있다.
        
        # | haproxy는 기본적으로 keep-alive 모드(mode)로 작동한다.
        
        option forwardfor       except 127.0.0.0/8
        # server로 전송된 요청(request)에 “X-Forwarded-For” 헤더(header) 삽입에 대한 설정.
        # “except” 키워드(keyword)를 적용하여 주소(address) 또는 네트워크(network)를 header에 추가하지 않을 수 있다.
        
        # | haproxy는 리버스(reverse) 프락시(proxy) mode로 작동하므로, haproxy server는 해당(server 자신) IP address를 client address로 간주한다.
        
        option                  redispatch
        # connection 실패 시, session 재전송(redistribution)에 대한 설정
        # “option” 앞에 “no” 키워드 추가로 설정을 비활성화 할 수 있
        # frontend section에서는 사용할 수 없다.
        
        retries                 3
        # connection 실패 후, server에서 수행할 재시도 횟수 설정.
        # 이 설정은 전체 request가 아닌 connection 시도 횟수에 적용된다.
        # frontend section에서는 사용할 수 없다.
        
        timeout http-request    10s
        # 전체 HTTP request를 대기할 최대 허용 시간 설정.
        # 이 설정을 활성화하면, client 유형(type)과 관계없이 request가 제시간에 완료되지 않으면 request는 중단된다.
        # 이 설정에서 제한 시간이 만료(expire)되면, client에게 HTTP 408 응답(response)을 전송하고 connection을 닫는다.
        
        timeout queue           1m
        # queue에서 보류(pending) 중인 request의 제한 시간 설정.
        # 이 설정을 지정하지 않으면, “timeout connect” 설정과 같은 값을 적용한다.
        # frontend section에서는 사용할 수 없다.
        
        timeout connect         10s # 5000        
        timeout client          1m  # 50000
        timeout server          1m  # 50000
        # 위 default section 의 timeout항목 참고
        
        timeout http-keep-alive 10s
        # 새로운 HTTP request를 대기할 최대 허용 시간 설정
        # “keep-alive”의 새 request를 대기 시간은 “timeout http-request”로 설정
        
        timeout check           10s
        # “timeout check” 설정은 “timeout connect” 설정의 최대 허용 연결 시간을 사용한 후, “timeout check” 설정을 추가로 최대 허용 읽기 시간으로 적용한다.
        # frontend section에서는 사용할 수 없다.
        
        maxconn                 3000
        # frontend의 최대 동시 connection 수를 설정
        # 기본값은 2,000이며, global maxconn을 초과하지 않아야 한다.
        # backend section에서는 사용할 수 없다.
        
#################################################################### 
# end of ADDED       
####################################################################
        
        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
        # haproxy의 오류(error) file 설정
        # HTTP 상태(status) 코드(code)에 맞춰서 error file을 연결

frontend http-rex
# frontend section
# “frontend section”은 client connection에 대한 IP address와 포트(port)를 설정한다.
# “http-rex”는 frontend 이름(name)
# 필요에 따라 “frontend section”을 추가 할 수 있으며, “frontend” 키워드 뒤에 name을 설정하여 구분할 수 있다.

# | 모든 proxy section name은 대소문자, 숫자, “-“(대시), “_“(밑줄), “.”(점), “:”(콜론)으로 구성되어야 한다.


        bind :::80 v4v6   # bind *:80
        # ”:::80”은 frontend가 수신할 address 설정이며, 선택 사항이다.
        # address 값은 호스트 name, IPv4 address, IPv6 address, “*“로 설정할 수 있으며, 미설정 시 IPv4 address가 수신된다.
        # “v4v6”는 기본 address 사용 시 IPv4 및 IPv6 모두 socket에 바인딩(bind)하는 설정이며, 리눅스(linux) 커널(kernel) 2.4.21 이상에서 지원한다.
        # defaults section과 backend section에서는 사용할 수 없다.
        
        option        http-server-close
 
        acl domain_net_scm hdr(host) -i scm.rex-domain.net
        acl domain_net_ci hdr(host) -i ci.rex-domain.net
        acl domain_net_sonar hdr(host) -i sonar.rex-domain.net
        # “acl”은 액세스 제어 목록(access control lists)을 의미하며. 데이터(data) 샘플(sample)의 패턴(pattern) 일치 여부에 따라 작업을 수행한다.
        #   - data sample은 request 또는 response, client 또는 server 정보 등에서 추출
        # “acl”은 일반적으로 request 차단(block), backend 선택 또는 header 추가로 구성됩니다.
        # “domain_net_scm”, “domain_net_ci”, “domain_net_sonar”는 acl name이다.
        #   - acl name은 대소문자, 숫자, “-“(대시), “_“(밑줄), “.”(점), “:”(콜론)으로 구성되며, 대소문자를 구분한다.
        # “hdr(host)”의 “hdr”은 header를 의미하며, “host”는 header가 포함된 HTTP request를 수락하는 설정이다.
        # “-i”는 acl flag이며, 대소문자를 무시하는 설정
        #   - acl flag는 “-f”, “-m”, “-n” 등이 있다.
        # “scm.rex-domain.net”, “ci.rex-domain.net”, “sonar.rex-domain.net”은 acl 값(value)이다.
        
        

        use_backend domain_net_app_scm       if domain_net_scm
        use_backend domain_net_app_ci        if domain_net_ci
        use_backend domain_net_app_sonar     if domain_net_sonar
        # “use_backend”는 acl 기반 조건(condition) 일치 시, 특정 backend로 전환하는 설정이다.
        # “domain_net_app_scm”, “domain_net_app_ci”, “domain_net_app_sonar”는 backend name 또는 listen section name이다.
        # “if domain_net_scm”, “if domain_net_ci”, “if domain_net_sonar”는 backend의 condition이며, “if” 뒤의 value는 acl name이다.
        #   - condition은 “if” 또는 “unless”를 사용할 수 있다.
        # backend section에서는 사용할 수 없다.
        
        

backend domain_net_app_scm
# backend section
# “backend section”은 들어오는 connection 전달을 위해 proxy가 연결할 server에 대한 설정이다.
# “domain_net_app_scm”, “domain_net_app_ci”, “domain_net_app_sonar”는 backend name이다.
# 필요에 따라 “backend section”을 추가 할 수 있으며, backend 키워드 뒤에 name을 설정하여 구분할 수 있다.

        balance roundrobin
        server host1 10.0.10.6:8801
 
backend domain_net_app_ci
        balance roundrobin
        server host1 10.0.10.6:8802
 
backend domain_net_app_sonar
        balance roundrobin
        # “balance”는 로드 밸런싱(load balancing) 알고리즘(algorithm) 설정이다.
        # 위 설정은 roundrobin algorithm을 지정한다.
        # 사용 가능한 algorithm은 “roundrobin”, static-rr”, “leastconn”, “first” 등이 있다.
        # frontend section에서는 사용할 수 없다.
        
        server host1 10.0.10.6:8803
        # “server”는 backend의 server 설정이다.
        # “host1”은 내부(internal) name이며, 로그(log) 및 경고(alert)에 표시된다.
        #   - 0.0.0.0” 또는 “*” 설정 시, client connection IP address와 동일한 IP address로 전달되며, 이는 투명(transparent) proxy 아키텍처(architecture)에 유용하다.
        # “10.0.10.6:8801”, “10.0.10.6:8802”, “10.0.10.6:8803”의 “8801”, “8802”, “8803”은 port 정보이며 선택사항이다.
        #   - port 설정 시, 모든 connection은 해당 port로 전송된다.
        #   - port 미설정 시, client가 연결된 port로 전송된다.
        # frontend section에서는 사용할 수 없다.        
        
# transparent proxy란 client가 server에 request 시, transparent proxy가 request를 가로채서 캐싱(caching), 리디렉션(redirection) 및 인증(authentication) 등 다양한 작업을 수행하여 client 모니터링(monitoring) 또는 특정 server에 대한 access block 등을 설정할 수 있는 proxy다.        

다음은 rtmp를 위한 haproxy의 config 설정값이다.
기본적으로 RTMP는 TCP 1935 포트를 통해 작동합니다. 따라서 HAProxy 구성은 아래와 같이 TCP 모드로 구성됩니다.

media03은 클라이언트가 다른 서버에 동기화되는 비디오를 업로드하는 데 사용하기 때문에 가중치가 더 낮습니다.

일부 방화벽은 포트 1935를 허용하지 않을 수 있으므로 장애 조치 솔루션이 있습니다. 일반 TCP 포트 80에서 HTTP (또는 심지어 HTTP)를 통해 RTMP를 제공합니다 .

frontend ft_rtpm
        bind <public ip>:1935 name rtmp
        mode tcp
        maxconn 600
        default_backend bk_rtmp
 
backend bk_rtmp 
        mode tcp
        balance roundrobin
        stick store-request src
        stick-table type ip size 200k expire 20m
        stick on src
        source 0.0.0.0 usesrc clientip
        server media01 10.0.0.1:1935 check maxconn 200 weight 10
        server media02 10.0.0.2:1935 check maxconn 200 weight 10
        server media03 10.0.0.3:1935 check maxconn 200 weight 8

frontend rtmp-80
        bind <public ip>:80
        mode tcp
        maxconn 600
        default_backend rtmp-over-http
        
backend rtmp-over-http
        mode tcp
        balance roundrobin
        stick store-request src
        stick-table type ip size 200k expire 20m
        stick on src
        source 0.0.0.0 usesrc clientip
        server media01 10.0.0.1:1935 check maxconn 200 weight 10
        server media02 10.0.0.2:1935 check maxconn 200 weight 10
        server media03 10.0.0.3:1935 check maxconn 200 weight 8

다음은 생성된 400.http 에러로그의 내용이다.

HTTP/1.0 400 Bad request^M
Cache-Control: no-cache^M
Connection: close^M
Content-Type: text/html^M
^M
<html><body><h1>400 Bad request</h1>
Your browser sent an invalid request.
</body></html>

각각의 에러로그는 텍스트 내용만 다르고 기본 구조는 동일하다.


Facility

Facility Code는 메시지를 기록하는 시스템 유형을 지정하는 데 사용된다. 기능이 다른 메시지는 다르게 처리될 수 있다.
Facility Code는 RFC5424표준에 의해 정의됩니다.

Facility code Keyword Description
0 kern Kernel messages
1 user User-level messages
2 mail Mail system
3 daemon System daemons
4 auth Security/authentication messages
5 syslog Messages generated internally by syslogd
6 lpr Line printer subsystem
7 news Network news subsystem
8 uucp UUCP subsystem
9 cron Cron subsystem
10 authpriv Security/authentication messages
11 ftp FTP daemon
12 ntp NTP subsystem
13 security Log audit
14 console Log alert
15 solaris-cron Scheduling daemon
16–23 local0 – local7 Locally used facilities

Severity level

심각도 목록도 RFC5424표준에 의해 정의됩니다.

Value Severity Keyword Deprecated keywords Description Condition
0 Emergency emerg panic System is unusable A panic condition.
1 Alert alert Action must be taken immediately A condition that should be corrected immediately, such as a corrupted system database.
2 Critical crit Critical conditions Hard device errors.
3 Error err error Error conditions
4 Warning warning warn Warning conditions
5 Notice notice Normal but significant conditions Conditions that are not error conditions, but that may require special handling.
6 Informational info Informational messages Confirmation that the program is working as expected.
7 Debug debug Debug-level messages Messages that contain information normally of use only when debugging a program.

레이어 7 로드 밸런싱 투명 프록시 모드

로드 밸런서는 사용자와 서버 간의 모든 트랜잭션의 중간에 있습니다.
두 개의 분리된 TCP 연결을 유지합니다.

  • 사용자와 함께: 로드 밸런서는 서버 역할을 합니다. 요청을 받고 응답을 전달합니다.
  • 서버 사용: 로드 밸런서는 사용자 역할을 합니다. 요청을 전달하고 응답을 받습니다.

프록시 모드에 가깝지만 한 가지 주요 차이점이 있습니다. 로드 밸런서는 클라이언트 IP 주소를 소스 IP로 사용하여 서버에 대한 연결을 엽니다.

물론 백엔드 서버의 기본 게이트웨이는 로드 밸런서여야 합니다.

TCP 연결 개요

728.png

다이어그램은 로드 밸런서에서 유지 관리하는 두 개의 TCP 연결을 명확하게 보여줍니다.

데이터 흐름

dataflow.png
로드 밸런서는 사용자 IP 주소로 서버에 대한 TCP 연결을 열므로 서버는 로드 밸런서를 기본 게이트웨이로 사용해야 합니다.
그렇지 않으면 서버는 클라이언트에 직접 응답을 전달하고 클라이언트는 응답을 삭제합니다.

장점과 단점

장점

  • 서버는 네트워크 계층에서 클라이언트 IP 주소를 봅니다.
  • 보안: 서버에 직접 연결되지 않음
  • 프로토콜 검사 및 검증 허용

단점

  • intrusive: 서버의 기본 게이트웨이를 변경해야 합니다.
  • 레이어 4 로드 밸런싱보다 "느림"(마이크로초)
  • 클라이언트와 서버는 두 개의 서로 다른 서브넷에 있어야 합니다.

When use this mode?

  • 부하 분산 서비스가 네트워크 계층에서 클라이언트 IP를 필요로 하는 경우(IE: 스팸 방지 서비스)
  • 애플리케이션 계층 인텔리전스가 필요할 때(컨텐츠 스위칭 등...)
  • 애플리케이션을 보호하기 위해

HAProxy를 사용하여 스트림 소비의 부하를 분산