Un monde d'octets

Aller au contenu | Aller au menu | Aller à la recherche

dimanche, avril 28 2019

Haproxy et check des backend

Lors de la mise en place d'un haproxy, le check des backend évite d'envoyer vers un backend non disponible.

Il existe plusieurs types de check (cf la documentation, mais nous allons en regarder quelques un de simple et efficaces.

httpchk

Le check http basique :

    option httpchk OPTIONS / HTTP/1.0
    http-check expect rstatus (2|3)[0-9][0-9]
    default-server inter 3s fall 3 rise 2
    server selphie 172.27.236.2:80 maxconn 32 check

le check à la fin de la directive server indique que le contrôle doit être fait, la ou httpchk et http-check expect précisent comment faire.

Ce contrôle repose sur la réponse à la directive OPTIONS du serveur web. il faut donc la mettre en place sur votre apache ou nginx

exemple sur nginx :

        location / {
                if ($request_method = OPTIONS ) {
                   add_header Content-Length 0;
                   add_header Content-Type text/plain;
                   return 200;
                }
        }

Il est aussi possible de faire un test sur la réponse d'une page, mais la encore, le plus complet reste la documentation officielle.

tcp check

Le tcp-check permet de simplement vérifier que le port est ouvert. Il est utile pour apache si on se moque de vérifier un état précis du serveur, mais surtout pour les autres services que nous voudrions proxiser avec haproxy (car ou, haproxy peut servir de frontal haute disponibilité à tout service tcp, dont ldap, pop, imap, rdp ...)

    option tcp-check
    option forwardfor except 127.0.0.1
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    http-request replace-header X-Location-Path /cluster /
    server web1 10.40.0.6 weight 100 check port 80
    server web2 10.40.0.8 weight 100 check port 80

ici c'est l'ajout de check qui précise qu'il doit y avoir contrôle, et port XX quel port contrôler par une connexion tcp.

Nous pouvons aussi faire en sorte que dans un cas multi-servers en backend, nous renvoyons un utilisateur toujours vers le même serveur. Pour cela, nous rajoutons dans le backend, les directives :

	stick-table type ip size 200k expire 30m
	stick on src

mercredi, janvier 10 2018

Haproxy basics

apt install haproxy

la conf de base mise en place est la suivante :

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

        # Default ciphers to use on SSL-enabled listening sockets.
        # For more information, see ciphers(1SSL). This list is from:
        #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
        # An alternative list with additional directives can be obtained from
        #  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxyL7OK/200 in 0ms
Layer7 check passed: OK
        ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
        ssl-default-bind-options no-sslv3

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

Définissions notre premier serveur web :

frontend web01
    bind *:80
    mode http
    default_backend web01-backends

backend web01-backends
    mode http
    balance roundrobin
    option forwardfor
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    option httpchk HEAD / HTTP/1.1\r\nHost:localhost
    server http1 172.17.0.2:80 check weight 100
    server http2 172.17.0.3:80 check weight 50
    server http3 172.17.0.4:80 check weight 50

Notre serveur web01 est paramétré avec trois backends pondérés (100/50/50) vers des container docker faisant tourner apache. L'option "check" vérifie la disponibilité du nœud et ne le servira plus si le check échoue.

Il y'a beaucoup d'options disponibles pour les frontend et backend, comme les acls pour faire un frontend "selectif" ou d'autres options que "check" et "weight" dans les backend. J'essayerai de faire un post ultérieur pour les options et acls les plus utiles !

Deuxième cas, un frontend tcp ! Car oui, dans le cas d'un serveur web, nous avons utilisé un frontend http qui permet comme on le voir dans le backend d'ajouter des informations à l'entête pour informer le serveur réel de la provenance de la demande.Mais dans un cas de ssh, cela n'est pas pertinent :

frontend tk-ssh
    bind *:2222
    mode tcp
    default_backend tk-ssh-backends

backend tk-ssh-backends
    mode tcp
    balance roundrobin
    server host-ssh1 10.0.0.9:22 check
    server host-ssh2 10.0.0.6:22 check

Ici on voit qu'on peut distinguer le port d'écoute du hlb du port réel du service. Certes, c'est banalement affligeant, mais c'est bon à savoir.

Dans ce cas, si nous ne précisons pas :22 dans le backend, le haproxy conservera le port d'écoute.

Dans tous les cas, il est bon d'être explicite !

Dernier point, l'ajout de stats :

listen stats
    bind :9000
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /stats
    stats auth Username:Password 

Cette configuration permet d'accéder aux statistiques via l'url : http://haproxy:9000/stats

Mais il y'a mieux !

Dans la configuration de base que met en place ubuntu pour le package haproxy, la socket unix /run/haproxy/admin.sock est en level admin pour haproxy.

Ce qui nous permet de dialoguer avec haproxy en ligne de commande :

Désactiver un backend pour maintenance :

echo "disable server web01-backends/http2" | nc -U /run/haproxy/admin.sock

Réactiver le noeud :

echo "enable server web01-backends/http2" | nc -U /run/haproxy/admin.sock