LXC : résoudre localement les noms des conteneurs
Et je vais l’appeler
systemd
. Je suis sûr que tout va bien se passer.
Alors, je t’arrête tout de suite, je n’ai pas d’allergie chronique à systemd
. Dans l’absolu, je trouve même que c’est pas si mal foutu que cela (et on aura l’occasion d’y revenir un peu plus tard). Alors, oui, il y a aussi des trucs à la con (et pas qu’un peu d’ailleurs) mais le simple fait que ça normalise énormément de choses est déjà en soi une bonne idée.
Bref, ce n’était pas tellement le sujet, je voulais surtout parler de LXC et de comment tu peux faire pour résoudre les noms de tes conteneurs directement depuis la machine hôte (pratique quand on doit faire un peu d’expérimentation, du Ansible, des choses comme ça).
Donner un nom de domaine à résoudre
Généralement LXC sous Linux vient avec tout un tas de trucs pour simplifier les choses, et notamment un service qui se nomme lxc-net
. Ce dernier est en réalité un « gros » script qui comprend :
- l’initialisation de l’interface de bridge qui va permettre aux conteneurs d’accéder au monde extérieur (et d’être accédé aussi)
- le démarrage d’un
dnsmasq
pour assurer la partie DHCP/résolution de nom
Or il se trouve que ce dnsmasq
peut aussi servir pour faire la résolution de nom des machines derrière le bridge en question (en gros, tu vas pouvoir joindre facilement tes conteneurs).
Pour cela, quelques manipulations sont nécessaires. Première chose, il faut aller éditer /etc/default/lxc-net
(sous Debian et Archlinux, c’est comme ça, je ne sais pas pour les autres). Il faut y ajouter la ligne suivante :
LXC_DOMAIN=lxc.buttse.cx.local
Ça peut être mis n’importe où évidemment. Cela permet d’indiquer à lxc-net
que l’on souhaite que la résolution du service dnsmasq
se fasse en lxc.buttse.cx.local
(tu peux évidemment mettre n’importe quoi, il n’y a pas de limitation particulière a priori).
En redémarrant le service, tu peux constater que tu peux résoudre ces noms en tapant directement sur l’interface de bridge :
> dig +short @100.64.4.1 youpi.lxc.buttse.cx.local
100.64.4.94
100.64.4.1
étant l’adresse de mon bridge LXC
Voilà, tout ça, c’est très bien mais comment tu fais pour que ton hôte (la grosse babasse là) puisse aussi faire cette résolution sans faire trop de contorsion.
Enter systemd
Côté réseau systemd
, c’est un peu le bordel par contre. Personnellement, étant sous Archlinux, j’utilise netctl
pour la partie réseau et systemd-resolved
pour faire la partie résolution de noms. Pas que je trouve ça particulièrement efficace, mais ça permet de gérer tout un tas de cas tordus à peu près automagiquement (changement de réseaux, VPN, etc…), donc je m’en contente pour le moment.
Bref, idéalement, on aimerait bien indiquer pour lxc.buttse.cx.local
, il faut utiliser le dnsmasq
local plutôt que le reste de la chaîne de résolution de noms. Bah il se trouve qu’on peut (et c’est presque pas tordu, tu vas voir). En fait, avec l’indicateur DNS=
dans /etc/systemd/resolved.conf
, on peut préciser plein de trucs : à quel serveur DNS s’adresser, mais également sur quelle interface et pour quel domaine. La syntaxe fait un peu peur mais ça marche relativement bien :
[Resolve]
DNS=100.64.4.1%lxcbr0#lxc.buttse.cx.local
Évidemment, rien n’empêche d’en ajouter d’autres, séparés par un espace. En redémarrant le service en question, on peut alors faire la résolution sans préciser le serveur DNS :
> dig +short youpi.lxc.buttse.cx.local
100.64.4.94
Et en prime, ça ne perturbe rien d’autres. Tu pourrais d’ailleurs très bien imaginer en ajouter d’autres pour KVM, Docker, etc…
Voilà, c’est gratuit, c’est pour moi.