haproxy & keepalived 로 프록시 구축하기

overview

VM 두대(이상)에 haproxy를 설치하여 L4(또는 L7) switch 장비를 대체 할 수 있도록 하는게 목표 입니다. haproxy간의 HA(High availability)는 keepalived를 사용하여 VIP를 넘기는 식으로 구성 합니다.
사실 지금 L7을 사용하고 있는데 이렇게 하려는 이유는 다음과 같습니다.

  1. LoadBalancer를 사용할 수는 있는 환경 이지만 내가 컨트롤 할 수 없는 상황 (네트워크 부서에서 담담).
  2. 검증계에서 이것저것 구성하려고 해도 L7 관련 설정은 SR(Service Request) 티켓을 만들어야 하고, 최소 일주일 전에는 SR을 올려야 내가 원하는 기간에 맞춰서 설정을 바꿀 수 있음.

구성할 모습(TO-BE)
stg1이 master
평상시에는 위 그림과 같이 stg1에 VIP 12.34.56.129 이 붙어 있고 리퀘스트가 들어오면 stg1의 haproxy를 통해 stg1과 stg2로 밸런싱 됩니다.
그러다가 stg1이 다운되면 아래 그림과 같이 VIP가 stg2로 옮겨 가게 되고, stg2 -> stg2로만 리퀘스트를 보내다가 stg1이 다시 살아 나면 stg1로도 리퀘스트를 나눠 줍니다.
stg2 master
테스트 목적의 검증계의 구성이라서 이렇게 열악하게 구성 되었지만, haproxy 두대를 별도로 구성하고 밑에 로드밸런싱 되는 서버들을 여러대 붙이는게 일반적인 구성입니다.

준비사항

haproxy와 keepalived를 설치할 VM 2대 (yum repository 사용 가능한)
floating ip로 사용할 VIP 1개

haproxy 설치

1
2
3
install haproxy

sudo yum install haproxy

haproxy.cfg 수정

1
2
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.template
sudo vi /etc/haproxy/haproxy.cfg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
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

frontend main
bind 12.34.56.119:80
mode http
default_backend test-internal-proxy

backend test-internal-proxy
# health check
option httpchk GET /
http-check expect status 200
default-server inter 1s fall 3 rise 2
# load balancing
balance source
mode http
server stg1 12.34.56.205 check
server stg2 12.34.56.206 check

balance option(algorithm) 에 대해 간략하게 정리 했습니다. (자세한 내용은 https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-balance 참조)

  • roundrobin: 우리가 잘 알고있는 ‘그’ roundrobin 방식과 동일. 순서대로 돌려주는 방식 입니다.
  • static-rr: weight 에 따라 분배해 주는 방식 입니다. weight가 높은 서버로 더 많은 리퀘스트를 돌려줍니다.
  • leastconn: connection이 제일 적은 서버에 돌려주는 방식 입니다.
  • first: 서버 id 순서대로 돌려주는데, 앞에 서버가 차면 그 다음 서버로 돌려주는 방식 입니다.
  • soucre: IP hash 값을 서버 댓수로 나눈 값에 따라 돌려주는 방식 입니다.
  • uri: uri hash값을 총 서버 댓수로 나눈 값에 따라 돌려주는 방식 입니다.
  • url_param: url의 쿼리스트링의 hash 값을 총 서버 댓수로 나눈 값에 따라 돌려주는 방식 입니다.
  • hdr(): http header의 name 값을 보고 돌려주는데 name이 header에 없으면 rr로 돌려 줍니다..
  • rdp-cookie(): TCP 리퀘스트의 hash 값을 보고 돌려줌. equivalent ACL ‘reqrdpcookie()’ function. cookie가 없으면 rr로 돌려 줍니다.

haproxy logging 설정

기본적으로 haproxy 설정을 보면 아래와 같이 log를 127.0.0.1 로 보내고 있는것을 확인 할 수 있습니다.
이렇게 보내면 rsyslog로 보내는 것 이지만, rsyslog에는 관련해서 아무런 설정을 하지 않았기 때문에 로깅이 당연히 안됩니다.

1
2
global
log 127.0.0.1 local2

/etc/rsyslog.conf 수정

haproxy는 로그를 UDP로 보내주기 때문에 rsyslog에서 udp를 처리 할 수 있도록 아래 두 가지 옵션의 주석을 해제 합니다

1
sudo vi /etc/rsyslog.conf
1
2
$ModLoad imudp
$UDPServerRun 514

/etc/rsyslog.d/haproxy.conf 파일 생성

rsyslog에 udp 를 받을 수 있게 처리를 해 줬으니 실제로 haproxy 로그에 대한 설정 파일을 만들어 줍니다.

1
sudo vi /etc/rsyslog.d/haproxy.conf
1
local2.*    /nakjunizm/data/logs/util/haproxy/haproxy.log

추가로 /nakjunizm/data/logs/util/haproxy 디렉토리 없으면 미리 생성. (mkdir -p /nakjunizm/data/logs/util/haproxy)

rsyslog 재시작

1
sudo systemctl restart rsyslog

sysctl 설정

keepalived를 이용해서 floating ip를 옮겨다니게 하기 위해 아래 두가지 설정이 필요 합니다.
net.ipv4.ip_forward 는 NIC 간의 forwarding 을 허용 해 주는 옵션으로, 예를들어 eth0으로 들어온 리퀘스트를 eth1로 포워딩 시킬때 필요 합니다.
eth0에 VIP를 추가로 bind 시키는 경우에는 위 옵션을 1로 수정할 필요가 없고, 다른 NIC에 VIP를 붙이는 경우엔 필요한 것으로 생각 됩니다.
net.ipv4.ip_nonlocal_bind 는 network interface에 할당되지 않은 IP를 bind 할수 있게 allow 하는 옵션으로, 우리는 VIP를 bind 할것이기 때문에 1로 설정하여 enable 시킬 것 입니다.

1
sudo vi /etc/sysctl.conf
1
2
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1

변경 사항 저장

1
sudo sysctl -p

keepalived 설치

install keepalived

1
sudo yum install keepalived

keepalived 설정 변경

MASTER 설정 변경 (stg1 서버)

1
2
sudo cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.template
vi /etc/keepalived/keepalived.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
! Configuration File for keepalived

global_defs {
router_id LVS_DEVEL
}

vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
12.34.56.119
}
}

BACKUP 설정 변경 (stg2 서버)

BACKUP은 priority가 MASTER 보다 낮게 설정되어야 합니다.

1
2
sudo cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.template
vi /etc/keepalived/keepalived.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
! Configuration File for keepalived

global_defs {
router_id LVS_DEVEL
}

vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
12.34.56.119
}
}

실행

keepalived 실행

1
sudo systemctl start keepalived

keepalived를 양쪽에서 실행 하고 나서 ip a 이나 ifconfig 로 확인해보면 MASTER로 설정한 서버의 eth0에 vip가 추가로 붙어있는것을 확인 할 수 있습니다.

MASTER 에서 ip a 한 결과

1
2
3
4
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:11:22:33:cc:dd brd ff:ff:ff:ff:ff:ff
inet 12.34.56.205/24 brd 12.30.97.255 scope global eth0
inet 12.34.56.119/32 scope global eth0

BACKUP 에서 ip a 한 결과

1
2
3
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:11:22:33:ee:ff brd ff:ff:ff:ff:ff:ff
inet 12.34.56.206/24 brd 12.30.97.255 scope global eth0

haproxy 실행

1
sudo systemctl start haproxy

References

pacemaker가 아닌 keepalived로 ha를 구성한 이유

haproxy 전체적인 개념 및 설치

haproxy logging

keepalived 개념 설명

ipforward & nonlocalbind

기타 참조 사이트

Share