본문 바로가기

리눅스

우분투에서 Keepalived와 HAProxy를 사용하여 고가용성(High Availability, HA)을 구현하는 방법

728x90

우분투에서 Keepalived와 HAProxy를 사용하여 고가용성(High Availability, HA)을 구현하는 방법

테스트 시스템 현황

Hostname IPAddress 패키지 비고
vip 172.19.0.10    
haproxy01 172.19.0.2 keepalived + haproxy  
haproxy02 172.19.0.3 keepalived + haproxy  
web01 172.19.0.11 nginx + php-fpm  
web02 172.19.0.12 nginx + php-fpm  

테스트 도커 컨테이너 - https://github.com/anti1346/ubuntu22_keepalived_haproxy.git

추가 패키지 설치

sudo apt-get update
sudo apt-get install -y lsb-release ca-certificates vim rsyslog openssh-server

VIP를 사용하여 바인딩하도록 커널 파라미터 설정

echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
sudo sysctl --system
sudo sysctl -a | egrep 'net.ipv4.ip_nonlocal_bind'

Keepalived 설치

각 노드에 Keepalived를 설치합니다.

sudo apt-get update
sudo apt-get install -y keepalived

Keepalived 구성

vim /etc/keepalived/keepalived.conf
  • haproxy01 keepalived.conf
vim /etc/keepalived/keepalived.conf
더보기

---

global_defs {
    notification_email {
        admin@example.com
    }
    notification_email_from admin@example.com
    #smtp_server smtp.example.com
    #smtp_connect_timeout 30
    router_id LVS_DEVEL
    enable_script_security
    script_user root
}

vrrp_script haproxy_check {
    script "/etc/keepalived/haproxy_check.sh"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.19.0.10/24 dev eth0 label eth0:1
    }
    track_script {
        haproxy_check
    }
}

---

 

  • haproxy02 keepalived.conf
vim /etc/keepalived/keepalived.conf
더보기

---

global_defs {
    notification_email {
        admin@example.com
    }
    notification_email_from admin@example.com
    #smtp_server smtp.example.com
    #smtp_connect_timeout 30
    router_id LVS_DEVEL
    enable_script_security
    script_user root
}

vrrp_script haproxy_check {
    script "/etc/keepalived/haproxy_check.sh"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.19.0.10/24 dev eth0 label eth0:1
    }
    track_script {
        haproxy_check
    }
}

---

 

스크립트 파일 생성

vim /etc/keepalived/haproxy_check.sh
#!/bin/bash

# 이 스크립트는 HAProxy가 실행 중인지 확인합니다.
# HAProxy가 실행 중이면 0을 반환하고 그렇지 않으면 1을 반환합니다.

if pidof haproxy > /dev/null; then
    exit 0
else
    exit 1
fi
sudo chmod +x /etc/keepalived/haproxy_check.sh

Keepalived 구문 검사

keepalived -t

Keepalived 시작

sudo systemctl restart keepalived

VIP(Virtual IP) 설정 확인

ip -brief address show
ip -brief address show eth0
root@node01:~$ ip -brief address show
lo               UNKNOWN        127.0.0.1/8 
eth0@if804       UP             172.19.0.3/16 172.19.0.10/24
root@node02:~$ ip -brief address show
lo               UNKNOWN        127.0.0.1/8 
eth0@if802       UP             172.19.0.2/16

SSL 인증서 생성

mkdir -p /etc/ssl/ha_sangchul_kr
cd /etc/ssl/ha_sangchul_kr
openssl req \
-newkey rsa:4096 \
-x509 \
-sha256 \
-days 3650 \
-nodes \
-out ha_sangchul_kr.crt \
-keyout ha_sangchul_kr.key \
-subj "/C=KR/ST=Seoul/L=Jongno-gu/O=SangChul Co., Ltd./OU=Infrastructure Team/CN=ha.sangchul.kr"
openssl x509 -in /etc/ssl/ha_sangchul_kr/ha_sangchul_kr.crt -noout -subject -dates
$ openssl x509 -in /etc/ssl/ha_sangchul_kr/ha_sangchul_kr.crt -noout -subject -dates
subject=C = KR, ST = Seoul, L = Jongno-gu, O = "SangChul Co., Ltd.", OU = Infrastructure Team, CN = ha.sangchul.kr
notBefore=Jan 29 04:11:25 2024 GMT
notAfter=Jan 26 04:11:25 2034 GMT

SSL 인증서 파일 통합(개인 키 + 서버 인증서)

cat ha_sangchul_kr.key ha_sangchul_kr.crt > unified_ha_sangchul_kr.pem

HAProxy 설치

각 노드에 HAProxy를 설치합니다.

sudo apt-get install -y haproxy

HAProxy 구성

vim /etc/haproxy/haproxy.cfg
  • node01 haproxy.cfg
vim /etc/haproxy/haproxy.cfg
더보기

---

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

defaults
    log                     global
    mode                    http
    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 http-in
    bind *:80
    acl url_admin       path_beg       /admin
    use_backend bk_admin     if url_admin
    default_backend             bk_web

frontend https-in
    bind *:443 ssl crt /etc/ssl/ha_sangchul_kr/unified_ha_sangchul_kr.pem
    acl url_admin       path_beg       /admin
    use_backend bk_admin     if url_admin
    default_backend             bk_web

backend bk_web
    balance     roundrobin
    server      web1 172.19.0.3:8080 check
    server      web2 172.19.0.2:8080 check

backend bk_admin
    balance     roundrobin
    server      web1 172.19.0.3:8080 check
    server      web2 172.19.0.2:8080 check

listen stats
    #bind *:1936
    bind *:9000
    stats enable
    stats uri /haproxy_stats
    stats refresh 10s

---

 

  • node02 haproxy.cfg
vim /etc/haproxy/haproxy.cfg
더보기

---

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

defaults
    log                     global
    mode                    http
    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 http-in
    bind *:80
    acl url_admin       path_beg       /admin
    use_backend bk_admin     if url_admin
    default_backend             bk_web

frontend https-in
    bind *:443 ssl crt /etc/ssl/ha_sangchul_kr/unified_ha_sangchul_kr.pem
    acl url_admin       path_beg       /admin
    use_backend bk_admin     if url_admin
    default_backend             bk_web

backend bk_web
    balance     roundrobin
    server      web1 172.19.0.3:8080 check
    server      web2 172.19.0.2:8080 check

backend bk_admin
    balance     roundrobin
    server      web1 172.19.0.3:8080 check
    server      web2 172.19.0.2:8080 check

listen stats
    bind *:9000
    stats enable
    stats uri /haproxy_stats
    stats refresh 10s

---

 

HAProxy 구문 검사

haproxy -c -f /etc/haproxy/haproxy.cfg -V

HAProxy 재시작

sudo systemctl restart haproxy
728x90

Nginx 설치 및 index.html 파일 생성

Nginx 패키지 설치

sudo apt-get install -y nginx

Nginx index.html 파일 생성

vim /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
        <head>
                <title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
        </head>
        <body>
                <h1>Welcome to nginx!</h1>
                <p>web11 - 172.19.0.11</p>
                <p><em>Thank you for using nginx.</em></p>
        </body>
</html>
sudo apt-get install -y php-fpm

Nginx, PHP-FPM 재시작

sudo systemctl --now enable nginx
sudo systemctl --now enable php8.1-fpm

curl 명령어를 사용하여 웹 페이지 테스트

html2text 패키지 설치

sudo apt-get install -y html2text

 

curl -s http://ha.sangchul.kr | html2text
$ curl -s http://ha.sangchul.kr | html2text   
****** Welcome to nginx! ******
web11 - 172.19.0.11
Thank you for using nginx.
$ curl -s http://ha.sangchul.kr | html2text
****** Welcome to nginx! ******
web12 - 172.19.0.12
Thank you for using nginx.
curl -sk https://ha.sangchul.kr | html2text
$ curl -sk https://ha.sangchul.kr | html2text
****** Welcome to nginx! ******
web11 - 172.19.0.11
Thank you for using nginx.
$ curl -sk https://ha.sangchul.kr | html2text
****** Welcome to nginx! ******
web12 - 172.19.0.12
Thank you for using nginx.

 

watch 명령어로 테스트 페이지 모니터링

watch -t -d -n 1 "curl -sk http://ha.sangchul.kr | html2text"

 

728x90