README.md_20220808 9.06 KB
[![logo](https://www.hongsnet.net/images/logo.gif)](https://www.hongsnet.net)

# HA-Proxy를 이용한 Load Balancer 운용

> Front-End에서 운용되는 www.hongsnet.net 서비스의 Load Balancer의 구성내역을 살펴본다.


# 서비스 구성

- www.hongsnet.net Backend (Round-Robin 분산 알고리즘)
- edu.hongsnetnet Backend (Round-Robin 분산 알고리즘)
- SSL Redirection (Backend의 경우 80만 Listen)

## 구성 내역

- **haproxy.cfg 설정 내역**

```bash
# cat haproxy.cfg |grep -v '#'
global
    daemon
    maxconn 8192
    user    haproxy
    tune.ssl.default-dh-param 2048
    log 127.0.0.1 local0
    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
    stats socket /var/run/haproxy/info.sock mode 666 level user

cache web_cache
    total-max-size 1024   # MB
    max-object-size 10000 # bytes
    max-age 180            # seconds

defaults
    log       global
    mode      http
    option    httplog clf
    option    dontlognull
    option    dontlog-normal
    option    forwardfor
    option    http-server-close

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

    option    accept-invalid-http-request

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    admin:패스워드

frontend hongs

    bind *:80
    bind *:443 ssl crt /etc/haproxy/certs/hongs.pem

    http-response set-header Cache-Control web_cache,\ max-age="600"
    http-request deny if deny_useragent

    compression algo gzip
    compression type text/plain application/json application/xml

    acl deny_useragent hdr_sub(user-agent) -i -f /etc/haproxy/deny_useragent.list
    acl private-network src 127.0.0.0/8
    acl private-network src 172.24.0.0/16
    acl private-network src 192.168.200.0/24

    monitor-uri /monitor
    monitor fail if !private-network

    capture request header Host len 128
    capture request header User-Agent len 64
    capture request header Referrer len 64

    log-format "%ci\ [%trl]\ %HM\ \"%HU\"\ \"%HV\"\ %ST\ %B\ %hr\ %s\ %b\ %TR/%Tw/%Tc/%Tr/%Ta\ %ac/%fc/%bc/%sc/%rc"

    acl is_www_hongsnet_net hdr_end(host) -i www.hongsnet.net
    use_backend www_hongsnet_net if is_www_hongsnet_net

    acl is_edu_hongsnet_net hdr_end(host) -i edu.hongsnet.net
    use_backend edu_hongsnet_net if is_edu_hongsnet_net

    acl is_newsystem_hongsnet_net hdr_end(host) -i newsystem.hongsnet.net
    use_backend newsystem_hongsnet_net if is_newsystem_hongsnet_net

    acl is_edu_example_com hdr_end(host) -i edu.example.com
    use_backend edu_example_com if is_edu_example_com

    acl is_study_hongsnet_net hdr_end(host) -i study.hongsnet.net
    use_backend study_hongsnet_net if is_study_hongsnet_net

    acl is_hongsnet_net hdr_end(host) -i hongsnet.net
    use_backend hongsnet_net if is_hongsnet_net

backend www_hongsnet_net

    # 에러 파일 설정
    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

    http-request cache-use web_cache
    http-response cache-store web_cache

    http-request set-src src

    #Redirect if HTTPS is *not* used, 강제 https 리디렉션, 평시운영 시
    redirect scheme https code 301 if !{ ssl_fc }

    server  tb2.hongsnet.net 172.24.0.151:30000 check fall 3 rise 2
    server  tb3.hongsnet.net 172.16.0.158:30000 check fall 3 rise 2

backend edu_hongsnet_net

    # 에러 파일 설정
    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

    http-request cache-use web_cache
    http-response cache-store web_cache

    http-request set-src src

    # Redirect if HTTPS is *not* used, 강제 https 리디렉션
    redirect scheme https code 301 if !{ ssl_fc }

    server  tb2.hongsnet.net 172.24.0.151:30000 cookie tb2 check fall 3 rise 2
    server  tb3.hongsnet.net 172.16.0.158:30000 cookie tb3 check fall 3 rise 2
    server  tb3-docker.hongsnet.net 172.16.0.251:30000 cookie tb3-docker check fall 3 rise 2

backend edu_example_com

    # 에러 파일 설정
    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

    http-request set-src src

    # Redirect if HTTPS is *not* used, 강제 https 리디렉션
    redirect scheme https code 301 if !{ ssl_fc }

    server  tb2.hongsnet.net 172.24.0.151:30000 cookie tb2 check fall 3 rise 2
    server  tb3.hongsnet.net 172.16.0.158:30000 cookie tb3 check fall 3 rise 2
    server  tb3-docker.hongsnet.net 172.16.0.251:30000 cookie tb3-docker check fall 3 rise 2

backend newsystem_hongsnet_net

    # 에러 파일 설정
    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

    http-request set-src src

    # Redirect if HTTPS is *not* used, 강제 https 리디렉션
    redirect scheme https code 301 if !{ ssl_fc }

    server  tb2.hongsnet.net 172.24.0.151:30000 check fall 3 rise 2
    server  tb3.hongsnet.net 172.16.0.158:30000 check fall 3 rise 2
    server  tb3-docker.hongsnet.net 172.16.0.251:30000 check fall 3 rise 2

backend study_hongsnet_net

    # 에러 파일 설정
    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

    http-request set-src src

    # Redirect if HTTPS is *not* used, 강제 https 리디렉션
    redirect scheme https code 301 if !{ ssl_fc }

    server  tb2.hongsnet.net 172.24.0.151:30000 cookie tb2 check fall 3 rise 2
    server  tb3.hongsnet.net 172.16.0.158:30000 cookie tb3 check fall 3 rise 2
    server  tb3-docker.hongsnet.net 172.16.0.251:30000 cookie tb3-docker check fall 3 rise 2

```


## 주요설정 내역

- **SSL Redirection**

```bash
redirect scheme https code 301 if !{ ssl_fc }
```

- X-Forwarded-For Add Header 
```bash
option    forwardfor
```
> request를 서버로 보낼 때 Backend에서는 HA-Proxy의 IP가 로그가 기록된다. 따라서 이 옵션을 추가하면 실제 클라이언트의 IP주소가 기록된다.
  
- **Session Reuse**
```bash
option    http-server-close
```
> 기본적으로 HAProxy는 접속유지 관점에서 keep-alive 모드로 동작을 하는데, 각각의 커넥션은 request와 reponse를 처리하고나서, 새로운 request을 받기까지 connection idle 상태(유휴상태)로 양쪽이 연결되어 있다. "option http-server-close" 는 클라이언트 사이드에서 HTTP keep-alive를 유지하고 파이프라이닝을 지원하면서 서버 사이드에 커넥션을 닫는 형태를 설정한다. 이는 클라이언트 사이드에서 최저 수준의 응답지연을 제공하고, Server-Side에서 리소스를 재활용할 수 있게 되어 **backend 에서 빠르게 세션을 재사용할 수 있도록** 해준다.
  
- **Unicode Accept**
```bash
option    accept-invalid-http-request
```
> 이 설정을 적용하지않으면, URI에 한글 등의 유니코드가 호출될 경우 400에러가 발생한다.
  
- **ACL 설정**
```bash
acl is_www_hongsnet_net hdr_end(host) -i www.hongsnet.net 
use_backend www_hongsnet_net if is_www_hongsnet_net
```
> 요청되는 호스트의 URI에 www.hongsnet.net 이 검출되면, is_www_hongsnet_net으로 설정하고, 이 설정은 www_hongsnet_net의 **Backend**로 라우팅되도록 설정한다.

- **Back-end 설정**

```bash
server  tb2.hongsnet.net 172.24.0.151:30000 check fall 3 rise 2
server  tb3.hongsnet.net 172.16.0.158:30000 check fall 3 rise 2
server  tb3-docker.hongsnet.net 172.16.0.251:30000 check fall 3 rise 2
```

> 연결할 Back-end 서버들의 리스트다. 3번 health check가 실패하면 down으로 판단되고, 2번 성공하면 다시 Load Balancer 대상에 포함시킨다. 그리고 backup의 경우 서버점검 시 사용한다.
> **30000**번 포트는 `K8s의 NodePort 설정으로 외부에 노출되는 서비스 포트` 이다.