{"id":3612,"date":"2019-07-16T21:27:05","date_gmt":"2019-07-16T18:27:05","guid":{"rendered":"https:\/\/kifarunix.com\/?p=3612"},"modified":"2019-07-16T21:27:07","modified_gmt":"2019-07-16T18:27:07","slug":"setup-haproxy-load-balancer-on-fedora-30-fedora-29","status":"publish","type":"post","link":"https:\/\/kifarunix.com\/setup-haproxy-load-balancer-on-fedora-30-fedora-29\/","title":{"rendered":"Setup HAProxy Load Balancer on Fedora 30\/Fedora 29"},"content":{"rendered":"\n<p>This guide will take you through how to setup HAProxy Load balancer on Fedora 30\/Fedora 29. <a rel=\"noreferrer noopener\" href=\"https:\/\/www.haproxy.org\/\" target=\"_blank\">HAProxy<\/a>\u00a0provides high availability,\u00a0load balancing and proxying for TCP and HTTP-based applications. There are different algorithms that HAProxy uses for load balancing. Some of the commonly used ones include;<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Roundrobin<\/strong> &#8211;  This is the default algorithm and it enables HAProxy to select each server to server requests in turns according to their weights.<\/li><li><strong>leastconn<\/strong> &#8211; The server with the lowest number of connections receives the connections. It is recommended where very long sessions are expected, such as LDAP, SQL.<\/li><li><strong>source<\/strong> &#8211; With this algorithm, the source IP address is hashed and divided by the total weight of the running servers to designate which server will receive the request. This ensures that the same client IP address will always reach the same server as long as no                   server goes down or up. If the hash result changes due to the                   number of running servers changing, many clients will be                   directed to a different server.<\/li><\/ul>\n\n\n\n<p>There are quite a number of algorithms that HAProxy can use. You can read more about them on the <a rel=\"noreferrer noopener\" aria-label=\"documentation page (opens in a new tab)\" href=\"https:\/\/www.haproxy.org\/download\/2.1\/doc\/configuration.txt\" target=\"_blank\">documentation page<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setup HAProxy Load Balancer on Fedora 30\/Fedora 29<\/h2>\n\n\n\n<p>To basically demonstrate how HAProxy can run as a load balancer, this guide uses three virtual machines; one running as HAProxy load balancer and two other web servers serving basic html pages;<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Install HAProxy on&nbsp;Fedora 30\/Fedora 29<\/h3>\n\n\n\n<p>To begin with, run system update.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>dnf update\ndnf upgrade<\/code><\/pre>\n\n\n\n<p>Once the update is done, execute the command below to install HAProxy on Fedora 30\/Fedora 29.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>dnf install haproxy<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Configure HAProxy on Fedora 30\/Fedora 29<\/h3>\n\n\n\n<p>The main configuration file for HAProxy is <strong>\/etc\/haproxy\/haproxy.cfg<\/strong>.<\/p>\n\n\n\n<p>The default HAProxy configuration file without comments looks like in below;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>global\n    log         127.0.0.1 local2\n    chroot      \/var\/lib\/haproxy\n    pidfile     \/var\/run\/haproxy.pid\n    maxconn     4000\n    user        haproxy\n    group       haproxy\n    daemon\n    stats socket \/var\/lib\/haproxy\/stats\n    ssl-default-bind-ciphers PROFILE=SYSTEM\n    ssl-default-server-ciphers PROFILE=SYSTEM\ndefaults\n    mode                    http\n    log                     global\n    option                  httplog\n    option                  dontlognull\n    option http-server-close\n    option forwardfor       except 127.0.0.0\/8\n    option                  redispatch\n    retries                 3\n    timeout http-request    10s\n    timeout queue           1m\n    timeout connect         10s\n    timeout client          1m\n    timeout server          1m\n    timeout http-keep-alive 10s\n    timeout check           10s\n    maxconn                 3000\nfrontend main\n    bind *:5000\n    acl url_static       path_beg       -i \/static \/images \/javascript \/stylesheets\n    acl url_static       path_end       -i .jpg .gif .png .css .js\n    use_backend static          if url_static\n    default_backend             app\nbackend static\n    balance     roundrobin\n    server      static 127.0.0.1:4331 check\nbackend app\n    balance     roundrobin\n    server  app1 127.0.0.1:5001 check\n    server  app2 127.0.0.1:5002 check\n    server  app3 127.0.0.1:5003 check\n    server  app4 127.0.0.1:5004 check<\/code><\/pre>\n\n\n\n<p>Well, in this guide, we are going to comment the <strong>frontend<\/strong> and <strong>backend<\/strong> sections and define our own configurations.<\/p>\n\n\n\n<p>Below is our <strong>frontend<\/strong> configuration.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>frontend lb_01\n    bind                192.168.43.62:80        # Bind HAProxy to port 80\n    default_backend     webapp_backends         # Define default backend servers\n    option              forwardfor              # Add HTTP header \"X-Forwarded-For\" to requests<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>bind<\/strong>&nbsp;setting assigns a listener to a given IP address and port.&nbsp;<\/li><li><code><strong>default_backend<\/strong><\/code>&nbsp;gives the name of a&nbsp;<code>backend<\/code>&nbsp;to send traffic to.<\/li><li><strong>option forwardfor<\/strong> enables HTTP header &#8220;X-Forwarded-For&#8221; on all HAProxy  requests sent to the server. This header contains a value representing the client&#8217;s IP address<\/li><\/ul>\n\n\n\n<p>The backend configuration section;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>backend webapp_backends\n    balance roundrobin\n    server webapp_01.example.com  192.168.43.252:80 check\n    server webapp_02.example.com  192.168.43.174:80 check<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>balance<\/strong>&nbsp;setting defines the roundrobin load balancer scheduling algorithm.<\/li><li><strong>server<\/strong>&nbsp;setting specify the servers available in the back end.<\/li><li><strong>check<\/strong>  &#8211; enables health checks on the server. By default, a server is always considered available. If  set, the server is available when accepting periodic TCP connections, to ensure that it is really able to serve requests.<\/li><\/ul>\n\n\n\n<p>Additionally, we are going to define the <strong>listener<\/strong> statistics section.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>listen stats\n    bind 192.168.43.62:80           # Bind stats to port 80\n    stats enable                    # enable statistics reports  \n    stats hide-version              # Hide the version of HAProxy\n    stats refresh 30s               # HAProxy refresh time\n    stats show-node                 # Shows the hostname of the node\n    stats auth admin:P@ssword       # Authentication for Stats page\n    stats uri \/lb_stats             # Statistics URL<\/code><\/pre>\n\n\n\n<p> Finally, our HAProxy configuration file looks like in below (without comments);<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>global\n    log         127.0.0.1 local2\n    chroot      \/var\/lib\/haproxy\n    pidfile     \/var\/run\/haproxy.pid\n    maxconn     4000\n    user        haproxy\n    group       haproxy\n    daemon\n    stats socket \/var\/lib\/haproxy\/stats\n    ssl-default-bind-ciphers PROFILE=SYSTEM\n    ssl-default-server-ciphers PROFILE=SYSTEM\ndefaults\n    mode                    http\n    log                     global\n    option                  httplog\n    option                  dontlognull\n    option http-server-close\n    option forwardfor       except 127.0.0.0\/8\n    option                  redispatch\n    retries                 3\n    timeout http-request    10s\n    timeout queue           1m\n    timeout connect         10s\n    timeout client          1m\n    timeout server          1m\n    timeout http-keep-alive 10s\n    timeout check           10s\n    maxconn                 3000\nfrontend lb_01\n    bind\t\t192.168.0.102:80\t# Bind HAProxy to port 80\n    default_backend\twebapp_backends\t\t# Define default backend servers\n    option\t\tforwardfor\t\t# Add HTTP header \"X-Forwarded-For\" to requests\nbackend webapp_backends\n    balance roundrobin\n    server webapp_01.example.com  192.168.0.110:80 check\n    server webapp_02.example.com  192.168.0.104:80 check\nlisten stats\n    bind 192.168.0.102:80           # Bind stats to port 80\n    stats enable                    # enable statistics reports  \n    stats hide-version              # Hide the version of HAProxy\n    stats refresh 30s               # HAProxy refresh time\n    stats show-node                 # Shows the hostname of the node\n    stats auth admin:P@ssword       # Authentication for Stats page\n    stats uri \/lb_stats             # Statistics URL<\/code><\/pre>\n\n\n\n<p>To read more about the configuration options used here, check the <a rel=\"noreferrer noopener\" aria-label=\"documentation page (opens in a new tab)\" href=\"https:\/\/cbonte.github.io\/haproxy-dconv\/2.0\/intro.html\" target=\"_blank\">documentation page<\/a>. <\/p>\n\n\n\n<p>Run the configuration checks;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>haproxy -c -f \/etc\/haproxy\/haproxy.cfg<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>Configuration file is valid<\/code><\/pre>\n\n\n\n<p>Open HAProxy port on firewall.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>firewall-cmd --add-port=80\/tcp --permanent\nfirewall-cmd --reload<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Running HAProxy<\/h4>\n\n\n\n<p>You can start and enable HAProxy to run on system boot by running the commands below;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>systemctl restart haproxy\nsystemctl enable haproxy<\/code><\/pre>\n\n\n\n<p>Check the status of HAProxy.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>systemctl status haproxy<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>\u25cf haproxy.service - HAProxy Load Balancer\n   Loaded: loaded (\/usr\/lib\/systemd\/system\/haproxy.service; enabled; vendor preset: disabled)\n   Active: active (running) since Mon 2019-07-15 02:39:48 EAT; 1min 3s ago\n Main PID: 12099 (haproxy)\n    Tasks: 2 (limit: 1143)\n   Memory: 2.3M\n   CGroup: \/system.slice\/haproxy.service\n           \u251c\u250012099 \/usr\/sbin\/haproxy -Ws -f \/etc\/haproxy\/haproxy.cfg -p \/run\/haproxy.pid\n           \u2514\u250012100 \/usr\/sbin\/haproxy -Ws -f \/etc\/haproxy\/haproxy.cfg -p \/run\/haproxy.pid\n\nJul 15 02:39:47 fedora29.example.com systemd[1]: Starting HAProxy Load Balancer...\nJul 15 02:39:48 fedora29.example.com systemd[1]: Started HAProxy Load Balancer.<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Configure HAProxy Logging<\/h3>\n\n\n\n<p>In order to configure HAProxy standard logging, edit <strong>\/etc\/rsyslog.conf<\/strong> and enable UDP syslog reception on port 514 by removing comments (<strong>#<\/strong>) on the lines, <strong>#module(load=&#8221;imudp&#8221;)<\/strong> and <strong>#input(type=&#8221;imudp&#8221; port=&#8221;514&#8243;)<\/strong> as shown below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>vim \/etc\/rsyslog.conf<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n# Provides UDP syslog reception\n# for parameters see http:\/\/www.rsyslog.com\/doc\/imudp.html\nmodule(load=\"imudp\") # needs to be done just once\ninput(type=\"imudp\" port=\"514\")\n...<\/code><\/pre>\n\n\n\n<p>Next, disable logging of messages sent to <strong>local2<\/strong> facility on, (<strong>local2.none<\/strong>) on <strong>\/var\/log\/messages<\/strong> and enable logging on <strong>\/var\/log\/haproxy.log<\/strong> as shown below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>...\n*.info;mail.none;authpriv.none;cron.none,<strong>local2.none<\/strong>                \/var\/log\/messages\nlocal2.* \/var\/log\/haproxy.log<\/code><\/pre>\n\n\n\n<p>Save the configuration file and run the command below to check for any errors.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>rsyslogd -N1<\/code><\/pre>\n\n\n\n<p>Next, restart Rsyslog.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>systemctl restart rsyslog<\/code><\/pre>\n\n\n\n<p>Restart HAProxy<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>systemctl restart haproxy<\/code><\/pre>\n\n\n\n<p>You should now be able to have HAProxy logs on \/var\/log\/haproxy.log.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>tail -f \/var\/log\/haproxy.log<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Jul 16 16:52:07 localhost haproxy[2050]: 192.168.0.103:45190 [16\/Jul\/2019:16:52:07.214] lb_01 webapp_backends\/webapp_02.example.com 0\/0\/0\/1\/1 200 358 - - ---- 2\/1\/0\/0\/0 0\/0 \"GET \/ HTTP\/1.1\"\nJul 16 16:52:07 localhost haproxy[2050]: 192.168.0.103:45190 [16\/Jul\/2019:16:52:07.374] lb_01 webapp_backends\/webapp_01.example.com 0\/0\/0\/1\/2 200 358 - - ---- 2\/1\/0\/0\/0 0\/0 \"GET \/ HTTP\/1.1\"<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Configure Apache X-Forwarded-For Logging<\/h3>\n\n\n\n<p>Since we have configured HAProxy to add HTTP header &#8220;X-Forwarded-For&#8221; to all requests sent to the backend server (<strong>option        forwardfor<\/strong>), you can configure logging for the same on the backend server. This ensures the IP address of the requesting client is captured instead of the HAProxy load balancer.<\/p>\n\n\n\n<p>Therefore, login to the backend servers and configure Apache to log X-Forwarded-For headers. The default line we are changing is;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n    LogFormat \"\\\"%{X-Forwarded-For}i\\\" %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined\n    LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common\n...<\/code><\/pre>\n\n\n\n<p>Hence, edit this line such that it looks like;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\nLogFormat \"\\\"%{X-Forwarded-For}i\\\" %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined\n...<\/code><\/pre>\n\n\n\n<p>Save the file and run Apache configuration file syntax check command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>apachectl configtest<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>Syntax OK<\/code><\/pre>\n\n\n\n<p>Restart Apache<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>systemctl restart httpd<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Testing HAProxy Load Balancer<\/h3>\n\n\n\n<p>To test HAProxy, navigate to the browser and enter the IP address of the HAProxy. When loaded and refreshed, the content from each web server is served in turns since we are using the <strong>roundrobin<\/strong> algorithm.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2019\/07\/haproxy-loadbalancer_webapp01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"641\" height=\"116\" src=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2019\/07\/haproxy-loadbalancer_webapp01.png\" alt=\"Setup HAProxy Load Balancer on Fedora 30\/Fedora 29\" class=\"wp-image-3650\" title=\"\"><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2019\/07\/haproxy-loadbalancer_webapp02.png\"><img loading=\"lazy\" decoding=\"async\" width=\"638\" height=\"109\" src=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2019\/07\/haproxy-loadbalancer_webapp02.png\" alt=\"haproxy load balancer\" class=\"wp-image-3651\" title=\"\"><\/a><\/figure>\n\n\n\n<p>You can also check HAProxy statistics using the URL defined on the <strong>listen<\/strong> configuration section, <strong>http:\/\/IP-Address\/lb_stats<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2019\/07\/haproxy_statistics.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1354\" height=\"475\" src=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2019\/07\/haproxy_statistics.png\" alt=\"haproxy statistics page\" class=\"wp-image-3652\" title=\"\" srcset=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2019\/07\/haproxy_statistics.png 1354w, https:\/\/kifarunix.com\/wp-content\/uploads\/2019\/07\/haproxy_statistics-768x269.png 768w\" sizes=\"(max-width: 1354px) 100vw, 1354px\" \/><\/a><\/figure>\n\n\n\n<p>Well there you go. You HAProxy on Fedora 30\/Fedora 29 is now running. To read more about HAProxy configuration, refer to<a href=\"http:\/\/www.haproxy.org\/download\/1.8\/doc\/configuration.txt\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" HAProxy configuration page (opens in a new tab)\"> HAProxy configuration page<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Related Tutorials<\/h3>\n\n\n\n<p><a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/kifarunix.com\/configure-haproxy-with-ssl-on-ubuntu-18-04-debian-10-9\/\" target=\"_blank\">Configure HAProxy Load Balancer with SSL on Ubuntu 18.04\/Debian 10\/9<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/kifarunix.com\/how-to-install-and-configure-pound-apache-load-balancer-on-ubuntu-16-04\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">How to Install and Configure Pound as Apache HTTP Load balancer on Ubuntu 16.04<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This guide will take you through how to setup HAProxy Load balancer on Fedora 30\/Fedora 29. HAProxy\u00a0provides high availability,\u00a0load balancing and proxying for TCP and<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rank_math_lock_modified_date":false,"footnotes":""},"categories":[1032,121,92],"tags":[289,924,1033,95],"class_list":["post-3612","post","type-post","status-publish","format-standard","hentry","category-haproxy","category-howtos","category-load-balancers","tag-fedora-29","tag-fedora-30","tag-haproxy","tag-load-balancer","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50"],"_links":{"self":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/3612"}],"collection":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/comments?post=3612"}],"version-history":[{"count":13,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/3612\/revisions"}],"predecessor-version":[{"id":3654,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/3612\/revisions\/3654"}],"wp:attachment":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media?parent=3612"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/categories?post=3612"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/tags?post=3612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}