Google PlusFacebookTwitter

systemd-networkd, l’âge de la maturité ?

By on Mar 13, 2018 in Linux | 0 comments

Share On GoogleShare On FacebookShare On Twitter

systemd, le « sujet » qui a fait couler beaucoup d’encre…

Dès son annonce, systemd à fait parler de lui que se soit en bien ou en mal. Certains étaient enthousiastes à la venue d’un nouveau système d’init, d’autres étaient réfractaire au changement, d’autres étaient partagés sur le fait que systemd faisait beaucoup trop de choses.

Pour ma part je n’avais pas spécialement d’opinion sur le sujet, j’attendais simplement de voir comment systemd allait s’intégrer aux distributions et plus particulièrement à Debian GNU/Linux. Depuis Debian GNU/Linux Stretch (9.x), l’intégration de systemd a été amplement améliorée même s’il est dommage que la version embarquée par défaut soit inférieure à 233 (heureusement que les backports sont là pour corriger cela).

Comme indiqué quelques lignes plus haut, systemd est capable de gérer plusieurs choses, entre autres:

Nous allons nous attarder sur systemd-networkd afin de configurer entièrement notre réseau et de remplacer le « déprécier » /etc/network/interfaces*.

Objectif Lune (dédicace à Tintin \o/)

Dans ce billet, nous avons pour objectif de configurer:

  1. Un bonding LACP (802.3ad) avec deux interfaces réseau
  2. Deux vlan configurés sur le bond
  3. Application des jumbo frames sur l’un des vlan

Configuration du module bonding

La première chose à effectuer avant d’aller plus loin et de définir le comportement du module bonding. Par défaut quand le module bonding est chargé, le noyau créé automatiquement une interface nommée bond0. Ce comportement pose problème à systemd… pour faire simple il se mélange les pinceaux en essayant de créer une interfaces bond0 qui existe déjà…

La configuration du module bonding est simple, il suffit d’ajouter le contenu suivant dans le fichier /etc/modprobe.d/bonding.conf (libre à vous d’en ajouter en fonction de vos besoins).

options bonding max_bonds=0

D’après la documentation officielle du module:

max_bonds

Specifies the number of bonding devices to create for this
instance of the bonding driver. E.g., if max_bonds is 3, and
the bonding driver is not already loaded, then bond0, bond1
and bond2 will be created. The default value is 1. Specifying
a value of 0 will load bonding, but will not create any devices.

À partir de la version 235, systemd se charge de configurer automatiquement le module bonding via un drop-in dans le répertoire /etc/modprobe.d/

Configuration de systemd-networkd

Le module bonding est désormais configuré (tu veux une médaille ?), systemd-networkd a maintenant besoin d’informations pour créer le réseau. Ces informations sont à fournir sous forme de fichiers, ces fichiers doivent se terminer avec des extensions particulières.

  1. .link: Utile pour configurer la MTU, l’adresse MAC, la bande passante, etc..
  2. .netdev: Permet de créer une interface virtuelle comme par exemple un bond, un bridge, un vlan, etc…
  3. .network: Permet d’assigner une configuration réseau à une interface physique ou virtuelle

L’ordre de lecture de ces fichiers s’effectue de manière lexicale. Il est important de noter que si aucun fichier .link existe, le fichier /lib/systemd/network/99-default.link sera automatiquement appliqué.

Les interfaces ens4 et ens5 sont membres de bond0, il est nécessaire de créer deux fichiers (un par interface physique) dans le répertoire /etc/systemd/network/.

# cat << EOF > /etc/systemd/network/20-bond0-ens4.network
[Match]
Name=ens4

[Network]
Bond=bond0
EOF

# cat << EOF > /etc/systemd/network/20-bond0-ens5.network
[Match]
Name=ens5

[Network]
Bond=bond0
EOF

L’activation des jumbo frames s’effectue à l’aide des fichiers .link. Il est donc nécessaire de créer un fichier par interface ou l’on souhaite appliquer cette modification.

# cat << EOF > /etc/systemd/network/20-bond0-ens4.link
[Match]
OriginalName=ens4

[Link]
MTUBytes=9000
EOF

# cat << EOF > /etc/systemd/network/20-bond0-ens5.link
[Match]
OriginalName=ens5

[Link]
MTUBytes=9000
EOF

Maintenant que nos interfaces sont prêtes à faire partie du bonding il ne reste plus qu’à créer notre bond0, ici nous allons créer une interface virtuelle (et oui, bond0 n’est pas physique).

# cat << EOF > /etc/systemd/network/20-bond0.netdev
[NetDev]
Name=bond0
Kind=bond

[Bond]
Mode=802.3ad
MIIMonitorSec=1s
LACPTransmitRate=fast
UpDelaySec=2s
DownDelaySec=8s
EOF

Comme pour les interfaces physiques, il est nécessaire de changer la MTU pour bond0 auquel cas la taille de cette dernière sera celle par défaut à savoir 1500.

# cat << EOF > /etc/systemd/network/20-bond0.link
[Match]
OriginalName=bond0

[Link]
MTUBytes=9000
EOF

Avant d’appliquer une configuration réseau à bond0, nous allons créer nos deux interfaces virtuelles de type vlan (bond0.10 et bond0.20). Encore une fois, nous allons devoir jouer avec les fichiers .link et .netdev (vous devriez commencer à comprendre le principe).

# cat << EOF > /etc/systemd/network/30-bond0-vlan10.link
[Match]
OriginalName=bond0.10

[Link]
MTUBytes=1500
EOF

# cat << EOF > /etc/systemd/network/30-bond0-vlan10.netdev
[NetDev]
Name=bond0.10
Kind=vlan

[VLAN]
Id=10
EOF

# cat << EOF > /etc/systemd/network/30-bond0-vlan20.link
[Match]
OriginalName=bond0.20

[Link]
MTUBytes=9000
EOF

# cat << EOF > /etc/systemd/network/30-bond0-vlan20.netdev
[NetDev]
Name=bond0.20
Kind=vlan

[VLAN]
Id=20
EOF

ens4 et ens5 ont été ajoutées à bond0, ce dernier a été créé pour supporté LACP, les vlan 10 et 20 ont été taggés sur bond0 et les jumbo frame ont été activées sur toutes les interfaces excepté bond0.10.

La dernière étape consiste à appliquer une configuration réseau à nos interfaces virtuelles, dans un premier temps sur bond0.10 et bond0.20 et dans un second temps sur bond0 lui même.

# cat << EOF > /etc/systemd/network/30-bond0-vlan10.network
[Match]
Name=bond0.10

[Network]
Address=10.10.0.10/24
EOF

# cat << EOF > /etc/systemd/network/30-bond0-vlan20.network
[Match]
Name=bond0.20

[Network]
Address=10.20.0.10/24
EOF

# cat << EOF > /etc/systemd/network/30-bond0.network
[Match]
Name=bond0

[Network]
BindCarrier=ens4 ens5
VLAN=bond0.10
VLAN=bond0.20
EOF

Le fichier 30-bond0.network indique que notre bond0 fait référence à nos deux interfaces avec vlan et que les interfaces ens4 et ens5 doivent être démarrées si elles sont inactives.

Nous arrivons au moment fatidique à savoir le démarrage/redémarrage du service systemd-networkd. Avant d’aller plus loin, assurez-vous d’avoir un accès iLO/iDrac/IPMI car si la configuration réseau n’est pas correcte vous n’aurez plus accès au serveur. 😳

# systemctl enable systemd-networkd
# systemctl restart systemd-networkd

Si tout s’est bien passé, vous devriez toujours avoir la main sur le serveur \o\/o/ !!

Alors, ça fonctionne ?

La méthode pour débugger le réseau avec systemd-networkd est un poil différente, il est toujours possible d’utiliser les commandes fournies par iproute2 mais ces dernières risquent de ne pas être suffisantes pour systemd en lui même.

La commande networkctl permet d’avoir un aperçu rapide sur ce qui a été configuré.

# networkctl
IDX LINK             TYPE               OPERATIONAL SETUP     
  1 lo               loopback           carrier     unmanaged 
  2 ens3             ether              routable    configured
  3 ens4             ether              carrier     configuring
  4 ens5             ether              carrier     configuring
  5 bond0            ether              degraded    configured
  6 bond0.20         ether              routable    configured
  7 bond0.10         ether              routable    configured

7 links listed.

Le retour de cette commande montre que l’interface bond0 est dans un état degraded, cela est tout à fait « normal » dans notre cas. La raison est que nous n’avons aucune adresse IP assignée sur cette interface.

À l’aide de la même commande, il est possible d’avoir de plus amples informations sur une interface spécifique.

# networkctl status bond0.10
● 8: bond0.10
       Link File: /etc/systemd/network/30-bond0-vlan10.link
    Network File: /etc/systemd/network/30-bond0-vlan10.network
            Type: ether
           State: routable (configured)
          Driver: 802.1Q VLAN Support
      HW Address: 4a:b3:ed:e1:d0:8c
         Address: 10.10.0.10
                  fe80::48b3:edff:fee1:d08c

Ici nous pouvons voir que les fichiers appliqués sur cette interface sont:

  1. /etc/systemd/network/30-bond1-vlan10.link
  2. /etc/systemd/network/30-bond1-vlan10.network

Il peut être aussi très utile de savoir ce qu’il s’est passé au niveau de systemd-networkd lors du démarrage du serveur, pour se faire journalctl est notre ami !

# journalctl --boot -u systemd-networkd

La commande dmesg permettra quant à elle de s’assurer que la MTU est correctement appliquée ou que les modules ont été correctement chargés.

[   10.340774] 8021q: 802.1Q VLAN Support v1.8
[   10.343750] e1000: ens5 changing MTU from 1500 to 9000
[   10.399964] 8021q: adding VLAN 0 to HW filter on device ens5
[   10.410635] bond0: Enslaving ens5 as an active interface with a down link
[   10.417307] e1000: ens4 changing MTU from 1500 to 9000
[   10.493156] 8021q: adding VLAN 0 to HW filter on device ens4
[   10.498667] bond0: Enslaving ens4 as an active interface with a down link
[   10.506141] 8021q: adding VLAN 0 to HW filter on device ens3
[   12.417194] e1000: ens5 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[   12.430021] 8021q: adding VLAN 0 to HW filter on device bond0
[   12.519335] e1000: ens4 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[   12.552724] bond0: link status definitely up for interface ens5, 1000 Mbps full duplex
[   12.552735] bond0: first active interface up!
[   12.552850] bond0: link status definitely up for interface ens4, 1000 Mbps full duplex

Au final il est assez simple de s’y retrouver après quelques recherches Google.

Petit bonus !!

Parce que je t’aime lecteur (si lecteur il y a), je joins un petit extra sur comment configurer une interface toute simple en DHCP avec une route statique et sa metric ainsi que des serveurs DNS personnalisés.

# cat << EOF > /etc/systemd/network/10-ens3.network
[Match]
Name=ens3

[Network]
Description="DHCP example with static route and custom DNS"
DHCP=ipv4
DNS=8.8.8.8 8.8.4.4

[Route]
Destination=172.16.0.0/24
Metric=10

[DHCP]
UseDNS=false
EOF

L’option DNS de la section [Network] requiert le démarrage du service systemd-revolsed. Ce service se base sur le contenu du fichier /var/run/resolvconf/resolv.conf,/etc/resolv.conf est un lien symbolique vers ce fichier.

# systemctl enable systemd-resolved
# systemctl restart systemd-resolved

Pensez bien à supprimer le contenu présent dans /etc/network/interfaces* et faites attention à cloud-init qui peut-être fourbe et recréer un fichier dans /etc/network/interfaces.d/ 😯

Conclusion

Nous y voilà, nous sommes passés à systemd-networkd (sans trop de douleur je l’espère). Cette transition nécessite quelques lectures afin de comprendre le fonctionnement et l’imbrication des services réseau de systemd.

Ci-dessus, j’ai rédigé une petite liste de pour et de contre (cette liste n’engage que moi).

Avantages:

Désavantages:

Liens

The following two tabs change content below.

Gaëtan Trellu (goldyfruit)

Cloud Technical Advisor chez IBM
Autodidacte en informatique, depuis 2005 je parcours l’écosystème Unix à la recherche de nouvelles connaissances et de nouvelles rencontres.

CC BY 4.0 systemd-networkd, l’âge de la maturité ? par Gaëtan Trellu (goldyfruit) est sous Licence Creative Commons Internationale Attribution 4.0.