6. Installation et gestion des conteneurs

Maintenant que le routage du trafic réseau est complet, on peut passer à l'hébergement des services sur les réseaux des sites distants.

Dans cette partie, on installe le gestionnaire de conteneurs systèmes Incus et on le configure pour que les conteneurs puissent échanger entre les sites.

Avant d'aborder les questions, on s'assure que les outils et les permissions sont en place.

  • Le gestionnaire Incus est installé sur chaque routeur Spoke.

    sudo apt -y install incus
  • L'utilisateur normal etu a la capacité à gérer les conteneurs en appartenant aux groupes incus et incus-admin.

    for grp in incus incus-admin; do sudo adduser etu $grp; done

    N'oubliez pas de vous déconnecter/reconnecter pour que l'appartenance aux groupes soit effective.

    groups
    etu adm sudo users incus-admin incus
  • La configuration par défaut du gestionnaire de conteneurs doit être initialisée.

    Voici un exemple de déclaration de configuration.

    incus admin init
    Would you like to use clustering? (yes/no) [default=no]:
    Do you want to configure a new storage pool? (yes/no) [default=yes]:
    Name of the new storage pool [default=default]:
    Where should this storage pool store its data? [default=/var/lib/incus/storage-pools/default]:
    Would you like to create a new local network bridge? (yes/no) [default=yes]: no
    Would you like to use an existing bridge or host interface? (yes/no) [default=no]: yes
    Name of the existing bridge or host interface: asw-host
    Would you like the server to be available over the network? (yes/no) [default=no]:
    Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
    Would you like a YAML "init" preseed to be printed? (yes/no) [default=no]:

    La configuration du raccordement réseau doit être complétée avec les instructions suivantes.

    incus profile device set default eth0 nictype bridged
    incus profile device set default eth0 vlan 20
    [Avertissement] Avertissement

    L'exemple ci-dessus doit être adapté au contexte réseau en changeant le numéro de VLAN.

  • L'adressage automatique IPv4 et IPv6 doit aussi être installé et configuré sur chaque routeur Spoke avec l'outil dnsmasq.

    Voici un exemple de fichier de configuration à mettre en place. Bien sûr, le nom d'interface sur laquelle les services sont actifs et les adresses IPv4 doivent être changées.

    sudo apt -y install dnsmasq
    cat << EOF | sudo tee /etc/dnsmasq.conf
    # Specify Container VLAN interface
    interface=vlan10
    
    # Enable DHCPv4 on Container VLAN
    dhcp-range=10.0.10.100,10.0.10.200,3h
    
    # Enable IPv6 router advertisements
    enable-ra
    
    # Enable SLAAC
    dhcp-range=::,constructor:vlan10,ra-names,slaac
    
    # Optional: Specify DNS servers
    dhcp-option=option:dns-server,172.16.0.2,9.9.9.9
    dhcp-option=option6:dns-server,[2001:678:3fc:3::2],[2620:fe::fe]
    
    # Avoid DNS listen port conflict between dnsmasq and systemd-resolved
    bind-interfaces
    listen-address=10.0.10.1
    EOF
    sudo systemctl restart dnsmasq.service

Q17.

Comment lancer 3 nouveaux conteneurs sur chaque routeur Spoke ?

Rechercher dans les options de la commande incus le moyen de créer un nouveau conteneur système.

Tester son exécution avec un conteneur de type debian/trixie.

C'est l'option launch qui correspond au besoin. Voici un exemple de création de trois nouveaux conteneurs.

for i in {0..2}; do incus launch images:debian/trixie c$i; done
Launching c0
Launching c1
Launching c2
etu@spoke1:~$ incus ls
+------+---------+--------------------+-----------------------------------------+-----------+-----------+
| NAME |  STATE  |        IPV4        |                  IPV6                   |   TYPE    | SNAPSHOTS |
+------+---------+--------------------+-----------------------------------------+-----------+-----------+
| c0   | RUNNING | 10.0.10.140 (eth0) | fda0:7a62:a:0:216:3eff:fe6a:395c (eth0) | CONTAINER | 0         |
+------+---------+--------------------+-----------------------------------------+-----------+-----------+
| c1   | RUNNING | 10.0.10.196 (eth0) | fda0:7a62:a:0:216:3eff:fe37:f12a (eth0) | CONTAINER | 0         |
+------+---------+--------------------+-----------------------------------------+-----------+-----------+
| c2   | RUNNING | 10.0.10.116 (eth0) | fda0:7a62:a:0:216:3eff:fed9:a25b (eth0) | CONTAINER | 0         |
+------+---------+--------------------+-----------------------------------------+-----------+-----------+

Q18.

Comment tester les communications réseau depuis les conteneurs des routeurs Spoke ?

Reprendre les tests ICMP déjà réalisés depuis les routeurs en les exécutant dans les conteneurs.

Pour traiter cette question, on peut utiliser une boucle qui rassemble les tests IPv4 et IPv6 :

for i in {0..2}
do
        echo ">>>>>>>>>>>>>>>>> c$i"
        incus exec c$i -- ping -qc2 9.9.9.9
        incus exec c$i -- ping -qc2 2620:fe::fe
done

On vérifie qu'aucun paquet n'a été perdu avec le message : 0% packet loss.

On peut aussi tester les services de la couche application avec la gestion de paquets.

for i in {0..2}
do
        echo ">>>>>>>>>>>>>>>>> c$i"
        incus exec c$i -- apt -y update
        incus exec c$i -- apt -y full-upgrade
        incus exec c$i -- apt clean
done

Q19.

Comment combiner l'adressage automatique à l'adressage statique pour chaque conteneur ?

On reprend les traitements réalisés dans le support Routage inter-VLAN et protocole PPPoE avec la création d'un script qui regroupe les traitements de gestion de paquets et de création du fichier de déclaration des paramètres des interfaces réseau des conteneurs.

Voici un exemple de script pour un routeur Spoke.

#!/bin/bash

# Préparation -> générer la liste des conteneurs actifs
clist=$(incus list status=running -c n -f compact | grep -v NAME | tr '\n' ' ' | tr -s ' ')

addr_idx=0
for c in $clist; do
  echo ">>>>>>>>>>>>>>>>> $c"

# Étape 1 -> installer le paquet netplan.io
  incus exec $c -- apt -y install netplan.io

# Étape 2 -> générer le fichier de configuration réseau YAML
$(cat << EOF > eth0.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: false
      dhcp6: false
      accept-ra: true
      addresses:
        - 10.0.10.$((addr_idx + 10))/24
        - fda0:7a62:a::$(printf "%x" $((addr_idx +10)))/64
      routes:
        - to: default
          via: 10.0.10.1
        - to: "::/0"
          via: fe80:a::1
          on-link: true
      nameservers:
        addresses:
          - 172.16.0.2
          - 2001:678:3fc:3::2
EOF
)

# Étape 3 -> transférer le fichier de déclaration YAML
  incus file push eth0.yaml $c/etc/netplan/eth0.yaml

# Étape 4 -> effacer le fichier /etc/systemd/network/eth0.network
  incus exec $c -- rm /etc/systemd/network/eth0.network

# Étape 5 -> appliquer la nouvelle configuration
  incus exec $c -- netplan apply

  ((addr_idx++))
done

exit 0

Si le script ci-dessus est enregistré dans le fichier static-addr.sh, on peut le lancer.

bash static-addr.sh

Les résultats des traitements sont visibles en affichant la liste des conteneurs actifs.

incus ls
+------+---------+-------------------+-----------------------------------------+-----------+-----------+
| NAME |  STATE  |       IPV4        |                  IPV6                   |   TYPE    | SNAPSHOTS |
+------+---------+-------------------+-----------------------------------------+-----------+-----------+
| c0   | RUNNING | 10.0.10.10 (eth0) | fda0:7a62:a::a (eth0)                   | CONTAINER | 0         |
|      |         |                   | fda0:7a62:a:0:216:3eff:fe6a:395c (eth0) |           |           |
+------+---------+-------------------+-----------------------------------------+-----------+-----------+
| c1   | RUNNING | 10.0.10.11 (eth0) | fda0:7a62:a::b (eth0)                   | CONTAINER | 0         |
|      |         |                   | fda0:7a62:a:0:216:3eff:fe37:f12a (eth0) |           |           |
+------+---------+-------------------+-----------------------------------------+-----------+-----------+
| c2   | RUNNING | 10.0.10.12 (eth0) | fda0:7a62:a::c (eth0)                   | CONTAINER | 0         |
|      |         |                   | fda0:7a62:a:0:216:3eff:fed9:a25b (eth0) |           |           |
+------+---------+-------------------+-----------------------------------------+-----------+-----------+

On doit suivre le même processus pour le second routeur Spoke.

Q20.

Comment ouvrir et tester des services Web dans les réseaux d'hébergement ?

On commence par installer un paquet comme nginx dans chaque conteneur et on effectue les tests d'accès ensuite.

pour simuler la consultation de pages Web depuis les conteneurs, on installe aussi un paquet comme wget.

L'installation des paquets se fait à l'aide d'une boucle.

for i in {0..2}
do
    echo ">>>>>>>>>>>>>>>>> c$i"
    incus exec c$i -- apt update
    incus exec c$i -- apt -y install nginx wget
    incus exec c$i -- apt clean
done

Le test de disponibilité des serveurs Web se fait aussi à l'aide d'une boucle.

for i in {0..2}
do
    echo ">>>>>>>>>>>>>>>>> c$i"
    incus exec c$i -- ss -at '( sport = :http )'
done

L'affichage produit par la commande ss et ses paramètres montre que le service HTTP est en écoute dans chaque conteneur.

Q21.

Comment valider l'accès à ces services Web à partir du routeur Spoke situé à l'autre extrémité de la topologie en triangle ?

Il s'agit de faire un test au niveau de la couche application. À la console, les deux outils adaptés sont wget et curl.

Voici un exemple de test pour chaque protocole de la couche réseau avec wget dans le contexte de la maquette.

for addr in {10..12}
do
    wget -O /dev/null http://10.0.20.$addr 2>&1 | grep "HTTP "
done
requête HTTP transmise, en attente de la réponse… 200 OK
requête HTTP transmise, en attente de la réponse… 200 OK
requête HTTP transmise, en attente de la réponse… 200 OK
for addr in {10..12}
do
    wget -O /dev/null http://[fda0:7a62:14::$(printf "%x" $addr)] 2>&1 | grep "HTTP "
done
requête HTTP transmise, en attente de la réponse… 200 OK
requête HTTP transmise, en attente de la réponse… 200 OK
requête HTTP transmise, en attente de la réponse… 200 OK

Q22.

Comment matérialiser le chemin suivi par les paquets IPv4 ou IPv6 entre les deux routeurs Spoke ?

On peut utiliser un outil comme tracepath fourni avec le paquet iputils-tracepath. Il suffit d'installer ce paquet dans les conteneurs du second routeur Spoke et de lancer les tests à destination des conteneurs du premier routeur Spoke.

On installe le paquet dans les conteneurs su second routeur Spoke.

for i in {0..2}
do
    echo ">>>>>>>>>>>>>>>>> c$i"
    incus exec c$i -- apt -y install iputils-tracepath
done

On lance ensuite les tests, toujours à l'aide d'une boucle.

for i in {0..2}
do
    echo ">>>>>>>>>>>>>>>>> c$i"
    incus exec c$i -- tracepath -n 10.0.10.$(($i + 10))
done

On obtient les résultats suivants dans lesquels apparait la valeur de l'encapsulation de la quantité de données dans la trame : 1492.

>>>>>>>>>>>>>>>>> c0
 1?: [LOCALHOST]                      pmtu 1500
 1:  10.0.20.1                                             0.868ms
 1:  10.0.20.1                                             0.112ms
 2:  10.0.20.1                                             0.078ms pmtu 1492
 2:  10.44.3.1                                             1.260ms
 3:  10.44.1.2                                             1.658ms
 4:  10.0.10.10                                            2.244ms reached
     Resume: pmtu 1492 hops 4 back 4
>>>>>>>>>>>>>>>>> c1
 1?: [LOCALHOST]                      pmtu 1500
 1:  10.0.20.1                                             1.722ms
 1:  10.0.20.1                                             0.134ms
 2:  10.0.20.1                                             0.056ms pmtu 1492
 2:  10.44.3.1                                             1.193ms
 3:  10.44.1.2                                             1.676ms
 4:  10.0.10.11                                            2.569ms reached
     Resume: pmtu 1492 hops 4 back 4
>>>>>>>>>>>>>>>>> c2
 1?: [LOCALHOST]                      pmtu 1500
 1:  10.0.20.1                                             2.055ms
 1:  10.0.20.1                                             0.077ms
 2:  10.0.20.1                                             0.074ms pmtu 1492
 2:  10.44.3.1                                             1.094ms
 3:  10.44.1.2                                             1.774ms
 4:  10.0.10.12                                            2.132ms reached
     Resume: pmtu 1492 hops 4 back 4

On suit la même démarche avec le protocole IPv6.

for i in {0..2}
do
    echo ">>>>>>>>>>>>>>>>> c$i"
    incus exec c$i -- tracepath -n fda0:7a62:a::$(printf "%x" $(($i + 10)))
done

Les résultats sont identiques aux précédents à l'adressage près.

>>>>>>>>>>>>>>>>> c0
 1?: [LOCALHOST]                        0.050ms pmtu 1500
 1:  fda0:7a62:14::1                                       1.815ms
 1:  fda0:7a62:14::1                                       0.129ms
 2:  fda0:7a62:14::1                                       3.201ms pmtu 1492
 2:  2001:678:3fc:168:baad:caff:fefe:5                     1.571ms
 3:  fda0:7a62:a:0:9c04:62ff:fe95:f948                     1.742ms
 4:  fda0:7a62:a::a                                        2.239ms reached
     Resume: pmtu 1492 hops 4 back 4
>>>>>>>>>>>>>>>>> c1
 1?: [LOCALHOST]                        0.030ms pmtu 1500
 1:  fda0:7a62:14::1                                       0.572ms
 1:  fda0:7a62:14::1                                       0.116ms
 2:  fda0:7a62:14::1                                       0.071ms pmtu 1492
 2:  2001:678:3fc:168:baad:caff:fefe:5                     1.374ms
 3:  fda0:7a62:a:0:9c04:62ff:fe95:f948                     2.088ms
 4:  fda0:7a62:a::b                                        2.396ms reached
     Resume: pmtu 1492 hops 4 back 4
>>>>>>>>>>>>>>>>> c2
 1?: [LOCALHOST]                        0.032ms pmtu 1500
 1:  fda0:7a62:14::1                                       0.666ms
 1:  fda0:7a62:14::1                                       0.091ms
 2:  fda0:7a62:14::1                                       0.093ms pmtu 1492
 2:  2001:678:3fc:168:baad:caff:fefe:5                     1.252ms
 3:  fda0:7a62:a:0:9c04:62ff:fe95:f948                     2.177ms
 4:  fda0:7a62:a::c                                        3.664ms reached
     Resume: pmtu 1492 hops 4 back 4