Apple Silicon : Docker est beaucoup plus lent directement sous macOS qu’en virtualisant Linux 🆕
Mise à jour le 29/12/2021
Des développeurs de Docker nous ont contacté pour signaler un point important lié aux performances. Plus que le système utilisé pour faire fonctionner l’app, c’est le type de conteneur qui peut faire la différence sur les Mac Apple Silicon. Si l’on exécute un conteneur x86, il faut ajouter une couche d’émulation en plus de la virtualisation qui est toujours présente avec Docker et cela peut ralentir considérablement les performances. Dans l’exemple de notre lecteur, c’est a priori l’explication pour le gain en passant sous Ubuntu : un conteneur arm64 a été créé, ce qui élimine cet intermédiaire supplémentaire.
Cela étant dit, il reste des problèmes de performances connus de Docker sous macOS, liés notamment à la gestion des fichiers. Une tâche est ouverte à ce sujet depuis le printemps 2020 et des versions expérimentales sont proposées pour corriger, au moins en partie, ces problèmes.
Article original
L’app pour macOS de Docker est optimisée pour les Mac Apple Silicon depuis le printemps dernier, mais cela ne veut pas dire que tout fonctionne parfaitement pour autant pour ce gestionnaire de conteneurs logiciels très utilisé dans le monde du développement web. Un lecteur nous a alerté sur un drôle de bug : la construction initiale du conteneur prend énormément de temps sur son MacBook Air M1 doté de 16 Go de RAM. Ce n’est pas l’ordinateur qui est en cause, car il obtient de bien meilleurs résultats sur la même machine et en passant par Linux.
Dans ses tests, il a noté une différence énorme pour créer le même conteneur avec la version macOS de Docker et la version intégrée à Ubuntu, une distribution Linux. Alors qu’il lui faut environ 2 600 secondes pour obtenir son conteneur prêt à emploi avec l’app macOS, il ne lui faut que 210 secondes pour atteindre le même résultat en passant par Linux. C’est plus de 12 fois plus rapide, sur le même MacBook Air et alors même qu’il ajoute une couche de virtualisation en plus de macOS !
Il y a manifestement un gros bug dans Docker qui justifie cet écart important. Quoi qu’il en soit, ce lecteur a noté d’autres témoignages similaires, dont cet article de LifeinTech publié en novembre dernier qui donne des chiffres avec un Apple M1 Max bien plus puissant que l’Apple M1 évoqué précédemment. Le processeur n’est pas en cause et le meilleur résultat de tous les tests réalisés par le site est fourni par le MacBook Pro, mais en virtualisation sous Linux encore une fois.
Ce qui est étonnant, c’est que ce problème n’est pas récent et on trouve facilement des témoignages depuis le printemps. Pourquoi est-ce que les développeurs de Docker ne le corrigent pas ? S’agit-il d’un bug de leur côté, ou bien du côté d’Apple et de macOS ? En fouillant un petit peu plus, on découvre d’autres articles qui datent d’avant la sortie des Mac Apple Silicon et qui se plaignent des mauvaises performances de Docker pour macOS. Le logiciel souffre a priori de mauvaises optimisations que la transition vers les nouvelles puces d’Apple pourrait avoir accentuées.
En attendant un correctif, le plus simple semble être de passer par une distribution Linux en virtualisation par dessus macOS. Cela fait deux couches virtuelles au lieu d’une, mais les chiffres que l’on peut croiser prouvent que cela fonctionne. En utilisant Multipass, on peut obtenir un Ubuntu virtualisé avec une seule ligne de commande et très rapidement, c’est la solution finalement utilisée par notre lecteur sur son MacBook Air M1.
Multipass : Ubuntu sur les Mac M1 en moins d’une minute
Rien ne vaut un petit serveur Linux dédié à docker, ne serait-ce que pour créer un réseau macvlan :)
@radeon
Le top avec un NAS. J’ai mis Homebridge dessus. Impeccable.
@RonDex
Idem, j’ai fait un peu joujou avec homebridge pour ma tv Samsung sous tizen. C’est pas parfait mais ça fait le job
Question à la rédaction, par quel canal avez vous l’information quand vous en faites un sujet : est-ce lié à un message sur le forum ou est-ce que la personne vous prévient directement ?
@CorbeilleNews
Ça dépend, là en l'occurrence c'est un contact direct, mais ça peut être nous qui surveillons les forums aussi…
Si vous avez une info, n'hésitez jamais à nous l'envoyer (redaction@mgig.fr), on est toujours preneurs !
@nicolasf
J’ai tenté il y a quelques semaines mais aucune réponse 😔 (le sujet n’était pas forcément suffisamment pertinent à vos yeux mais sans retour de votre part je ne sais même pas s’il a fini dans vos spams 😅)
@ssssteffff
Ça arrive que ça se perde, désolé. 😕
C’était quoi le sujet ?
@nicolasf
Aucun souci Nicolas 😉
Il s’agissait d’un mail (30/11) dans lequel je vous faisais part de mon analyse (partielle) sur l’indexation des photos (suite à votre article sur le sujet). Ce n’est pas forcément un article clés en main, mais le sujet semblant toucher une grande partie des utilisateurs iOS/macOS il me semblait pertinent de partager avec vous mon retour d’expérience sur le sujet. Si vous souhaitez creuser je suis à dispo pour en discuter, et si cela ne vous semble pas pertinent il n’y a aucun souci !
Effectivement, docker est une des 2 raisons pour lesquelles je suis resté sur mon MBP 2018 et que je ne suis pas passé sur M1 (la seconde étant l’encoche). Déjà que j’ai des perfs moyennes par rapport aux autres sur Linux (j’ai dû surcharger les infos de timeout sur les fichiers de config…)
C'est pas nouveau, et d'ailleurs on le voit aussi sur les chiffres de la machine Intel sous macOS. Docker pour macOS souffre de lenteur d'accès disque notamment lorsqu'on utilise des point de montage (bind mount).
C'est pas nouveau non, mais là on parle pas de quelques minutes de differences mais d'une 40n.
Non, 220 à 480 secondes ça fait entre 3 minutes 40 secs et 8 minutes, donc pas une quarantaine.
Le cas du Docker x86 sur M1 c'est franchement pas très recommandable de toute façon, car ça passe par QEmu pour l'émulation CPU (et non Rosetta) qui n'est pas très performant. Donc pas étonnant que les performances soient exécrables dans ce cas de figure, car on ajoute aux performances déjà très mauvaise du système de fichier de bind mounting de Docker for Mac le coût de l'émulation x86 via QEmu.
Et non c'est pas nouveau ces ordres de grandeurs, d'ailleurs on le voit bien le Docker for Mac sur Mac Intel donne le même niveau de performance que le Docker for Mac sur Mac Apple Silicon en natif ARM64 (c'est même un chouilla moins bon sur le Mac Intel).
@Frodon
Je suis plutôt d’accord que c’est « vicieux » (pour ne pas dire tordu) de monter des conteneurs x86 sur une plateforme arm 👍
Par contre je ne sais pas de où tu as pris tes chiffres.
Entre une image x86 et arm la ratio est en gros x10. Si je orends les chiffres de @weeta on passe de 200 a 2000 secondes. Donc 30 mins de plus pour le x86
Bon, avec ces elements je me demande si mon futur mac m1 pro sera suffisant ou est ce que je dois investir dans un petit pc linux dédié a docker (casual coding, ce n’est pas/plus mon job)
Les perfs sur M1 Max sont excellentes lors des build de container linux/arm64.
Par contre, je confirme que les build de containers linux/amd64 sont catastrophiques.
Exemple avec la lib grpc c#:
- linux/arm64 sur M1 Max : 283s
- linux/amd64 sur M1 Max : 2004s
- linux/amd64 sur un 5900x avec Docker Desktop Windows WSL2 : 303s
Un autre soucis concerne les crashs aléatoires de build linux/amd64: qemu: uncaught target signal 11 (Segmentation fault)
@WeetA
En même temps, on passe par la couche QEMU pour cross-compiler pour une autre plateforme.
Je ne suis pas sûr que la VM LinuxKit utilisé par Docker sous macOS, soit la meilleure pour ce genre de chose. Il serait intéressant de voir la cross-compilation via d’autres distributions avec Parallels Desktop et VMWare Fusion, voire même Multipass.
Il faut aussi voir ce que la donne la cross-compilation avec buildx et buildkit donc.
Et on peut aussi faire ce genre de build sur un environnement d’integration continue.
En tout cas, je trouve cela fort intéressant pour la monter en puissance d’ARM dans les serveurs surtout quand on voit Graviton sur AWS et Ampere Computing.
Scaleway avait eu une bonne idée avec ses instances C1 et ARM64, il aurait dû continuer.
L’Europe pourrait jouer un grand rôle dans les processeurs ARM, voire même RISC-V.
C'est sûr que la couche qemu n'aide pas.
Sinon, j'avais testé vite fait avec
et sansbuildkit (activé par défaut dans le json du docker engine via features.buildkit: true)Je n'avais pas vu trop de différence.
Après, je n'ai pas fait de tests poussés :)
@WeetA
J’allais poser la question, merci pour la réponse !
Sait-on si le problème vient de « docker » ou de sa couche de virtualisation nécessaire sur Windows / Mac ? Il pourrait être intéressant de faire le même test sur Windows sur M1, non ?
Il faudra que je refasse des tests plus sérieux :)
- docker desktop macOS build (arm64/amd64) avec et sans virtualization.framework
- docker desktop macOS buildx build (arm64/amd64) avec et sans virtualization.framework
- mutipass + docker (arm64/amd64)
- docker desktop Windows WSL2 build (amd64/arm64)
- docker desktop Windows WSL2 buildx (amd64/arm64)
@WeetA
Si jamais vous faites ces tests, je suis intéressé par le résultat ! 😉
corrigez-moi si je me trompe:
docker windows = hyper-v + linux kernel
docker mac = hyperkit + linux kernel
docker linux = linux kernel
c'est bien ça ?
@aspartame
Yep, l’article est mal recherché (rien que de limiter docker au web…). Docker fonctionne avec cgroups, une fonctionnalité du kernel de linux. Donc sous Mac ou autre on doit avoir une couche en plus d’abstraction. Bien sûr que sous un linux Docker va être plus rapide… Et rien de neuf avec M1, ça n’a juste rien à voir. Après que l’app Docket sous Mac soit moins performante qu’une virtualization c’est autre chose.
@aspartame
oui en dehors de Linux, Docker tourne avec linuxkit qui fonctionne avec l’un des hypervisor/hypervisor framework que vous mentionnez.
A ceci près pour windows, que docker peut aussi tourner sous WSL2, et dans ce cas c’est une couche de virtualization basée sur hyper-v, mais plus spécialisée (au sens ou seulement le nécessaire est reimplementé pour que WSL2 fonctionne).
@Sometime
Et là, encore, il faut faire une différence si on build dans le dossier WSL2 de Linux ou dans le disque Windows monter.
Et avec WSL2, le kernel Linux est implémentée par Microsoft, donc logiquement Docker ne devrait pas utiliser linuxkit.
Et sous macOS, il y a aussi plusieurs façons de monter le filesystem dans Docker (avec notamment l’utilisation de grpc fuse qui peut-être activé). Et il semblerait que notamment que le montage effectué par Parallels Desktop soit plus rapide.
C’est pour cela, que je trouve que l’on devrait regarder beaucoup plus pour faire fonctionner quelque chose comme VirtIO pour monter le filesystem.
Et essayer de beaucoup moins se reposer sur FUSE.
Le Mac en tant que machine de développement, macOS en tant que plateforme, a de moins en moins d’intérêt. C’est la plateforme obligée pour du développement iOS, mais pour le reste, de plus en plus de collègues quittent le bateau pour Windows/WSL qui est devenu très solide, très très solide.
La migration vers du hardware propriétaire y compris pour les CPU et GPU a certainement des avantages majeurs, mais tout aussi certainement des inconvénients majeurs également.
Bref. Le Mac n’est plus pour moi. Mes besoins de développement ne sont plus couverts par macOS. C’est la vie.
@fte
Je ne pense pas que le problème soit hardware mais plutôt « software ». Les logiciels de développement ne sont juste pas encore vraiment optimisés pour macOS et ARM. Maintenant, Apple devrait beaucoup plus s’ouvrir à certains niveaux et ils le font. On le voit avec Swift, Kubernetes,… Et l’aide qu’il donne aux logiciels Open Source. Une migration de ce type ne se fait pas en un claquement de doigts.
Mais le boulot accompli en un an est déjà incroyable et voilà seulement que l’on arrive avec des M1 Pro/Max réellement tailler pour le développement.
@fte
Par curiosité quels sont vos besoins ? En Python de mon côté je vois l’inverse. Tout le monde est sous Mac. On traîne tous pour supporter Windows et c’est toujours une galère pas possible (je parle de Windows pure, SciPy par ex). Et Windows avec WSL est un peu de la triche 😉