+++
title = "LXC : résoudre localement les noms des conteneurs"
date = 2022-12-23
[taxonomies]
tags = [ "lxc", "système", "dns" ]
+++

> Et je vais l’appeler `systemd`. Je suis sûr que tout va bien se passer.

![Grand sourire](/2022/12/smile_loud.jpg)

<!-- more -->

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.
