Bài đăng nổi bật

Redo log, undo log và binary log

Đây là ba loại log mà bạn đã từng nghe khi tiếp cận mysql. Trong các cơ sở dữ liệu quan hệ (RDBMS) khác, cũng sẽ có các thành phần có vai tr...

Thứ Bảy, 27 tháng 2, 2016

Quick setup haproxy and keepalived

Haproxy đóng vai trò như một reverse proxy thực hiện load balancer. Bản thân một haproxy thì không ấn định  high availabilty (HA) cho chính nó. Tính chất HA là ấn định cho cac backend server đằng sau nó. Nếu chỉ có một haproxy thì mô hình sẽ có một SPOF (Single Point Of Failure). Nó down thì cả hệ thống down theo. Để giải quyết, chúng ta  có thể thêm một haproxy để dự phòng (redundancy). Nhưng phương án đó lại phát sinh thêm vấn đề . Khi failover xảy ra client làm sao kết nối đến haproxy dự phòng. Tôi không thể gán cùng một IP lên hai haproxy được. IP conflict sẽ khiến mạng không ổn định. Tôi cũng không thể gán IP khác nhau cho mỗi haproxy được. Khi failover, tôi sẽ phải thông báo cho tất cả client về IP mới. Việc đó thật quá sức. Xem chừng lúc này chúng ta cần đến keepalived. Sử dụng keepalived sẽ cho phép tôi tạo ra một VIP - Virtual IP. Client sẽ kết nối đến haproxy qua VIP này. VIP này sẽ được keepalived luân chuyển sang haproxy dự phòng khi failover. Tất cả đều trong suốt với client. Client không biết được nó đang kết nối đến VIP, nó nghĩ nó đang kết nối trực tiếp đến một single backend thay vì một cluster backend nằm sau VIP. Client sẽ không biết đến real IP của proxy và IP của backend cũng như sự luân chuyển VIP này khi failover.

VIP là gì ?


Thực sự nó là một IP được gán thêm trên một network alias (virtual interface) của haproxy. Tính chất virtual của nó nằm ở chỗ nó không gắn cố định trên một network interface thật sự nào cả. Khi có sự cố xảy ra, keepalived sẽ hủy ip trên network alias của haproxy down và tạo trên haproxy backup.

Bạn có thể tự tạo một network alias và gán ip lên đó như sau:
Giả sử network interface của bạn được nhận dạng là eth0. Trong terminal, bạn gõ

ifconfig eth0:0 1.2.3.4 up

ip a
inet 192.168.2.100/24 brd 192.168.2.255 scope global eth0
inet 1.2.3.4/8 brd 1.255.255.255 scope global eth0:0

Để gỡ bỏ  network alias, trong terminal, bạn gõ:
ifconfig eth0:0 down

Cài đặt


yum install haproxy keepalived

Cấu hình


Haproxy config trên master và backup

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
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  dontlognull
    option http-server-close
    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

listen  backend_example
    bind *:<PROXY PORT>
    mode tcp
    balance leastconn
    option httpchk
    server backend_db_1 <IP1>:<BACKEND_PORT> check port <CHECK PORT>
    server backend_db_2 <IP2>:<BACKEND_PORT> check port <CHECK PORT>
    server backend_db_3 <IP3>:<BACKEND_PORT> check port <CHECK PORT>

listen stats
    bind *:<STATS PORT >
    mode http
    option httplog
    option httpclose
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
    stats auth <stats_user>:<stats_passwd>
    stats refresh 5s

Bộ config này dựa trên config mẫu của haproxy nên rất đơn giản. Mặc định các giá trị inter, rise, fall trong mỗi backend lần lượt là 2s,2,3. Tham số rise định nghĩa số lần một backend được check thành công trước khi proxy xem backend đó hoạt động để forward request vào. Tham số fall định nghĩa số lần check backend không thành công trước khi proxy xem backend đó ngừng hoạt động để không forward request vào backend đó nữa. Tham số inter sẽ đinh nghĩa khoảng thời gian giữa hai lần check liên tiếp.

Ở trên haproxy sẽ check trạng thái backend qua một http <CHECK_PORT>. Bản thân backend sẽ không phục vụ các check request này từ haproxy mà một service khác cũng nằm trên backend sẽ xử lý check request. Do là httpchk nên nếu kết quả nhận được là một response status code 200 thì thành công còn response status code 500 thì thất bại. Kỹ thuật này được sử dụng nhiều trong việc check trạng thái các node trong galera cluster.

Các bạn có thể tham khảo hướng dẫn tại đây:
https://www.percona.com/doc/percona-xtradb-cluster/5.6/howtos/haproxy.html
https://github.com/olafz/percona-clustercheck

Trên backup haproxy, bạn cũng cấu hình tương tự hoặc viết một script để đồng bộ config hai bên:
/usr/local/bin/rsync_haproxy_config

#!/bin/bash
rsync -avzP  root@<MASTER HAPROXY IP>:/etc/haproxy/haproxy.cfg /etc/haproxy

Phải đảm bảo bạn đã thực hiện ssh based key authentication trên master proxy cho backup proxy.

crontab -e
* * * * * /usr/local/bin/rsync_haproxy_config

Keepalived trên master proxy

vim /etc/keepalived/keepalived.cfg

vrrp_script chk_haproxy {
    script "killall -0 haproxy"
    interval 2
}

vrrp_instance example_VI {
    state MASTER
    interface eth0
    virtual_router_id 10
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass <pass>
    }
    virtual_ipaddress {
         <VIP>/<NETMASK> dev eth0 label eth0:0
    }

    track_script {
        chk_haproxy
    }
}

Keepalived trên backup proxy

vim /etc/keepalived/keepalived.cfg

vrrp_script chk_haproxy {
    script "killall -0 haproxy"
    interval 2
}

vrrp_instance example_VI {
    state BACKUP
    interface eth0
    virtual_router_id 10
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass <pass>
    }
    virtual_ipaddress {
        <VIP>/<NETMASK> dev eth0 label eth0:0
    }

    track_script {
        chk_haproxy
    }
}

Cần chú ý:

- vrrp_instance phải khai báo tên giống nhau trên cả keepalived master và backup
- virtual_router_id cũng phải khai báo giống nhau trên cả keepalived master và backup
-  interface eth0 sẽ chỉ định interface được chọn đến gán VIP
- keepalived master sẽ có state MASTER và priority cao hơn keepalived backup có state là BACKUP
- phần authentication type và pass phải giống nhau
  <VIP>/<NETMASK> dev eth0 label eth0:0, chỉ định VIP và netmask tương ứng, cùng với interface gán VIP

Lần lượt start service haproxy và keepalived trên server master và backup nữa là xong. Bạn sẽ thấy VIP luân chuyển giữa master và backup khi bạn cố tình đánh sập proxy :D

Tham khảo:

https://www.digitalocean.com/community/tutorials/how-to-use-haproxy-to-set-up-mysql-load-balancing--3
https://www.digitalocean.com/community/tutorials/how-to-set-up-highly-available-haproxy-servers-with-keepalived-and-floating-ips-on-ubuntu-14-04
https://www.howtoforge.com/setting-up-a-high-availability-load-balancer-with-haproxy-keepalived-on-debian-lenny-p2

Không có nhận xét nào:

Đăng nhận xét