728x90
반응형

HAProxy & Keepalived

 

HAProxy 이중화를 위해 Keepalived를 사용한 테스트이다. (Keepalived도 IPVS를 사용한 L4 Level의 LoadBalancing을 할 수 있다.)

 

 

 

 

설치

 

Test 환경

 

  • OS : Ubuntu 18.04

  • Node

    • VIP : 192.168.219.253

    • Master IP : 192.168.219.125

    • Slave IP : 192.168.219.126

    • Web01 : 192.168.219.128

    • Web02 : 192.168.219.129

  • HAProxy Version : 1.8.8

  • Keepalived Version : 1.3.9

 

 

HAProxy

 

# apt install -y haproxy

-> Ubuntu 18.04에서 기본 Repo로 설치시 1.8.8 버전이 설치된다.

 

현재 (2020-01) 2.1버전이 최신버전이며 1.5버전부터 SSL을 지원하기 때문에 기본설치방법으로도 SSL 사용이 가능하지만 최신 버전을 사용하고 싶다면 wget을 사용하여 다운로드 후 컴파일하거나 별도 Repo를 추가시켜준다.

 

# apt-add-repository ppa:vbernat/haproxy-2.1

# apt update

# apt install -y haproxy 또는 apt install -y haproxy=2.1

-> 위와 같은 방법으로 Repo 추가 후 설치하면 2.1.2 버전이 설치된다.

 

 

Keepalived

 

# apt install -y keepalived

 

 

 

설정

 

HAProxy (Master&Slave)

 

# vim /etc/haproxy/haproxy.cfg

global   

    log 127.0.0.1   local1 notice

    chroot /var/lib/haproxy

    stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners   

    stats timeout 30s   

    user haproxy    

    group haproxy  

    daemon  

    maxconn 4000

 

    ca-base /etc/ssl/certs

    crt-base /etc/ssl/private

 

    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

    ssl-default-bind-options no-sslv3

 

defaults

    log global

    mode    http

    option  httplog

    option  dontlognull

    option  forwardfor

    option  httpclose   

    timeout http-request 10s

    timeout http-keep-alive 10s

    timeout connect 10s

    timeout client  1m

    timeout server  1m

    timeout queue   1m

    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

 

listen stats_page  

    bind    192.168.219.253:8080

    stats   enable

    stats   realm HAProxy Statistics

    stats   uri /  

    stats   auth admin:admin   

 

frontend haproxy    

    bind    192.168.219.253:80

    mode    http  

    default_backend server

 

backend server  

    mode    http      

    balance roundrobin

    cookie  SVID insert indirect nocache maxlife 10m  

    option  httpchk GET /  

    http-check expect status 200  

    server web01 192.168.219.128:80 cookie web01 check inter 2000 rise 2 fall 5  

    server web02 192.168.219.129:80 cookie web02 check inter 2000 rise 2 fall 5  

 

 

Keepalived

 

# vim /etc/keepalived/keepalived.conf (Master)

vrrp_instance VI_1 {

  state MASTER

  interface eth0

  virtual_router_id 51

  priority 200

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass 7388

  }

  virtual_ipaddress {

    192.168.219.253

  }

}

 

# vim /etc/keepalived/keepalived.conf (Slave)

vrrp_instance VI_1 {

  state BACKUP

  interface eth0

  virtual_router_id 51

  priority 100

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass 7388

  }

  virtual_ipaddress {

    192.168.219.253

  }

}

 

 

 

커널 파라미터 변경

 

Kernel Parameter Default List

 

net.ipv4.ip_forward = 1

  • Kernel이 패킷을 전달하게 하는 경우 사용한다.

  • Keepalived가 네트워크 패킷을 실제 서버에 정상적으로 전달하려면 각 라우터 노드가 커널에서 IP Forward를 설정해야한다.

 

net.ipv4.ip_nonlocal_bind = 1

  • HAProxy 및 Keepalived의 로드밸런싱은 동시에 로컬이 아닌 IP 주소에 바인딩할 수 있어야한다.

  • 즉, 네트워크 인터페이스에 없는 주소로 바인딩할 수 있도록 해주는 커널 값이다. (네트워크 인터페이스가 지정된 정적 IP가 아닌 동적 IP를  바인딩할 수 있다.)

  • 해당 옵션이 비활성화 되어 있어도 서비스가 시작하면서 인터페이스에 특정 IP를 바인딩할 수 있으나 FailOver시 문제 발생

 

 

참고 URL

 

 

HAProxy Kernel Parameter Best Practices

 

 

가장 중요한 Paramater

 

net.ipv4.ip_local_port_range = "1025 65534"

net.ipv4.tcp_max_syn_backlog = 100000

net.core.netdev_max_backlog = 100000

net.core.somaxconn = 65534

ipv4.tcp_rmem = "4096 16060 64060"

ipv4.tcp_wmem = "4096 16384 262144"

 

 

작업량에 따라 조절

 

tcp_slow_start_after_idle = 0

 

 

iptables tuning

 

net.netfilter.nf_conntrack_max = 131072

 

 

주의 사항

 

conntrack이 잘못 구성되면 HAProxy가 최대 성능을 발휘하지 못한다.

또한 iptables가 활성화 되어 있으면 connection tracking 작업을 위해 iptables에 규칙이 없더라도 20%의 CPU를 소모한다.

 

 

참고 URL

 

 

 

테스트

 

아래 테스트는 커널 파라미터 중 기본값만 변경한 테스트이다.

 

1. 커널 파라미터 변경전 FailOver

 

# curl 192.168.219.253 (VIP)

 

외부에서 HAProxy의 VIP로 curl 명령 실행시 뒷단의 Web 서버로 LoadBalancing이 되는 것이 확인된다.

 

앞단에서 HAProxy Master역할을 하는 것은 Keepalived의 Master로 설정된 노드이다.

 

이제 Master VM 장애 발생을 가정하고 Failover 테스트를 진행한다.

Slave에는 Haproxy Service가 실행 중이다. 

(기본 커널 파라미터가 셋팅이 안된상태에서 Slave의 HAProxy 데몬은 실행에 실패한다. 테스트를 위해 Master를 Off후 서비스를 올린 뒤에 다시 Master를 On 시켜 테스트 환경을 만든 것이다.

데몬이 실패한 이유는 haproxy에 의해 VIP가 네트워크 인터페이스에 바인딩되어야하는데 커널파라미터가 비활성화 값이므로 실패하였다.)

 

Master VM을 Poweroff 하였을때 Keepalived에 의해 Slave VM이 Master로 승격되었다.

 

외부에서 HAProxy로 curl 명령 실행시 무중단으로 실행되는 것도 확인되었다.

 

이제 다시 Master VM을 실행시켜 FailBack을 할 예정이다.

 

 

Slave는 정상이나 Master가 다시 정상으로 돌아왔을 경우 HAProxy에 대한 응답은 실패했다.

Master에서 확인해보니 아래와 같이 HAProxy Service가 실패하였다.

 

 

실패 원인

 

haporxy는 haproxy.cfg에 있는 VIP를 바인딩해야하는데 VIP가 현재 로드밸런서에 없으므로 오류를 발생시킨다. (오류 내용 - 프록시 : 소켓을 바인드 할 수 없음)

Master -> Slave로 FailOver하는 경우 Keepalived에 의해 VIP가 옮겨간다. Slave에서 서비스 구동을 하다가 Master가 정상으로 돌아오면 Keepalived는 가중치에 의해 다시 Master가 트래픽을 받도록 변경한다.

이 상태에서 VIP도 Master로 옮겨오는데 Keepalived가 VIP를 Master의 네트워크 인터페이스에 바인딩하고 HAProxy가 서비스가 실행되면 커널파라미터에 상관없이 HAProxy에서 VIP를 네트워크 인터페이스에서 인식하여 정상적으로 FailBack이 된다.

 

# vim /lib/systemd/system/haproxy.service

 

 

위 방법은 Service의 Boot Type에서 notify를 idle로 변경한 것이다.

notify의 경우 simple과 동일하나 unit이 구동되면 systemd에 시그널을 보낸다. (unit이 시작된 즉시 systemd는 유닛의 시작이 완료되었다고 판단한다. 그런데 다른 유닛과 통신하기 위해 소켓을 사용하는 경우 이 설정을 사용하면 안된다.)

HAProxy의 경우 Keepalived와 통신하기 때문에 HA를 구성하기 위해서는 Type이 notify가 되어서는 안된다. 이런 부분을 해결해주는 것이  net.ipv4.ip_nonlocal_bind 파라미터이다.

Master에서 Type을 notify -> idle로 변경하였을 경우 net.ipv4.ip_nonlocal_bind=0 이더라도 정상적으로 FailBack이 진행된다.

하지만 Slave의 경우 Unit의 Type을 변경하더라도 서비스는 실패가 된다. (실패한 이유는 Keepalived의 VIP가 Master에 있기때문에 통신할 소켓이 없어서 발생한다. 네트워크 인터페이스의 바인딩 문제)

net.ipv4.ip_nonlocal_bind=1 일경우 Unit의 Type에 상관없이 HAProxy 서비스는 정상 시작된다. 

 

 

2. 커널 파라미터 변경후 FailOver 

 

net.ipv4.ip_nonlocal_bind=1 로 변경한 경우 정상적으로 FailOVer & FailBack이 진행된다. 다면 FailBack 과정에서 짧은시간동안 순단이 발생할 수 있으며 순단시에는 HTTP Code 503을 발생한 후 정상적으로 HTTP Code 200을 반환한다.

실제 운영환경에서는 자동 FailBack이 아닌 수동으로 FailBack을 진행하는 것을 권장한다. 잠시동안이라도 발생하는 네트워크 순단현상을 최대한 방지하기 위해서이다.

 

 

3. 정리

 

Master & Slave 구성에서 Master는 Service Unit의 Type 값을 변경해 정상적인 FailBack을 할 수 있고 Slave에서는 커널 파라미터를 변경하여 FailOver 환경을 만들수 있으나 정상적인 방법은 아니므로 기본 커널 파리미터 값을 변경하여 HA를 구성하는 것을 권장한다.

 

 

 

 

반응형

'Web' 카테고리의 다른 글

SNI(Server Name Indication)  (0) 2020.10.25
HAProxy  (2) 2020.01.17
Keepalived & VRRP  (0) 2020.01.17
부하분산 테스트 설명 및 용어  (0) 2019.04.09
PinPoint  (0) 2019.04.09

+ Recent posts