HAProxy LB
When you’re working with a Kubernetes cluster, having a separate external proxy that enables different public IP addresses for each application can be beneficial. In this post, we delve into setting up HAProxy as a frontend load balancer for Kubernetes cluster ingress, focusing on Layer 7 load balancing, SSL offloading, and maintaining separate public IPs via an external proxy.
Understanding the Topology
To give you a visual understanding of what we aim to achieve, consider the following flowchart, where Users are directed to their respective clusters based on the URLs they access:
flowchart LR A[User] ---> | https://aaa.com | B(Internet) 0[User] ---> | https://bbb.com | B(Internet) B --> | https URL | C{HAProxy} C --->|http://aaa.com| D[Cluster A Ingress worker-01] C --->|http://aaa.com| E[Cluster A Ingress worker-02] C --->|http://aaa.com| F[Cluster A Ingress worker-03] C --->|http://bbb.com| G[Cluster B Ingress worker-01] C --->|http://bbb.com| H[Cluster B Ingress worker-02] C --->|http://bbb.com| I[Cluster B Ingress worker-03]
To facilitate this, we will use a HAProxy configuration based on ACL (Access Control Lists)…
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
cache mycache
total-max-size 4095 # MB
max-object-size 10000 # bytes
max-age 30 # seconds
frontend http-in
bind :443 ssl crt /usr/local/etc/haproxy/ssl-bundle.crt
mode http
option httplog
redirect scheme https if !{ ssl_fc }
acl http ssl_fc,not
acl https ssl_fc
http-request set-header X-Forwarded-Protocol http if http
http-request set-header X-Forwarded-Protocol https if https
log global
acl from_cf src -f /etc/haproxy/CF_ips.lst
acl cf_ip_hdr req.hdr(CF-Connecting-IP) -m found
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)] if from_cf cf_ip_hdr
http-request set-src hdr(x-forwarded-for) if from_cf
http-request set-var(sess.cloudflare) always_true if { http_first_req } from_cf
acl is_aaa_com hdr_end(host) -i aaa.com
use_backend aaa_com if is_aaa_com
acl is_bbb_com hdr_end(host) -i bbb.com
use_backend bbb_com if is_bbb_com
backend aaa_com
log global
mode http
option forwardfor
http-request cache-use mycache
http-response cache-store mycache
compression algo gzip
compression type text/html "text/html; charset=utf-8" text/html;charset=utf-8 text/plain text/css text/javascript application/x-javascript application/javascript application/ecmascript application/rss+xml application/atomsvc+xml application/atom+xml application/atom+xml;type=entry application/atom+xml;type=feed application/cmisquery+xml application/cmisallowableactions+xml application/cmisatom+xml application/cmistree+xml application/cmisacl+xml application/msword application/vnd.ms-excel application/vnd.ms-powerpoint image/svg+xml
balance roundrobin
option httpchk
http-check send hdr User-Agent "HAproxy-health-check" meth HEAD uri / hdr Host "aaa.com"
cookie SERVERUID insert indirect nocache httponly secure
server a-worker-01 192.168.0.2:80 cookie ingress-01 check
server a-worker-02 192.168.0.3:80 cookie ingress-02 check
server a-worker-03 192.168.0.4:80 cookie ingress-03 check
backend bbb_com
log global
mode http
option forwardfor
http-request cache-use mycache
http-response cache-store mycache
compression algo gzip
compression type text/html "text/html; charset=utf-8" text/html;charset=utf-8 text/plain text/css text/javascript application/x-javascript application/javascript application/ecmascript application/rss+xml application/atomsvc+xml application/atom+xml application/atom+xml;type=entry application/atom+xml;type=feed application/cmisquery+xml application/cmisallowableactions+xml application/cmisatom+xml application/cmistree+xml application/cmisacl+xml application/msword application/vnd.ms-excel application/vnd.ms-powerpoint image/svg+xml
balance roundrobin
option httpchk
http-check send hdr User-Agent "HAproxy-health-check" meth HEAD uri / hdr Host "bbb.com"
cookie SERVERUID insert indirect nocache httponly secure
server b-worker-01 192.168.0.5:80 cookie ingress-01 check
server b-worker-02 192.168.0.6:80 cookie ingress-02 check
server b-worker-03 192.168.0.7:80 cookie ingress-03 check
frontend stats
bind 192.168.0.61:8404
mode http
option httpclose
http-request use-service prometheus-exporter if { path /metrics }
stats enable
stats uri /stats
stats refresh 10s
listen statistic
bind 192.168.0.61:9000
mode http
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /
stats auth haproxy:<password>
By following these steps, you can successfully set up HAProxy as a frontend load balancer for your Kubernetes cluster ingress. This setup will not only enhance your load balancing capabilities on Layer 7 but also facilitate SSL offloading. Further, it allows you to maintain separate public IPs for each of your applications via an external proxy, adding an extra layer of security and manageability to your Kubernetes deployments.
Optimizing Web Performance with HAProxy Caching
Caching is an integral part of any high-performing web infrastructure, and HAProxy, a powerful and flexible load balancer, doesn’t shy away from providing robust caching capabilities. HAProxy’s in-memory cache, aptly named mycache
in our configuration, improves response times by storing and delivering frequently accessed data directly to the client, thereby reducing the load on backend servers.
The mycache
configuration operates on three key parameters: total-max-size
, max-object-size
, and max-age
. Let’s delve into these parameters to understand their roles and how you can optimize them.
cache mycache
total-max-size 4095 # MB
max-object-size 10000 # bytes
max-age 30 # seconds
-
total-max-size
: Defines the maximum size of the cache in megabytes (MB). In our case, it’s set to 4095 MB, allocating about 4GB of RAM for the cache. Be cautious while setting this value as it directly impacts your server’s memory consumption. -
max-object-size
: Specifies the maximum size of an individual object that can be stored in the cache. It’s measured in bytes, and we’ve set it to 10000 bytes or roughly 10KB. Any object larger than this size won’t be cached. -
max-age
: Determines how long an object stays in the cache before it’s considered stale and is subsequently removed. The value is given in seconds, with our configuration set to hold objects for 30 seconds.
By understanding and effectively managing these parameters, you can tailor your HAProxy cache to align with your application needs, significantly boosting web performance and ensuring a smoother user experience.
A deep dive into HAProxy’s frontend configuration. Learn how to implement SSL, set HTTP headers, and use ACLs for efficient traffic management.
In the intricate web of network traffic management, HAProxy’s frontend configuration plays a pivotal role. It serves as the first point of contact for client requests and decides how to direct traffic to backend servers. The frontend configuration, encompassing SSL implementation, HTTP headers management, and Access Control Lists (ACLs), can significantly enhance your server’s security and efficiency.
frontend http-in
bind :443 ssl crt /usr/local/etc/haproxy/ssl-bundle.crt
mode http
option httplog
redirect scheme https if !{ ssl_fc }
acl http ssl_fc,not
acl https ssl_fc
http-request set-header X-Forwarded-Protocol http if http
http-request set-header X-Forwarded-Protocol https if https
log global
acl from_cf src -f /etc/haproxy/CF_ips.lst
acl cf_ip_hdr req.hdr(CF-Connecting-IP) -m found
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)] if from_cf cf_ip_hdr
http-request set-src hdr(x-forwarded-for) if from_cf
http-request set-var(sess.cloudflare) always_true if { http_first_req } from_cf
acl is_aaa_com hdr_end(host) -i aaa.com
use_backend aaa_com if is_aaa_com
acl is_bbb_com hdr_end(host) -i bbb.com
use_backend bbb_com if is_bbb_com
-
bind :443 ssl crt /usr/local/etc/haproxy/ssl-bundle.crt
: This line instructs HAProxy to bind to port 443 (the default HTTPS port) and implement SSL using the provided certificate bundle. Key file name ssl-bundle.crt.key . -
redirect scheme https if !{ ssl_fc }
: Here, HAProxy checks if the incoming connection uses SSL (ssl_fc
). If not, it redirects the client to the HTTPS version of the requested URL, enhancing your application’s security. -
http-request set-header X-Forwarded-Protocol ...
: These lines set theX-Forwarded-Protocol
header to eitherhttp
orhttps
based on the scheme of the incoming request. This information can be helpful for your backend servers to understand the client’s original protocol. -
acl from_cf src -f /etc/haproxy/CF_ips.lst
and subsequent lines: These Access Control Lists (ACLs) and associated actions deal with traffic from Cloudflare, setting appropriate headers and source IPs based on Cloudflare’s connecting IPs. -
acl is_aaa_com hdr_end(host) -i aaa.com
andacl is_bbb_com hdr_end(host) -i bbb.com
: These ACLs determine which backend to use based on the host header of the incoming HTTP request. If the host header ends withaaa.com
, the request is forwarded toaaa_com
backend, and if it ends withbbb.com
, the request is directed tobbb_com
backend.
By leveraging HAProxy’s robust frontend configuration, you can ensure not only the secure transmission of data but also efficient and intelligent traffic management, leading to an optimized and secure web environment.
Explore HAProxy’s backend configuration and learn how to balance loads, optimize traffic, and maintain high availability for your web services.
When it comes to serving client requests, the configuration of the backend servers in HAProxy plays a crucial role. This section covers several features of a typical HAProxy backend configuration, including load balancing, caching, compression, health checking, and session persistence.
backend aaa_com
log global
mode http
option forwardfor
http-request cache-use mycache
http-response cache-store mycache
compression algo gzip
compression type text/html "text/html; charset=utf-8" text/html;charset=utf-8 text/plain text/css text/javascript application/x-javascript application/javascript application/ecmascript application/rss+xml application/atomsvc+xml application/atom+xml application/atom+xml;type=entry application/atom+xml;type=feed application/cmisquery+xml application/cmisallowableactions+xml application/cmisatom+xml application/cmistree+xml application/cmisacl+xml application/msword application/vnd.ms-excel application/vnd.ms-powerpoint image/svg+xml
balance roundrobin
option httpchk
http-check send hdr User-Agent "HAproxy-health-check" meth HEAD uri / hdr Host "aaa.com"
cookie SERVERUID insert indirect nocache httponly secure
server a-worker-01 192.168.0.2:80 cookie ingress-01 check
server a-worker-02 192.168.0.3:80 cookie ingress-02 check
server a-worker-03 192.168.0.4:80 cookie ingress-03 check
-
option forwardfor
: The ‘forwardfor’ option enables HAProxy to include the client’s IP address in the request forwarded to the backend server, which is often required for client tracking or blacklisting purposes. -
http-request cache-use mycache
andhttp-response cache-store mycache
: These directives instruct HAProxy to use the ‘mycache’ cache for serving and storing HTTP requests and responses, respectively. This can significantly speed up response times for cacheable resources. -
compression algo gzip
andcompression type ...
: These lines enable and configure gzip compression for various types of responses, which can reduce bandwidth usage and improve response times, especially for text-based resources. -
balance roundrobin
: The ‘roundrobin’ balancing algorithm distributes incoming requests evenly across the available servers, helping to maintain high availability and prevent any single server from becoming a bottleneck. -
http-check send hdr ...
: This directive configures HAProxy to send health check requests to the backend servers. If a server does not respond to the health check, HAProxy will stop sending requests to it until it becomes responsive again. -
cookie SERVERUID insert indirect nocache httponly secure
: This line manages session persistence through cookies. It tells HAProxy to insert a cookie named ‘SERVERUID’ into the response if the request didn’t initially contain this cookie. This way, subsequent requests from the same client will be directed to the same backend server, which is crucial for session-dependent applications. -
server a-worker-01 192.168.0.2:80 cookie ingress-01 check
: These lines define the backend servers. The ‘check’ option enables health checking for these servers.
By understanding these various aspects of HAProxy’s backend configuration, you can tailor it to your specific needs, ensuring efficient traffic management, optimal server performance, and high availability for your services.
Dive into the details of HAProxy’s statistics and metrics exposition configuration, exploring the significance of different directives in gathering and viewing vital performance data.
Maintaining a high-performance infrastructure requires constant monitoring and analysis of your HAProxy load balancer. By exposing essential statistics and metrics, HAProxy provides visibility into your application’s health and performance. In this post, we will discuss some crucial HAProxy configuration parts that enable statistics exposition and how they contribute to a more transparent and manageable system.
frontend stats
bind 192.168.0.61:8404
mode http
option httpclose
http-request use-service prometheus-exporter if { path /metrics }
stats enable
stats uri /stats
stats refresh 10s
listen statistic
bind 192.168.0.61:9000
mode http
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /
stats auth haproxy:<password>
-
bind 192.168.0.61:8404
andbind 192.168.0.61:9000
: These lines tell HAProxy to bind the stats frontend and the ‘statistic’ listen block to specific IP addresses and ports. The bind directive determines where HAProxy listens for incoming connections. -
mode http
: This directive sets the mode to HTTP, meaning HAProxy will treat all incoming connections as HTTP requests. This is vital because the statistics interface is a web page that provides real-time data in an HTTP-friendly format. -
http-request use-service prometheus-exporter if { path /metrics }
: This configuration line is specifically tailored for integration with Prometheus, a popular open-source monitoring and alerting toolkit. It instructs HAProxy to use the prometheus-exporter service if the request path is ‘/metrics’. This service converts the statistics from HAProxy’s native format into a format that Prometheus can understand. -
stats enable
,stats uri /stats
, andstats refresh 10s
: These directives are related to HAProxy’s built-in statistics module. The ‘stats enable’ directive turns on the statistics module, the ‘stats uri’ defines the URL where the statistics page can be accessed, and ‘stats refresh’ sets the refresh rate of the statistics page to 10 seconds. -
stats enable
,stats hide-version
,stats realm Haproxy\ Statistics
,stats uri /
, andstats auth haproxy:<password>
: In the ’listen statistic’ block, these directives enable the stats, hide the HAProxy version from the stats page, set a realm for HTTP authentication, define the URI for accessing the stats page, and set up authentication credentials, respectively. These settings provide both a layer of security and a user-friendly interface to access your HAProxy statistics.
Through these settings, HAProxy allows you to monitor its performance and gain insights into your application’s behavior, helping you make informed decisions about resource allocation, troubleshooting, and system improvements.
In conclusion ,configuring HAProxy appropriately is pivotal to the optimal functioning and management of your infrastructure. Every directive and line of code in the configuration plays a crucial role in maintaining the balance between resource allocation, security, and performance. Understanding and effectively implementing these elements, from setting up frontends and backends, managing caching and compression, to exposing detailed statistics for monitoring, can make a significant difference in how your system performs under varying loads.
However, the configuration of HAProxy is not a one-time task. It requires constant monitoring, tweaking, and tuning according to the evolving requirements of your system. The robust and flexible nature of HAProxy allows it to adapt to these changes, making it a highly reliable solution for load balancing and proxying HTTP and TCP applications.
In the end, the power of HAProxy is as vast as your ability to harness its features and capabilities. The more familiar you become with its intricacies, the better you can utilize it to create a robust, resilient, and highly available system. Don’t be afraid to delve deeper into the documentation, experiment with different configurations, and optimize the setup to meet your specific needs. Remember, a well-configured HAProxy is an invaluable asset to any high-performance application infrastructure.
Strengthening Security with HAProxy in Your Kubernetes Environment
In today’s digital landscape, the protection and security of data and services have never been more critical. Implementing robust security measures in a Kubernetes environment can sometimes be challenging due to the complex nature of the system. However, using HAProxy as a frontline barrier offers an efficient way to enhance security significantly.
HAProxy acts as a sturdy shield, intercepting all incoming traffic and protecting the Kubernetes cluster from direct access. This approach has a twofold benefit. Firstly, it controls and secures the flow of traffic entering the Kubernetes ecosystem, minimizing the exposure to potential external threats. Secondly, it liberates the cluster from handling client connections directly, thereby reserving more resources for processing requests internally and improving overall efficiency.
One standout feature of HAProxy is its ability to provide SSL termination. In a time when data security is paramount, the SSL termination feature ensures that all data is encrypted when in transit, providing a secure communication channel and enhancing data privacy.
Moreover, HAProxy can enforce Access Control Lists (ACLs) and rate-limiting policies to mitigate common web threats, such as DDoS attacks. By defining and applying appropriate ACLs, the traffic reaching your services can be adequately controlled, mitigating risks and potential vulnerabilities. Rate limiting can also be used to limit the number of requests a client can make to your service within a certain timeframe, protecting your services from being overwhelmed by an influx of traffic.
HAProxy’s extensive logging capability offers another layer of security. Monitoring traffic patterns in real-time helps to identify and mitigate potential threats before they can impact your services. Regular log analysis can also provide insights into usage patterns and performance, offering valuable data for capacity planning and infrastructure optimization.
However, while HAProxy offers many security enhancements, it’s crucial to remember that no single tool or approach can offer complete protection. Regular audits of your HAProxy and Kubernetes configurations, staying updated with the latest software versions, and following best security practices are all critical components of maintaining a secure system.
In conclusion, the integration of HAProxy into your Kubernetes architecture provides a vital line of defense, allowing your Kubernetes cluster to focus on efficiently orchestrating your containers and running your applications smoothly. With HAProxy in place, you can enjoy a more secure, controlled, and performant Kubernetes environment.