Configuration environnement local
mkdir ~/.config/lxc/
echo "lxc.include = /etc/lxc/default.conf" > ~/.config/lxc/defaults.conf
echo "lxc.id_map = u 0 100000 65536" > ~/.config/lxc/defaults.conf
echo "lxc.id_map = g 0 100000 65536" > ~/.config/lxc/defaults.conf
echo "lxc.lxcpath=/srv/containers/lxc" > ~/.config/lxc/lxc.conf
sudo mkdir -p /srv/containers/lxc
sudo chown 10000 /srv/containers/lxc
sudo chmod g+w /srv/containers/lxc
Creation container
TODO: voir comment faire un template local
lxc-create -t download -n lxc-debian
Les donnés du container seront dans /srv/containers/lxc/lxc-debian
Lancer une instance éphémère, c'est à dire qu'elle se supprime après le stop.
lxc-copy --name lxc-debian -N p1
Connaître les données de configuration de p1 (@IP ...)
lxc-ls --fancy
Se connecter à la machine en mode admin
lxc-attach --name p1
Arrêter la machine p1
lxc-stop --name p1
Exemple de workflow : créer un service web
On clone la base
lxc-copy --name lxc-debian -N lxc-webserver
On installe et configure le service web : DocumentRoot par défaut /var/www/html
lxc-start -n lxc-webserver
lxc-attach -n lxc-webserver
apt install nginx
exit
lxc-ls --fancy
NAME STATE AUTOSTART GROUPS IPV4 IPV6
lxc-debian STOPPED 0 - - -
lxc-webserver RUNNING 0 - 10.0.3.250 -
# Test
curl http://10.0.3.250
# \o/
On crée les env de test
mkdir -p ${HOME}/src/LXC-CONF/web/site{1,2}
echo "site 1" > ${HOME}/src/LXC-CONF/web/site1/index.html
echo "site 2" > ${HOME}/src/LXC-CONF/web/site2/index.html
on lance une instance pour chaque site
lxc-copy -n lxc-webserver -e -m bind=${HOME}/src/LXC-CONF/web/site1:/var/www/html:ro -N site1
lxc-copy -n lxc-webserver -e -m bind=${HOME}/src/LXC-CONF/web/site2:/var/www/html:ro -N site2
lxc-ls --fancy
NAME STATE AUTOSTART GROUPS IPV4 IPV6
lxc-debian STOPPED 0 - - -
lxc-webserver STOPPED 0 - - -
site1 RUNNING 0 - 10.0.3.250 -
site2 RUNNING 0 - 10.0.3.127 -
# tests
curl http://10.0.3.250
Site 1
curl http://10.0.3.127
Site 2
# \o/
Résolution de nom
Par défaut, lxc lance dnsmasq pour le réseau des conteneurs. Par défaut depuis le début c'est le réseau 10.0.3.0/24. L'adresse de l'hôte est 10.0.3.1. C'est à cette adresse que la résolution se fait. Si on souhaite résoudre les sites en dehors d'un conteneur, si rien n'est configuré, il faut donner explicitement le nom du serveur dns aux commandes de résolution :
host site1 10.0.3.1
Using domain server:
Name: 10.0.3.1
Address: 10.0.3.1#53
Aliases:
site1 has address 10.0.3.250
On voit que pour monter du site à la demande, il faut faire des ajustements : * du NAT/PAT ou bridge depuis le serveur hôte ou alors un mod_proxy * configurer le dns de l'hôte pour utiliser les noms des sites plutôt que leur @IP
Pour forcer les @IP des serveurs, soit on le fixe dans les conteneurs, soit on le fixe dans la configuration de dnsmasq.
Pour continuer, j'ai choisi la seconde solution plus flexible.Sur la Debian, il faut éditer le fichier /etc/default/lxc-net et dé commenter la ligne contenant la déclaration de la variable LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
Puis définir les @ip en fonction des noms de conteneurs
cat /etc/lxc/dnsmasq.conf
dhcp-host=site1,10.0.3.101
dhcp-host=site2,10.0.3.102
... et on relance le service réseau de lxc
systemctl restart lxc-net.service
En relançant les conteneurs site1 et site2, on vérifie bien que les @IP sont celles affectées dans le fichier de conf de DNSMASQ.
HAPROXY
Pour tester un mécanisme de HA avec les deux sites web, j'ai décidé de tester haproxy dans un conteneur.
Je décide de fixer l'@IP du conteneur :
echo "dhcp-host=haproxy,10.0.3.100" | sudo tee -a /etc/lxc/dnsmasq.conf'
sudo systemctl restart lxc-net.service
Comme pour les serveurs web, je fais une copie du conteneur lxc-debian en lxc-haproxy qui va me servir de modèle. Ce nouveau modèle doit être exécuté pour l'installation de haproxy.
lxc-copy -n lxc-debian -N lxc-haproxy
lxc-start -n lxc-haproxy
lxc-attach -n lxc-haproxy
apt install haproxy haproxyctl
exit
La configuration de haproxy se fait à l'aide du fichier de configuration /etc/haproxy/haproxy.cfg
Pur permettre une configuration en dehors du conteneur, on va créer un fichier de configuration dans l'environnement de tests et l'utiliser via un point de montage lors du lancement du conteneur.
mkdir -p ${HOME}/src/LXC-CONF/web/haproxy
Créer le fichier ${HOME}/src/LXC-CONF/web/haproxy/haproxy.cfg avec la configuration souhaitée (cf exemple en Annexes) puis lancer le service haproxy
lxc-copy -n lxc-haproxy -e -m bind=${HOME}/src/LXC-CONF/web/haproxy:/etc/haproxy:ro -N haproxy
Test de bon fonctionnement:
lxc-ls --fancy
NAME STATE AUTOSTART GROUPS IPV4 IPV6
haproxy RUNNING 0 - 10.0.3.100 -
lxc-debian STOPPED 0 - - -
lxc-haproxy STOPPED 0 - - -
lxc-webserver STOPPED 0 - - -
site1 RUNNING 0 - 10.0.3.101 -
site2 RUNNING 0 - 10.0.3.102 -
for i in $(seq 1 10); do curl http://10.0.3.100/; done
Site 1
Site 2
Site 1
Site 2
Site 1
Site 2
Site 1
Site 2
Site 1
Site 2
Test de failover
lxc-stop -n site2
for i in $(seq 1 10); do curl http://10.0.3.100/; done
Site 1
Site 1
Site 1
Site 1
Site 1
Site 1
Site 1
Site 1
Site 1
Site 1
Test de reprise
lxc-copy -n lxc-webserver -e -m bind=${HOME}/src/LXC-CONF/web/site2:/var/www/html:ro -N site2
/o\ le retour de Site2 ne fonctionne pas.
FIXME:
En se connectant (lxc-attach) au site 2, le tcpdump montre que les paquets
arrivent mais le sevrice nginx ne répond pas. arp -a ne montre aucune entrée
pour haproxy.
En faisant un ping vers haparoxy, la table arp est bonne et les flux sont ok.
=> Y'a un schmole dans la conf lxc ou est-ce un bug ?
TODO
- configurer le syslog
- configurer iptables
Annexes
Fichier de coonfiguration haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
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=haproxy
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
frontend http-in
bind *:80
default_backend mybackend
backend mybackend
balance roundrobin
# option forceclose
# option tcp-check
option httpchk GET /
timeout check 1s
default-server inter 1s fall 1 rise 1
server srv1 10.0.3.101:80 check
server srv2 10.0.3.102:80 check