Home Tags Anciens articles Mon CV

LXD, Ansible & DNSMasq

Quand on a un porte-conteneur LXD qui est piloté via ansible, c’est qu’on aime bien automatiser les choses.

On peut avoir disons, une tâche de création de conteneurs, mais il faut encore mettre à jour la configuration SSH avec les hosts créés au fur et à mesure.

Evidemment, cela peut se faire avec un playbook qui va écrire la configuration SSH au moyen de récupération de variables… C’est déjà lourd.

La véritable solution résiderait plutôt dans le fait de ne créer la configuration SSH qu’une seule fois et ne plus la modifier.

C’est possible avec DNSmasq et un peu de configuration LXD.

LXD

En premier lieu la configuration LXD. C’est donc le bridge configuré à l’installation que nous allons modifier via la commande :

$ lxc network edit lxdbr0

On va rajouter dans config le paramètre raw.dnsmasq ainsi :

config:
  ipv4.address: 10.100.179.1/24
  ipv4.nat: "true"
  ipv6.address: none
  raw.dnsmasq: |
    auth-zone=lxd
    dns-loop-detect

C’est tout ce qu’il y a à faire.

DNSMasq

C’est là que le gros du boulot réside. Il y a sans doute d’autres façons de le faire, pour ma part c’est ainsi que j’y suis parvenu.

Après avoir installé dnsmasq, je créé sur le porte-conteneur (le host donc) la configuration nécessaire dans le fichier /etc/dnsmasq.d/lxd :

server=/lxd/
bind-interfaces
except-interface=lxdbr0

Je redémarre ensuite dnsmasq (et l’active au démarrage):

# systemctl enable dnsmasq && systemctl restart dnsmasq

Top. Maintenant, il nous reste à dire à notre système, sur le host donc, d’utiliser le DNS de lxdbr0, qui est donc piloté par dnsmasq.

Dans la configuration Netplan, il faut rajouter :

nameservers:
  search: [lxd]
  addresses:
    - 10.100.179.1

Puis lancer netplan apply.

Note: un bug touche le fichier /etc/resolv.conf sur ubuntu 18.04 et votre fichier ne prendra pas en compte les modifications faites par netplan. Pour le corriger, deux lignes de bash suffisent:

$ sudo rm -f /etc/resolv.conf
$ sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

Si tout va bien:

kharec@vjun:~$ host cs-cv-01.lxd
cs-cv-01.lxd has address 10.100.179.89
kharec@vjun:~$

La résolution de nom fonctionne. De la même façon, si je lance un conteneur tout neuf:

kharec@vjun:~$ lxc launch template0 test-01
Creating test-01
Starting test-01
kharec@vjun:~$ host test-01.lxd
test-01.lxd has address 10.100.179.95
kharec@vjun:~$

Son IP est bien résolue sur le domaine .lxd sans action supplémentaire.

Configuration SSH et Ansible

Maintenant, voyons la configuration SSH. Dans un premier temps, j’avais dans ma configuration SSH, ssh/config dans mon projet, chacun de mes conteneurs avec leur ip en dur que je rajoutais, ainsi que le proxyjump nécessaire pour rebondir dedans.

Voici ma nouvelle configuration ssh:

Host vjun
    Hostname <ip du porte-conteneur>
    User kharec
    IdentityFile ssh/id_rsa
    Port 22

Host cs-*
    Hostname %h.lxd
    User ubuntu
    IdentityFile ssh/id_rsa
    ProxyJump vjun

Inutile de rajouter mes nouveaux conteneurs, tant qu’ils respectent ma nomenclature cs-, la configuration ssh ne bougera pas.

Je n’ai donc plus à me préoccuper d’elle et uniquement à ajouter mes conteneurs dans mon fichier env/inventory.ini qui représente mon inventaire, car leurs noms seront maintenant résolus automatiquement.

Note finale: avec le module ini_file, un ami à moi écrit même son inventaire dynamiquement dans sa task de création de conteneur.

Pensez-y :-)