sumarsono.com
Take it with a grain of salt


Setup Haproxy Dan Keepalived Di Debian 10

Posted on

Untuk membuat HA HAProxy on premise, aku pakai Keepalived. Keepalived disini berperan sebagai penjaga Floating IP, untuk fail over ketika master0 mati maka keepalived akan assign floating ip ke master1 atau master2.

Lab Setup

Note: Disini aku memakai keepalived dengan unicast, krn environment engga mendukung untuk multicast.

Install keepalived dan haproxy di semua node (master0, master1, dan master2)

Aku perlu menambahkan repo haproxy karena mau pakai versi 2.2 LTS yang belum masuk ke repo debian buster:

root@master0:~# echo deb http://deb.debian.org/debian buster-backports main > /etc/apt/sources.list.d/backports.list

Kemudian update list package:

root@master0:~# apt update

Lanjut install yang aku butuhkan:

root@master0:~# apt install curl keepalived haproxy=2.2.\* -t buster-backports

Kemudian aku perlu setup beberapa parameter kernel yang dibutuhkan oleh keepalived dan haproxy untuk bind floating ip/virtual ip.

root@master0:~# vi /etc/sysctl.d/999-keepalived-haproxy.conf

net.ipv4.ip_forward=1
net.ipv4.ip_nonlocal_bind=1

Aku apply parameter kernel tersebut tanpa reboot:

root@master0:~# sysctl -p

Ulangi semua langkah di node master1 dan master2

Konfigurasi keepalived dan haproxy di master0

Node Master0 akan aku jadikan master untuk keepalived, sedangkan master1 dan master2 akan aku jadikan backup untuk keepalived. Perlu di juga perhatikan bagian unicast_src_ip dan unicast_peer.

root@master0:~# vi /etc/keepalived/keepalived.conf

# konfigurasi yang aku pakai:
global_defs {
    router_id LVS_DEVEL
}
vrrp_script check_apiserver {
  script "/usr/bin/killall -0 haproxy"
  interval 3
  weight -2
  fall 10
  rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    unicast_src_ip 10.179.72.245
    unicast_peer {
        10.179.72.211
        10.179.72.47
    }

    authentication {
        auth_type PASS
        auth_pass 42
    }
    virtual_ipaddress {
        10.179.72.200
    }
    track_script {
        check_apiserver
    }
}

Konfigurasi keepalived dan haproxy di master1

Keepalived di master1 aku konfig sebagai backup dengan priority lebih rendah dari master0. Perlu diperhatikan bagian unicast_src_ip dan unicast_peer

root@master1:~# vi /etc/keepalived/keepalived.conf

# konfigurasi yang aku pakai:
global_defs {
    router_id LVS_DEVEL
}
vrrp_script check_apiserver {
  script "/usr/bin/killall -0 haproxy"
  interval 3
  weight -2
  fall 10
  rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    unicast_src_ip 10.179.72.211

    unicast_peer {
        10.179.72.245
        10.179.72.47
    }

    authentication {
        auth_type PASS
        auth_pass 42
    }
    virtual_ipaddress {
        10.179.72.200
    }
    track_script {
        check_apiserver
    }
}

Konfigurasi keepalived di master2

Keepalived di master1 aku konfig sebagai backup dengan priority lebih rendah dari master0 dan master1. Perlu diperhatikan bagian unicast_src_ip dan unicast_peer.

root@master2:~# vi /etc/keepalived/keepalived.conf

# konfigurasi yang aku pakai:
global_defs {
    router_id LVS_DEVEL
}
vrrp_script check_apiserver {
  script "/usr/bin/killall -0 haproxy"
  interval 3
  weight -2
  fall 10
  rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 99
    unicast_src_ip 10.179.72.47

    unicast_peer {
        10.179.72.211
        10.179.72.245
    }

    authentication {
        auth_type PASS
        auth_pass 42
    }
    virtual_ipaddress {
        10.179.72.200
    }
    track_script {
        check_apiserver
    }
}

Perbedaan dari konfigurasi keepalived MASTER dan BACKUP:

[sumar@tingpret ~]$ diff master0-keepalived.conf master1-keepalived.conf 
13c13
<     state MASTER
---
>     state BACKUP
16,17c16,17
<     priority 101
<     unicast_src_ip 10.179.72.245
---
>     priority 100
>     unicast_src_ip 10.179.72.211
20c20
<         10.179.72.211
---
>         10.179.72.245
[sumar@tingpret ~]$ diff master0-keepalived.conf master2-keepalived.conf 
13c13
<     state MASTER
---
>     state BACKUP
16,17c16,17
<     priority 101
<     unicast_src_ip 10.179.72.245
---
>     priority 99
>     unicast_src_ip 10.179.72.47
21c21
<         10.179.72.47
---
>         10.179.72.245
[sumar@tingpret ~]$ diff master1-keepalived.conf master2-keepalived.conf 
16,17c16,17
<     priority 100
<     unicast_src_ip 10.179.72.211
---
>     priority 99
>     unicast_src_ip 10.179.72.47
19a20
>         10.179.72.211
21d21
<         10.179.72.47

Yang membedakan adalah state , priority , unicast_src_ip , unicast_peer

Konfigurasi haproxy di semua node (master0, master1, dan master2)

Konfigurasi untuk haproxy adalah sama untuk semua node.

root@master0:~# vi /etc/haproxy/haproxy.cfg

# configurasi yang aku pakai:
global
        log /dev/log    local0
        log /dev/log    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

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # 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-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        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

# apiserver frontend, pakai ip floating 
frontend apiserver
    bind 10.179.72.200:8080
    mode tcp
    option tcplog
    default_backend apiserver

# round robin balancing apiserver
backend apiserver
    option httpchk GET /healthprobe
    http-check expect status 200
    mode tcp
    balance     roundrobin
    server apiku1 10.179.72.2:80 check
    server apiku2 10.179.72.3:80 check
    server apiku3 10.179.72.4:80 check

Enable keepalived dan haproxy di semua node (master0, master1, dan master2)

root@master0:~# systemctl enable keepalived haproxy
root@master0:~# systemctl restart keepalived haproxy
root@master0:~# systemctl status keepalived haproxy

Ulangi untuk master1 dan master2.

Pengujian

Kondisi setelah semua jalan, terlihat bahwa floating ip (10.179.72.200) ada di master0:

+-------------+---------+----------------------+
| master0     | RUNNING | 10.179.72.245 (eth0) |
|             |         | 10.179.72.200 (eth0) |
+-------------+---------+----------------------+
| master1     | RUNNING | 10.179.72.211 (eth0) |
+-------------+---------+----------------------+
| master2     | RUNNING | 10.179.72.47 (eth0)  |
+-------------+---------+----------------------+

Aku coba curl ke floating ip tersebut + port yang aku konfig di HAProxy:

[sumar@tingpret ~]$ curl -IL 10.179.72.200:8080
HTTP/1.1 200 OK
...
Vary: Accept-Encoding
Date: Wed, 31 Mar 2021 08:17:07 GMT

Good, request diteruskan ke apiserver di belakang haproxy.

Kemudian, coba matikan koneksi master0, atau shutdown nodenya juga bisa.

+-------------+---------+----------------------+
| master0     | STOPPED |                      |
+-------------+---------+----------------------+
| master1     | RUNNING | 10.179.72.211 (eth0) |
|             |         | 10.179.72.200 (eth0) |
+-------------+---------+----------------------+
| master2     | RUNNING | 10.179.72.47 (eth0)  |
+-------------+---------+----------------------+

Terlihat floating ip di pindahkan ke node master1. Lalu aku coba lagi curl:

[sumar@tingpret ~]$ curl -IL 10.179.72.200:8080
HTTP/1.1 200 OK
...
Vary: Accept-Encoding
Date: Wed, 31 Mar 2021 08:20:17 GMT

Hasilnya good, request tetap diteruskan ke apiserver di belakang haproxy.

Sampai disini sudah selesai, semoga bermanfaat.

Cool~