web-dev-qa-db-fra.com

Comment Docker peut-il exécuter des distributions avec différents noyaux?

Comment le docker peut-il fonctionner sur un hôte Debian, peut-être un OpenSUSE dans un conteneur? Il utilise un noyau différent, avec des modules séparés. De plus, les anciennes versions de Debian ont utilisé des noyaux plus anciens, alors comment peut-on l'exécuter sur une version de noyau 3.10+? Les noyaux plus anciens n'ont que des fonctions intégrées plus anciennes, comment une ancienne distribution peut-elle gérer de nouvelles fonctionnalités? Quel est "l'astuce" en elle?

37
plaidshirt

Comment Docker peut-il fonctionner sur un hôte Debian, peut-être un OpenSUSE dans un conteneur

Parce que le noyau est le même et prendra en charge le moteur Docker pour exécuter toutes ces images de conteneur: le noyau hôte doit être 3.10 ou plus, mais ses liste des appels système est assez stable.

Voir " Architecting Containers: Why Understanding User User vs. Kernel Space Matters ":

  1. Les applications contiennent une logique métier, mais reposent sur des appels système.
  2. Une fois qu'une application est compilée, l'ensemble des appels système qu'une application utilise (c'est-à-dire s'appuie sur) est incorporé dans le binaire (dans les langages de niveau supérieur, il s'agit de l'interpréteur ou de la JVM).
  3. Les conteneurs n'abstiennent pas de la nécessité pour l'espace utilisateur et l'espace noyau de partager un ensemble commun d'appels système.
  4. Dans un monde conteneurisé, cet espace utilisateur est regroupé et expédié à différents hôtes, allant des ordinateurs portables aux serveurs de production.
  5. Au cours des prochaines années, cela créera des défis.

https://rhelblog.files.wordpress.com/2015/07/user-space-vs-kernel-space-simple-container.png?w=584&h=231

De nouveaux appels système sont ajoutés de temps à autre et les anciens appels système sont obsolètes; cela doit être pris en compte lors de la réflexion sur le cycle de vie de votre infrastructure de conteneurs et les applications qui y seront exécutées.

Voir aussi " Pourquoi la version du noyau ne correspond pas à la version d'Ubuntu dans un conteneur Docker? ":

Il n'y a pas de noyau à l'intérieur d'un conteneur. Même si vous installez un noyau, il ne sera pas chargé au démarrage du conteneur. Le but même d'un conteneur est d'isoler des processus sans avoir besoin d'exécuter un nouveau noyau.

35
VonC

Docker n'utilise jamais un noyau différent: le noyau est toujours votre noyau hôte.

Si votre noyau hôte est "suffisamment compatible" avec le logiciel dans le conteneur que vous souhaitez exécuter, cela fonctionnera; sinon ce ne sera pas le cas.

Les "conteneurs" ne sont que des configurations de processus

L'essentiel à comprendre est qu'un conteneur Docker n'est pas une machine virtuelle: il ne crée pas un nouvel ordinateur virtuel sur lequel exécuter le logiciel. Au lieu de cela, Docker exécute simplement des processus dans votre système d'exploitation existant, de la même manière que vous démarrez un processus à partir de la ligne de commande.

La différence entre un processus conteneurisé et un processus ordinaire réside dans les restrictions imposées au processus conteneurisé et aux changements dans la façon dont il voit l'environnement qui l'entoure. (Celles-ci sont transmises à tous les processus enfants démarrés par le processus conteneurisé.) Les restrictions et modifications typiques incluent:

  • Au lieu d'utiliser le système de fichiers racine de l'hôte, montez un système de fichiers différent sur / (généralement fourni avec l'image du conteneur). Des parties du système de fichiers hôte peuvent être montées sous le système de fichiers racine du nouveau processus, par ex. en utilisant docker run -v /u/myprogram-data:/var/data/myprogram de sorte que lorsque le processus conteneurisé lit ou écrit /var/data/myprogram/file ceci lit/écrit /u/myprogram-data/file dans le système de fichiers hôte.
  • Créez un espace de processus séparé pour le processus conteneurisé afin qu'il ne puisse voir que lui-même et ses enfants (avec ps ou des commandes similaires), mais ne puisse pas voir les autres processus en cours d'exécution sur l'hôte.
  • Créez un espace de noms d'utilisateurs distinct afin que les utilisateurs du conteneur soient différents de ceux de l'hôte: par exemple, l'UID 1234 dans le processus conteneurisé ne sera pas le même que l'UID 1234 pour les non conteneurisés
  • Créez un ensemble distinct d'interfaces réseau avec leurs propres adresses IP, en utilisant souvent un "routeur virtuel" et une traduction d'adresse entre celles-ci et les interfaces réseau hôtes. (Par exemple, l'hôte, lorsqu'il reçoit un paquet sur le port 8080, le transmet au port 80 sur l'interface réseau virtuelle des processus de conteneur.)

Tout cela est fait par des installations intégrées au noyau; vous pouvez le faire vous-même sans Docker si vous écrivez un programme pour effectuer la configuration appropriée et définir les paramètres appropriés au démarrage d'un nouveau processus.

Compatibilité

Que signifie "suffisamment compatible"? Cela dépend de ce que le programme demande au noyau (appels système) et des fonctionnalités qu'il attend du support. Certains programmes font des demandes qui vont casser des choses; d'autres non. Par exemple, sur un Ubuntu 18.04 (noyau 4.19) ou un hôte similaire:

  • docker run centos:7 bash fonctionne très bien.
  • docker run centos:6 bash échoue avec le code de sortie 139, ce qui signifie qu'il s'est terminé par un signal de violation de segmentation; c'est parce que le noyau 4.19 ne supporte pas quelque chose que la construction de bash a essayé de faire.
  • docker run centos:6 ls fonctionne très bien, car il ne fait pas de requête que le noyau ne peut pas gérer, comme bash.

Si tu essayes docker run centos:6 bash sur un noyau plus ancien, disons 4.9 ou antérieur, vous constaterez que cela fonctionnera bien. (Au moins pour autant que je l'ai testé.)

9
Curt J. Sampson