Total de visualizações de página

segunda-feira, 25 de abril de 2016

HAProxy : Load Balancing on Layer4


HAProxy : Load Balancing on Layer4
2015/02/18
 
Configure HAProxy on Layer4 Mode.
This example based on the environment like follows.
       |
-------+-----------------------------------------------
       |
       +-------------------+--------------------+
       |10.0.0.30          |10.0.0.31           |10.0.0.32
 +-----+-----+     +-------+------+     +-------+------+
 | Frontend  |     |   Backend#1  |     |   Backend#2  |
 |  HAProxy  |     |    MariaDB   |     |    MariaDB   |
 +-----------+     +--------------+     +--------------+

[1]Configure HAProxy.
[root@dlp ~]# 
vi /etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2 info
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     256
    maxsslconn  256
    user        haproxy
    group       haproxy
    daemon

defaults
      # set "mode tcp" for Layer4

    mode               tcp
    log                global
    timeout connect    10s
    timeout client     30s
    timeout server     30s

# define frontend and backend servers

frontend  mysql-in
    bind *:3306
    default_backend    backend_servers

backend backend_servers
    balance            roundrobin
    server             db01 10.0.0.31:3306 check
    server             db02 10.0.0.32:3306 check

[root@dlp ~]# 
systemctl restart haproxy 
[2]Make sure all works fine to access to the frontend server from a Client with SQL like follows.
[root@desktop ~]# 
mysql -u keystone -p -h 10.0.0.30 keystone -e "select * from table01;" 

Enter password:
+------+-------------------+
| id   | name              |
+------+-------------------+
|    1 | db01.server.world |
+------+-------------------+

[root@desktop ~]# 
mysql -u keystone -p -h 10.0.0.30 keystone -e "select * from table01;" 

Enter password:
+------+-------------------+
| id   | name              |
+------+-------------------+
|    1 | db02.server.world |
+------+-------------------+

HAProxy : Refer to the Statistics#2


HAProxy : Refer to the Statistics#2
2015/02/18
 
Configure HAProxy to see HAProxy's Statistics with commands.
[1]Install some packages.
[root@dlp ~]# 
yum -y install socat
[2]Configure HAProxy.
[root@dlp ~]# 
vi /etc/haproxy/haproxy.cfg
# add follows in the "global" section

global
      # binds UNIX sockets

    stats socket /var/lib/haproxy/stats

[root@dlp ~]# 
systemctl restart haproxy 
[3]Refer to the Statistics like follows.
# display current stats

[root@dlp ~]# 
echo "show info" | socat /var/lib/haproxy/stats stdio
Name: HAProxy
Version: 1.5.2
Release_date: 2014/07/12
Nbproc: 1
Process_num: 1
Pid: 1953
...
...
Idle_pct: 100
node: dlp.server.world
description:
# display stas with CSV

[root@dlp ~]# 
echo "show stat" | socat /var/lib/haproxy/stats stdio
# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,.....
http-in,FRONTEND,,,0,1,2000,1,0,187,0,0,1,,,,,OPEN,,,,,,,,,1,2,0,,,,0,0,0,1,,,,0,0,.....
backend_servers,www01,0,0,0,0,,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,0,67,0,,1,3,1,,0,,2,0,,.....
backend_servers,www02,0,0,0,0,,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,0,67,0,,1,3,2,,0,,2,0,,.....
backend_servers,BACKEND,0,0,0,0,200,0,0,0,0,0,,0,0,0,0,UP,2,2,0,,0,67,0,,1,3,0,,0,,.....
# display current session

[root@dlp ~]# 
echo "show sess" | socat /var/lib/haproxy/stats stdio
0x7fbc09349150: proto=tcpv4 src=10.0.0.18:55987 fe=http-in be=<NONE> srv=<none> ts=08 
age=4s calls=8 rq[f=400000h,i=0,an=1ch,rx=26s,wx=,ax=] rp[f=048200h,i=0,an=00h,rx=,wx=,ax=] 
s0=[7,8h,fd=1,ex=] s1=[0,0h,fd=2,ex=] exp=26s
0x7fbc09351d80: proto=unix_stream src=unix:1 fe=GLOBAL be=<NONE> srv=<none> ts=0b age=0s 
calls=1 rq[f=c08200h,i=0,an=00h,rx=10s,wx=,ax=] rp[f=008002h,i=0,an=00h,rx=,wx=,ax=] s0=[7,8h,fd=3,ex=] 
s1=[7,8h,fd=-1,ex=] exp=
# for other operations

# enter the interactive mode

[root@dlp ~]# 
socat readline /var/lib/haproxy/stats 
prompt
# show help

help

Unknown command. Please enter one of the following commands only :
  clear counters : clear max statistics counters (add 'all' for all counters)
  clear table    : remove an entry from a table
  help           : this message
  prompt         : toggle interactive mode with prompt
  quit           : disconnect
  show info      : report information about the running process
  show pools     : report information about the memory pools usage
  show stat      : report counters for each proxy and server
  show errors    : report last request and response errors for each proxy
  show sess [id] : report the list of current sessions or dump this session
  show table [id]: report table usage stats or dump this table's contents
  get weight     : report a server's current weight
  set weight     : change a server's weight
  set server     : change a server's state or weight
  set table [id] : update or create a table entry's data
  set timeout    : change a timeout setting
  set maxconn    : change a maxconn setting
  set rate-limit : change a rate limiting value
  disable        : put a server or frontend in maintenance mode
  enable         : re-enable a server or frontend which is in maintenance mode
  shutdown       : kill a session or a frontend (eg:to release listening ports)
  show acl [id]  : report avalaible acls or dump an acl's contents
  get acl        : reports the patterns matching a sample for an ACL
  add acl        : add acl entry
  del acl        : delete acl entry
  clear acl <id> : clear the content of this acl
  show map [id]  : report avalaible maps or dump a map's contents
  get map        : reports the keys and values matching a sample for a map
  set map        : modify map entry
  add map        : add map entry
  del map        : delete map entry
  clear map <id> : clear the content of this map
  set ssl <stmt> : set statement for ssl

# exit from interactive mode

quit

HAProxy : Refer to the Statistics#1


HAProxy : Refer to the Statistics#1
2015/02/18
 
Configure HAProxy to see HAProxy's Statistics on the web.
[1]Configure HAProxy.
[root@dlp ~]# 
vi /etc/haproxy/haproxy.cfg
# add follows in the "frontend" section

frontend  http-in
    bind *:80
      # enable statistics reports

    stats enable
      # auth info for statistics site

    stats auth admin:adminpassword
      # hide version of HAProxy

    stats hide-version
      # display HAProxy hostname

    stats show-node
      # refresh time

    stats refresh 60s
      # statistics reports' URI

    stats uri /haproxy?stats

[root@dlp ~]# 
systemctl restart haproxy 
[2]Access to the frontend server from a Client with HTTP/HTTPS, then authentication is required like follows, input the auth info you set in config.
[3]Just accessed. It's possible to refer to statistics of HAProxy on here.

HAProxy : SSL Settings


HAProxy : SSL Settings
2015/02/18
 
Configure HAProxy with SSL.
The connection between HAproxy and Clients are encrypted with SSL. ( HAproxy - backends are normal )
This example based on the environment like follows.
       |
-------+-----------------------------------------------
       |
       +-------------------+--------------------+
       |10.0.0.30          |10.0.0.31           |10.0.0.32
 +-----+-----+     +-------+------+     +-------+------+
 | Frontend  |     |   Backend#1  |     |   Backend#2  |
 |  HAProxy  |     |  Web Server  |     |  Web Server  |
 +-----------+     +--------------+     +--------------+

[1]Create SSL certificates.
[root@dlp ~]# 
cd /etc/pki/tls/certs 

[root@dlp certs]# 
openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/pki/tls/certs/haproxy.pem -out /etc/pki/tls/certs/haproxy.pem -days 365 

Generating a 2048 bit RSA private key
......++++++
.......++++++
writing new private key to '/etc/pki/tls/certs/haproxy.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
JP
# country

State or Province Name (full name) [Some-State]:
Hiroshima
   
# state

Locality Name (eg, city) []:
Hiroshima
# city

Organization Name (eg, company) [Internet Widgits Pty Ltd]:
GTS
   
# company

Organizational Unit Name (eg, section) []:
Server World
   
# department

Common Name (eg, YOUR name) []:
dlp.server.world
   
# server's FQDN

Email Address []:
root@server.world
# admin email address
[root@dlp certs]# 
chmod 600 haproxy.pem 
[2]Configure HAProxy for SSL.
[root@dlp ~]# 
vi /etc/haproxy/haproxy.cfg
# add in the "global" section

global
      # max per-process number of SSL connections

    maxsslconn     256
      # set 2048 bits for Diffie-Hellman key

    tune.ssl.default-dh-param 2048

# add follows in the "frontend" section

frontend  http-in
    bind *:80
      # specify port and certs

    bind *:443 ssl crt /etc/pki/tls/certs/haproxy.pem

[root@dlp ~]# 
systemctl restart haproxy 
[3]Make sure all works fine to access to the frontend server from a Client with HTTPS like follows.

HAProxy : HTTP Load Balancing


HAProxy : HTTP Load Balancing
2015/02/18
 
Install HAProxy to configure Load Balancing Server.
This example based on the environment like follows.
       |
-------+-----------------------------------------------
       |
       +-------------------+--------------------+
       |10.0.0.30          |10.0.0.31           |10.0.0.32
 +-----+-----+     +-------+------+     +-------+------+
 | Frontend  |     |   Backend#1  |     |   Backend#2  |
 |  HAProxy  |     |  Web Server  |     |  Web Server  |
 +-----------+     +--------------+     +--------------+

 
Configure Servers that HTTP connection to HAProxy Server is forwarded to backend Web Servers.
[1]Install HAProxy.
[root@dlp ~]# 
yum -y install haproxy
[2]Configure HAProxy.
[root@dlp ~]# 
mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.org 

[root@dlp ~]# 
vi /etc/haproxy/haproxy.cfg
# create new

global
      # for logging section

    log         127.0.0.1 local2 info
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
      # max per-process number of connections

    maxconn     256
      # process' user and group

    user        haproxy
    group       haproxy
      # makes the process fork into background

    daemon

defaults
      # running mode

    mode               http
      # use global settings

    log                global
      # get HTTP request log

    option             httplog
      # timeout if backends do not reply

    timeout connect    10s
      # timeout on client side

    timeout client     30s
      # timeout on server side

    timeout server     30s

# define frontend ( set any name for "http-in" section )

frontend http-in
      # listen 80

    bind *:80
      # set default backend

    default_backend    backend_servers
      # send X-Forwarded-For header

    option             forwardfor

# define backend

backend backend_servers
      # balance with roundrobin

    balance            roundrobin
      # define backend servers

    server             www01 10.0.0.31:80 check
    server             www02 10.0.0.32:80 check
    
[root@dlp ~]# 
systemctl start haproxy 

[root@dlp ~]# 
systemctl enable haproxy 
[3]Configure Rsyslog to get logs for HAProxy.
[root@dlp ~]# 
vi /etc/rsyslog.conf
# line 15,16: uncomment, lne 17: add

$ModLoad imudp
$UDPServerRun 514
$AllowedSender UDP, 127.0.0.1
# line 54: change like follows

*.info;mail.none;authpriv.none;cron.none
,local2.none
   /var/log/messages
local2.*                                                /var/log/haproxy.log

[root@dlp ~]# 
systemctl restart rsyslog 
[4]Change httpd settings on Backends to logging X-Forwarded-For header.
[root@www ~]# 
vi /etc/httpd/conf/httpd.conf
# line 196: change like follows

LogFormat "
\"%{X-Forwarded-For}i\"
 %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
[root@www ~]# 
systemctl restart httpd 
[5]Make sure all works fine to access to the frontend server from a Client with HTTP like follows.

LVS + Keepalived


LVS + Keepalived
2015/06/10
 
This is the Redundant configuration for LVS + Keepalived Server itself.
This example is based on the environment below.
                              |
             +----------------+-----------------+
             |                                  |
 192.168.0.30|eth0 --- VIP:192.168.0.29 --- eth0|192.168.0.31
     +-------+--------+                +--------+-------+
     | LVS+Keepalived |                | LVS+Keepalived |
     +-------+--------+                +--------+-------+
    10.0.0.30|eth1 ----- VIP:10.0.0.29 ---- eth1|10.0.0.31
             |                                  |
             +----------------+-----------------+
                              |
    +------------+            |             +------------+
    |  Backend01 |10.0.0.51   |    10.0.0.52|  Backend02 |
    | Web Server +------------+-------------+ Web Server |
    |            |eth0                  eth0|            |
    +------------+                          +------------+


 
HTTP packets to the eth0 on LVS Server are forwarded to Backend01 and Backend02 Servers with NAT.
Change the default gateway to internal IP address of LVS on both Backend Web Servers first. (it's 10.0.0.29 on the example)
[1]Install ipvsadm and keepalived.
[root@dlp ~]# 
yum -y install ipvsadm keepalived
# enable IP forward

[root@dlp ~]# 
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf 

[root@dlp ~]# 
sysctl -p
[root@dlp ~]# 
touch /etc/sysconfig/ipvsadm 

[root@dlp ~]# 
systemctl start ipvsadm 

[root@dlp ~]# 
systemctl enable ipvsadm 
[2]Configure Keepalived.
It's OK to configure the same settings except one setting on both backend servers. 
(but only for the "priority" section, Change it on both backend server.)
[root@dlp ~]# 
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.org 

[root@dlp ~]# 
vi /etc/keepalived/keepalived.conf
# create new

global_defs {
    notification_email {
        root@dlp.server.world
    }
    notification_email_from root@dlp.server.world
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id LVS_Server
}
vrrp_instance VI_1 {
    state BACKUP
    # monitored interface
    interface eth0
    # virtual router's ID
    virtual_router_id 51
    # set priority (change this value on each server)
    # (large number means priority is high)
    priority 100
    nopreempt
    # VRRP sending interval
    advert_int 1
    # authentication info between Keepalived servers
    authentication {
        auth_type PASS
        auth_pass password
    }

    virtual_ipaddress {
        # virtual IP address
        192.168.0.29 dev eth0
        10.0.0.29/24 dev eth1
    }
}
virtual_server 192.168.0.29 80 {
    # monitored interval
    delay_loop 3
    # distribution method
    lvs_sched rr
    # routing method
    lvs_method NAT
    protocol TCP

    # backend server#1
    real_server 10.0.0.51 80 {
        weight 1
        HTTP_GET {
            url {
                # monitored path
                path /
                # status code for normally state
                status_code 200
            }
            # timeout(sec)
            connect_timeout 3
        }
    }
    # backend server#2
    real_server 10.0.0.52 80 {
        weight 1
        HTTP_GET {
            url {
                path /
                status_code 200
            }
            connect_timeout 3
        }
    }
}

[root@dlp ~]# 
systemctl start keepalived 

[root@dlp ~]# 
systemctl enable keepalived 
[3]
It's OK, Access to the Service IP address and make sure it works normally. 

Configure LVS (Linux Virtual Server)


Configure LVS (Linux Virtual Server)
2015/06/10
 
Configure LVS (Linux Virtual Server) to build a load barancer.
This example is based on the environment below.
                          |
                          |
                      eth0|192.168.0.30
                    +----------+
--------------------|    LVS   |----------------------
                    +-----+----+
                      eth1|10.0.0.30
                          |
+------------+            |             +------------+
|  Backend01 |10.0.0.51   |    10.0.0.52|  Backend02 |
| Web Server +------------+-------------+ Web Server |
|            |eth0                  eth0|            |
+------------+                          +------------+

 
HTTP packets to the eth0 on LVS Server are forwarded to Backend01 and Backend02 Servers with NAT.
Change the default gateway to internal IP address of LVS on both Backend Web Servers first. (it's 10.0.0.30 on the example)
[1]Install ipvsadm.
[root@dlp ~]# 
yum -y install ipvsadm
# enable IP forward

[root@dlp ~]# 
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf 

[root@dlp ~]# 
sysctl -p
[root@dlp ~]# 
touch /etc/sysconfig/ipvsadm 

[root@dlp ~]# 
systemctl start ipvsadm 

[root@dlp ~]# 
systemctl enable ipvsadm 
[2]Configure Load Balancing.
# clear tables

[root@dlp ~]# 
ipvsadm -C
# add virtual service

# [ ipvsadm -A -t (Service IP:Port) -s (Distribution method) ]

[root@dlp ~]# 
ipvsadm -A -t 192.168.0.30:80 -s wlc 
# add backend real servers

# [ ipvsadm -a -t (Service IP:Port) -r (Real Server's IP:Port) -m ] ("m" means masquerading (NAT))

[root@dlp ~]# 
ipvsadm -a -t 192.168.0.30:80 -r 10.0.0.51:80 -m 

[root@dlp ~]# 
ipvsadm -a -t 192.168.0.30:80 -r 10.0.0.52:80 -m 
# confirm tables

[root@dlp ~]# 
ipvsadm -l 

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  dlp.server.world:http wlc
  -> 10.0.0.51:http               Masq    1      0          0
  -> 10.0.0.52:http               Masq    1      0          0
[3]It's OK, Access to the Service IP address and make sure it works normally.
By the way, there are some Distribution method like follows. 
MethodDescription
rrRobin Robin
distributes jobs equally amongst the available real servers.
wrrWeighted Round Robin
assigns jobs to real servers propor-tionally to there real servers’ weight. Servers with higher weights receive new jobs first and get more jobs than servers with lower weights. Servers with equal weights get an equal dis-tribution of new jobs.
lcLeast-Connection
assigns more jobs to real servers with fewer active jobs.
wlcWeighted Least-Connection
assigns more jobs to servers with fewer jobs and relative to the real servers' weight (Ci/Wi). This is the default.
lblcLocality-Based Least-Connection
assigns jobs destined for the same IP address to the same server if the server is not overloaded and available, otherwise assign jobs to servers with fewer jobs, and keep it for future assignment.
lblcrLocality-Based Least-Connection with Replication
assigns jobs destined for the same IP address to the least-con- nection node in the server set for the IP address. If all the node in the server set are over loaded, it picks up a node with fewer jobs in the cluster and adds it in the sever set for the target. If the server set has not been modified for the speci-fied time, the most loaded node is removed from the server set, in order to avoid high degree of replication.
dhDestination Hashing
assigns jobs to servers through looking up a statically assigned hash table by their destination IP addresses.
shSource Hashing
assigns jobs to servers through looking up a statically assigned hash table by their source IP addresses.
sedShortest Expected Delay
assigns an incoming job to the server with the shortest expected delay. The expected delay that the job will experience is (Ci + 1) / Ui if sent to the ith server, in which Ci is the number of jobs on the the ith server and Ui is the fixed service rate (weight) of the ith server.
nqNever Queue
assigns an incoming job to an idle server if there is, instead of waiting for a fast one, if all the servers are busy, it adopts the Shortest Expected Delay policy to assign the job.

Pound : URL Redirect


Pound : URL Redirect
2015/06/09
 
This is the Redirection settings from URL matching.
This example based on the environment like follows.
        |
--------+--------------------------------------------------------------------
        |
        +-------------------+--------------------+--------------------+
        |10.0.0.30          |10.0.0.51           |10.0.0.52           |10.0.0.53
 +------+-----+     +-------+------+     +-------+------+     +-------+------+
 |  Frontend  |     |   Backend#1  |     |   Backend#2  |     |   Backend#3  |
 |   Pound    |     |  Web Server  |     |  Web Server  |     |  Web Server  |
 +------------+     +--------------+     +--------------+     +--------------+

 
For example, Configure Pound like that
HTTP connections to dlp.server.world are forwarded to Backend#1,
HTTP connections to dlp.virtual.host are forwarded to Backend#2,
HTTP connections to others except above are forwarded to Backend#3.
[1]Configure Pound.
[root@dlp ~]# 
mv /etc/pound.cfg /etc/pound.cfg.org 

[root@dlp ~]# 
vi /etc/pound.cfg
User "pound"
Group "pound"
LogLevel 3
LogFacility local1
Alive 30

ListenHTTP
    Address 0.0.0.0
    Port 80
End

Service
    # define for dlp.server.world

    HeadRequire "Host: .*dlp.server.world"
    BackEnd
        Address  10.0.0.51
        Port     80
        Priority 5
    End
End

Service
    # define for dlp.virtual.host

    HeadRequire "Host: .*dlp.virtual.host"
    BackEnd
        Address  10.0.0.52
        Port     80
        Priority 5
    End
End

Service
    # define for others

    HeadRequire "Host: .*"
    BackEnd
        Address  10.0.0.53
        Port     80
        Priority 5
    End
End

[root@dlp ~]# 
systemctl restart pound 
[2]Make sure all works fine to access to the frontend server from a Client with HTTP like follows.