The Ops Community ⚙️

xavki
xavki

Posted on • Originally published at xavki.blog on

Bridge, namespaces et vethernet comme docker0

Souvent quand on introduit docker, on le présente comme un outil qui utilise des fonctionnalités de Linux : les cgroups et les namespaces… Je sais je l’ai fait plusieurs fois sur la chaine Xavki. Bon c’est bien et ça buzz bien mais bon si on montre jamais comment ça marche on passe à côté d’un truc. Aujourd’hui on va comprendre comment docker simplifie les choses avec son bridge Docker0.

Eh oui on va installer un bridge, 2 namespaces et 2 vethernets.

Alors le but c’est de créer un script qui va nous permettre de créer la structure suivante :

Et on va faire original, on va créer un bridge nommé Xavki0 !! La gloire éternel merci Linux !!

Première choses les variables de tout ce petit monde…

Alors voici les variables que l’on définit dans la partie haute de notre script bash :

#!/usr/bin/bash

## Variables Namespace
NS1="x1"
NS2="x2"

## Variables vethernet
VETH1="xeth1"
VETH2="xeth2"

## Variables interface des conteneurs
VPEER1="xpeer1"
VPEER2="xpeer2"

# Variables ip des conteneurs
VPEER_ADDR1="10.11.0.10"
VPEER_ADDR2="10.11.0.20"

## Variables du bridge
BR_ADDR="10.11.0.1"
BR_DEV="xavki0"
Enter fullscreen mode Exit fullscreen mode

Première chose les 2 namespaces x1 et x2 qui sont les deux boites isolées d’un point de vue réseau. Et c’est important, aujourd’hui on ne voit que l’isolation réseau. Donc on va considérer que cela pourrait s’apparenter à 2 conteneurs si on ne regarde que la partie réseau.

Ensuite pour connecter ces deux namespaces à notre bridge, il faut un cable. Ce cable, il est virtuellement forcément, ce sont ce que l’on appelle des vethernets : xeth1 et xeth2.

Et pour chaque namespace comme dans nos conteneurs, il nous faut une interface virtuelle les vpeers : xpeer1 et xpeer2.

Pour chacune de ces interfaces, il nous faut une ip pour chaque : 10.11.0.10 et 10.11.0.20.

Bon et enfin, il nous faut un bridge xavki0 et l’adresse de ce bridge, en l’occurence l’ip1 de notre cidr (range d’ip).

Maintenant créons tout ces éléments réseaux

## Création des namespaces
ip netns add $NS1
ip netns add $NS2

##Création des vethernet (cables) & interfaces
ip link add ${VETH1} type veth peer name ${VPEER1}
ip link add ${VETH2} type veth peer name ${VPEER2}

## Ajout des interfaces au namespace
ip link set ${VPEER1} netns ${NS1}
ip link set ${VPEER2} netns ${NS2}

## Activation des vethernet
ip link set ${VETH1} up
ip link set ${VETH2} up
Enter fullscreen mode Exit fullscreen mode

A noter particulièrement que pour la création des vethernets on précise le nim mais aussi les vpeers. nos fameuses interfaces vituelles de chaque namespace. Ensuite, on va ajouter ces vpeers à nos namespaces. Et enfin on va activer nos vethernet.

Vous remarquerez que l’on a pas tout créé 😉

Ajout des ip dans les namespaces

Alors pour l’instant c’est bien tout cela mais on a pas d’ip dans nos namespaces : ni loopback (127.0.0.1), ni nos fameuses ip définies dans nos variables au début. Bon ben go…

## Activation des interfaces dans les namespaces
ip netns exec ${NS1} ip link set lo up
ip netns exec ${NS2} ip link set lo up
ip netns exec ${NS1} ip link set ${VPEER1} up
ip netns exec ${NS2} ip link set ${VPEER2} up
Enter fullscreen mode Exit fullscreen mode

Et là vous voyez que notre commande ip avec son argument netns ne sert pas qu’à créer des namespaces… Non en fait elle permet de lancer les commandes de votre choix dans le contexte du namespace que vous allez préciser. On pourrait lancer un LS mais là on décide d’activer nos fameuses ip… Donc pour vérifier on pourrait passer un “ip a” plutôt que ip link set…

Maintenant ces ip on va les attribuer à nos interfaces de chacun de nos namespaces :

## Ajout des ip pour chaque interface
ip netns exec ${NS1} ip addr add ${VPEER_ADDR1}/16 dev ${VPEER1}
ip netns exec ${NS2} ip addr add ${VPEER_ADDR2}/16 dev ${VPEER2}
Enter fullscreen mode Exit fullscreen mode

Et je dirais que classiquement on fait cela avec ‘ip addr add’ et le device en question. Remarquez aussi que l’on choisit ici de définir un masque /16.

Et notre bridge associé à nos namespaces ???

Ah quand même on vient pour avoir un bridge et on l’a toujours pas créé. Alors voilà ce que l’on fait :

## Création et activation du bridge
ip link add ${BR_DEV} type bridge
ip link set ${BR_DEV} up

## Ajout des vethernet au bridge
ip link set ${VETH1} master ${BR_DEV}
ip link set ${VETH2} master ${BR_DEV}

## Ajout de l'ip du bridge
ip addr add ${BR_ADDR}/16 dev ${BR_DEV}
Enter fullscreen mode Exit fullscreen mode

On créé le bridge et on le rend up (active).

On y branche nos deux câbles virtuels (souvenez vous ils sont déjà branchés de l’autre côté à l’interface de nos namespaces).

Et ensuite on définit le CIDR ou range d’ip c’est à dire notre /16 et du coup l’ip qui sera attribué à ce bridge au niveau de notre host.

Router le traffic via le bridge

Alors c’est bien d’avoir de IP, des vethernet et tout le bazard mais quand je suis dans un namespace je ne sait pas par où passer pour communiquer à l’extérieur… Et ien on va ajouter des routes dans nos namespaces et donc dans notre cas pour faire simple on va juste avoir des routes par défaut :

## Ajout des routes poru chaque namespace pour passer par le bridge
ip netns exec ${NS1} ip route add default via ${BR_ADDR}
ip netns exec ${NS2} ip route add default via ${BR_ADDR}
Enter fullscreen mode Exit fullscreen mode

Et pour accéder à internet !!! (à l’extérieur du host plutôt)

Oui c’est toujours cette fameuse question : comment je fais pour accéder à internet.

Et bien on va autoriser l’ip_forwarding au niveau de notre noyau linux. Et surtout on va utiliser iptables pour faire ce que l’on appelle un masquerade pour encapsuler nos paquets qui sortent et savoir dans quel namespace il doivent rentrer (par quelle interface plus précisément).

## Accès externe
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s ${BR_ADDR}/16 ! -o ${BR_DEV} -j MASQUERADE
Enter fullscreen mode Exit fullscreen mode

Et bim c’est terminé !!! Tout le script est ici.

Voilà j’espère que cela a été assez clair. Vous avez bien sûr la vidéo. Et n’hésitez pas à faire connaître : le blog, la chaine et le podcast !!!

L’article Bridge, namespaces et vethernet comme docker0 est apparu en premier sur Xavki.

Oldest comments (0)