Cet article vous guide comment bien démarrer avec le WSL2 sous Windows (version 10) en vous exposant les contraintes que la distribution embarquée impose et les contournement possibles.

Introduction

Depuis maintenant plusieurs années, les équipes Microsoft se sont penchées sur l’open source des solutions après la montée en puissance des distribution Linux sur le marché professionnel, mais aussi personnel.

Ce mouvement a notamment entrainé chez Microsoft le renouvellement du noyau, sur lequel repose Windows, afin de proposer des fonctionnalités natives que Linux propose.

Ce revirement de situation, comprenons-le bien, fait suite à l’émergence et la popularisation des distribution libres. Microsoft se “rapproche de ses ennemis” en adoptant un modèle similaire.

C’est ici qu’émerge le Windows Subsystem Linux, appelée WSL, qui reproduit l’utilisation d’une distribution Linux de manière quasi identique. Le WSL est apparu en version 1 à ses début, pour évoluer en version 2 avec comme principale amélioration la prise en charge des conteneurs avec Docker.

Configuration

Utiliser le système de WSL de Windows induit quelques comportements déviants de la part du système ; il fallait s’y attendre avec une base Windows.

Rassurez-vous, rien de bien méchant ! De plus, les points faibles possèdent des solutions de contournement en attendant une résolution définitive par les équipes de Microsoft.

Gestion de la mémoire de la WSL

Mis à jour le 08/11/2023.

Vous remarquerez assez vite qu’avec l’utilisation des conteneurs (Docker ou équivalent), votre WSL va s’emballer et consommer de la mémoire abusivement.

La seule solution (actuelle) à cet effet de bord de WSL est de limiter la quantité de mémoire utilisable par WSL. Ce qui n’est pas une mauvaise chose en soit si on veut pouvoir travailler à cote de la WSL dans les cas où elle consomme beaucoup de mémoire.

Pour configurer la taille maximum de la mémoire de la WSL, modifier le fichier %UserProfile%/.wslconfig :

[wsl2]
memory=8GB

Les variables d’environnement

Le système du WSL propage toutes les variables d’environnement Windows au sein de sa WSL. On retrouvera les variables dédiées à Windows, mais aussi les variables injectées dans le variables d’environnements Windows, tel que les chemins des exécutables pour développer.

Avec ce comportement, les conflits entre les variables d’environnements Windows et Linux peuvent se faire nombreux. D’autant plus que les binaires Windows n’ont pas le même comportement que ceux Linux.

C’est pour cette raison qu’il peut être judicieux de désactiver la propagation et isoler le WSL sur ces variables d’environnement.

Désactiver la propagation des variables d’environnement

Pour désactiver la fonctionnalité, il faut modifier le fichier /etc/wsl.conf du WSL et positionner les attributs interop.enabled et interop.appendWindowsPath.

sudo vi /etc/wsl.conf
[interop]
enabled=false
appendWindowsPath=false

La résolution DNS

Le modèle WSL propage également les entrées DNS locales Windows ainsi que ses résolvers. On retrouvera les serveurs DNS de résolution de Windows au sein du WSL.

La propagation des resolvers DNS peut poser problème sur la résolution des noms de domaine. Ce problème est vite bloquant quand on souhaite atteindre des adresses publiques.

Une issue a été ouverte sur le compte Github de Mircrosoft sur le WSL concernant ce phénomène :

Il est nécessaire de rendre le WSL indépendant sur la résolution des noms de domaine en désactivant la propagation des resolvers.

Désactiver la propagation des resolvers

Pour désactiver la fonctionnalité, il faut modifier le fichier /etc/wsl.conf et positionner l’attribut network.generateResolvConf.

sudo vi /etc/wsl.conf
[network]
generateResolvConf = false

Le WSL embarque le paquet resolvconf, entre autre, pour automatiser la récupération et le montage des resolvers de Windows.

sudo apt remove resolvconf
sudo rm /etc/resolv.conf

La modification des fonctionnalités de noms de domaine du WSL nécessite une réconciliation avec les autres services du WSL ainsi qu’avec Windows. Un redémarrage est donc nécessaire pour pleinement bénéficier des modifications.

Ouvrir une console Windows Powershell en administrateur et lancer la commande suivante.

wsl --shutdown Ubuntu-18.04

Si la commande retourne une erreur, c’est que le nom du WSL ciblé est différent. Pour en savoir plus la résolution, je vous invite à parcourir l’article Utiliser le terminal bash natif dans Windows 10.

Relancer ensuite l’image Ubuntu en lançant un terminal.

Configurer manuellement la résolution de nom pour pointer vers les resolvers Google (8.8.8.8 et 8.8.4.4)

sudo vi /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4

Si vous passez par un VPN, vous devez ajouter les resolvers DNS du réseau cible du VPN avant les resolvers de base.

Les règles pare-feu

Mise à jour le 28/11/2023.

Si vous êtes un amoureux des conteneurs (comme moi <3), vous tomberez peut-être sur l’erreur suivante au démarrage de docker :

failed to start daemon: Error initializing network controller: error obtaining controller instance: unable to add return rule in DOCKER-ISOLATION-STAGE-1 chain:  (iptables failed: iptables --wait -A DOCKER-ISOLATION-STAGE-1 -j RETURN: iptables v1.8.7 (nf_tables):  RULE_APPEND failed (No such file or directory): rule in chain DOCKER-ISOLATION-STAGE-1
 (exit status 4))

Si tel est le cas, c’est que la distrib (Ubuntu peut-être ?) a changé la librairie de la gestion des iptables. A date, elle propose iptables-ntf et iptables-legacy. Les installation rcentes ont la librairie iptables-ntf installée d’office (vous verrez l’option “auto” avec la commande qui suit).

La solution est de basculer sur l’ancien mode : iptables-legacy.

sudo update-alternatives --set iptables /usr/sbin/iptables-legacy

Démarrez docker et tout devrait bien se dérouler. La commande “docker info” vous permettra de facilement vérifier son bon fonctionnement.

Le système de fichiers

Le mode d’exécution du WSL est un peu particulier comparé aux serveurs classiques.
Le système démarre sur un processus unique, de type systemd unique, qui verrouille les fonctionnalités liées au systemd. On peut ainsi dire adieu à l’utilisation des services nouvelles génération (systemd) et à la gestion des namespaces pour les services.

Cette particularité pose notamment problème pour les service récents qui nécessitent le systemd pour fonctionner.

Autre inconvénient, c’est l’absence des isolateurs de type cgroups pour les services. Ce qui est gênant pour Docker notamment, qui utilise les cgroups pour isoler les processus.

Heureusement, des solutions de contournement permettent de contourner, et au pire atténuer l’impact du parti pris par Microsoft sur l’exécution du WSL.

Activer le mode systemd/cgroup

Les cgroups pour les services systemd est une fonctionnalités indispensable pour Docker. Il ne sont pas activés de base, mais on peut facilement contourner le problème en rattachant le système d’isolation cgroups aux services systemd. On permet ainsi de bénéficier des cgroups dans le bash courant, représenté par le service systemd unique du WSL (le fameux PID 1 du système).

Créer un répertoire cgroup/systemd pour faire illusion au système et monter ce répertoire sur le système d’isolation des cgroups.

sudo mkdir /sys/fs/cgroup/systemd
sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd

Vous pouvez maintenant installer Docker et exécuter des conteneurs dans le WSL.

Troubleshooting

Il est possible que le point de montage se démonte avec le temps (garbage collector du système, libération de la mémoire windows). Vous devrez relancer les 2 commandes précdentes pour re-bénéficier des fonctionnalités de Docker.
L’exécution multiple des commandes n’a aucun incidence sur le système.

Les namespaces de SystemD

WSL utilise un unique service de type systemd comme processus principal (PID 1). Ce mode de fonctionnement bloque l’accès à une fonctionnalité principale et essentielle de systemd : les namespaces.

Les namespaces de systemd sont des espaces isolés créés pour chaque service systemd. Ils permettent de mieux gérer la gestion des ressources consommées par les services.
Cette fonctionnalité permet une implémentation simplifiée du système d’isolation des cgroups qui isole l’accès aux ressources systèmes des processus isolés.

Les composants récents (sous forme de paquets Linux) nécessitent de plus en plus l’utilisation de systemd pour les faire fonctionner. On se retrouve rapidement privés des paquets snap (Package Manager) ou kubeadm/kubelet (Kubernetes).
Un peu gênant comme contrainte…

Des issues sont régulièrement ouvertes chez Microsoft sur le sujet :

On trouve des alternatives au système du WSL qui surchargent le processus principal (PID 1) par un système de gestion des namespaces avec systemd.
Encore faut-il que les solutions soient stables et pérennes.

Voici quelques alternatives possibles :

Pour des taches simples, ces alternatives sont suffisantes. Dès que vous souhaitez pousser un peu plus loin, les alternatives montrent très vite leurs limites.

Exemple de minikube avec installation de kubelet sur la machine qui plante un beau jour et nécessite de réinstaller le WSL… #truestory

Pour installer Minikube, je vous invite à parcourir l’article Utiliser Kubernetes en local avec Minikube sous Windows 10.

Point de montage du disque Windows

La distribution installée avec le WSL permet d’être autonome sur l’utilisation de Linux. Cependant, vous aurez très certainement besoin d’accéder aux fichiers qui sont stockés sur votre disque accessible sur Windows : le disque C:\.

Tous les disques Windows sont montés dans le répertoire /mnt du WSL.
On retrouvera facilement le disque C:\ dans le répertoire /mnt/c/ avec toute l’arborescence qu’elle présente.

Sachez néanmoins que le montage du disque Windows dans le WSL n’est pas sans impact sur les performances. Le I/O disque en sont extrêmement dégradées sous WSL2 (comparé au WSL1).
Ne soyez pas étonné si la copie massive de fichiers prend du temps, ou que le gestionnaire de dépendance Node.js (npm ou yarn) est très lent comparé à d’habitude.

Des issues sont régulièrement ouvertes chez Microsoft sur le sujet :

  • https://github.com/microsoft/WSL/issues/4197

Le chemin pour accéder aux fichiers du WSL n’est aussi direct que l’on peut l’entendre. Plusieurs services Windows font le pont pour nous faciliter l’accès, mais le chemin est long.

Trucs & astuces

Mon adresse IP

Avec le WSL, on peut récupérer son adresse IP machine de plusieurs façon. Elle est notamment stockée dans le fichier /etc/resolv.conf.

Cette méthode nécessite de ne pas avoir modifier la propagation des resolvers DNS.

tail -1 /etc/resolv.conf | cut -d' ' -f2

Les options de la console

La console native proposée avec le WSL est quelque peu différents des consoles classique.

Copier dans la console

L’art du copier/coller n’a de secret pour personne. La console se veut déroutante pour les utilisateurs d’une console Putty Linux.

Pour copier du contenu :

  • Sélectionner le texte avec le curseur
  • Clic droit avec la souris

Coller dans la console en ligne de commande

Coller une valeur déjà copiée en mémoire à la souris revient à effectuer un clic droit. Coller en ligne de commande diffère du classique [Shift] + [Insert].

Pour coller du contenu depuis la ligne de commande : [Ctrl] + [Shift] + [V]

Il est également possible d’activer le collage classique en activant l’option Mode d’insertion depuis les propriétés de la console.

Conclusion

Le WSL2 de Microsoft offre des possibilités beaucoup plus grandes pour les Linuxiens qui utilisent Windows. Le WSL s’interface aussi très facilement aux IDE type Visual Studio, augmentant drastiquement l’intégration des applications aux systèmes Linux.

Même si des contraintes sont déjà visibles, les possibilités du WSL2 sont très larges. On peut à présent lancer Docker et scripter au format bash sans nécessiter “Docker for Windows” et complexifier la gestion des conteneurs au sein d’une équipe.

WSL2 nous réserve encore des surprises, on reste attentifs aux actualités de Microsoft pour les améliorations en cours ainsi que les nouvelles fonctionnalités.

Pour aller plus loin, vous pouvez parcourir l’article qui propulse Minikube sur le WSL2 en évitant les pièges, facilitant un bon démarrage. Vous trouverez l’article sur ce blog : Utiliser Kubernetes en local avec Minikube sous Windows 10.

Bibliographie