Technologie de conteneur : virtualisation du système d'exploitation prise en charge par les Cgroups et les espaces de noms

Table des matières

L'historique du développement de la virtualisation du système d'exploitation (technologie de conteneur)

En 1979, la version 7 d'UNIX a introduit la fonctionnalité Chroot. Chroot est maintenant considéré comme le prototype de la première technologie de virtualisation au niveau du système d'exploitation (virtualisation au niveau du système d'exploitation), qui est essentiellement une technologie d'isolation pour la couche du système de fichiers du système d'exploitation.

En 2006, Google a lancé la technologie Process Container (conteneur de processus) fonctionnant sous Linux. Son objectif est de fournir une limitation et une priorité des ressources au niveau du système d'exploitation similaire à Virtual Mahine (technologie de virtualisation informatique), mais principalement pour le contrôle des processus, capacité d'audit des ressources et capacité de contrôle des processus.

En 2007, Google a promu l'intégration du code Process Container dans le noyau Linux. Dans le même temps, étant donné que le nom Container a de nombreuses significations différentes dans le noyau, afin d'éviter toute confusion dans la dénomination du code, Process Container a été renommé Control Groups, appelé : Cgroups.

En 2008, la communauté Linux a intégré Chroot, Cgroups, Namespaces, SELinux, Seccomp et d'autres technologies et a publié la version LXC (Linux Container) v0.1.0. LXC réalise une virtualisation complète et légère du système d'exploitation en combinant la capacité de gestion des quotas de ressources de Cgroups et la capacité d'isolation de la vue des ressources de Namespace.

Le 15 mars 2013, lors de la Python Developers Conference qui s'est tenue à Santa Clara, en Californie, Solomon Hvkes, fondateur et PDG de DotCloud, a publié pour la première fois Docker basé sur le package LXC en un mini-speak de seulement 5 minutes. son code source et l'héberger sur Github après la réunion.

insérez la description de l'image ici

Chroot

Chroot est une interface d'appel système qui peut être appelée par le processus utilisateur, qui permet à un processus d'utiliser le répertoire spécifié comme répertoire racine (répertoire racine), puis toutes les opérations du système de fichiers du processus ne peuvent être effectuées que dans ce répertoire spécifié. Il s'appelle donc Changer la racine.

Le prototype de fonction de chroot() est très simple :

  • Autorité d'invocation : Utilisateur root.
  • Liste des paramètres formels :
    • chemin : un pointeur vers une chaîne de caractères, qui est un chemin absolu, indiquant le chemin du répertoire vers lequel modifier le répertoire racine du processus.
  • La fonction retourne :
    • succès : renvoie 0 ;
    • Échec : renvoie -1.
#include <unistd.h>

int chroot(const char *path);

Il convient de noter qu'après avoir changé le répertoire racine du processus, le processus ne peut accéder qu'aux fichiers et ressources du nouveau répertoire racine et de ses sous-répertoires. Par conséquent, après avoir appelé chroot(), assurez-vous que tous les fichiers et ressources auxquels le processus doit accéder existent sous le nouveau répertoire racine.

chroot() est actuellement principalement utilisé pour :

  1. Scénario d'isolation de sécurité : limitez la plage d'accès du processus pour améliorer la sécurité du système.
  2. Scénario d'environnement de débogage : créez un environnement isolé du système principal pour le débogage, les tests et l'exécution de Process.
  3. Scénario de sauvetage du système : lorsque le système d'exploitation Linux est endommagé ou attaqué, vous pouvez utiliser chroot pour basculer le processus vers le répertoire racine du système endommagé pour les opérations de réparation et de sauvetage.

On peut voir que chroot () fournit une isolation pour Process au niveau du système de fichiers Linux (système de fichiers), mais il ne fournit pas une isolation de sécurité complète et ne peut pas empêcher d'autres attaques. Par conséquent, afin d'obtenir une isolation de sécurité entre les processus, d'autres mesures de sécurité doivent être prises.

Cgroups

Cgroups (Control Groups) est une technologie de quota et de gestion des ressources du système d'exploitation pour le processus utilisateur ou le thread du noyau fourni par le noyau Linux. Il comprend principalement les quatre aspects suivants :

  1. Quota de ressource : Limite le quota d'utilisation d'une ressource système par un processus.
  2. Priorité : En cas de concurrence des ressources, quels processus doivent prioriser l'utilisation des ressources.
  3. Audit : surveillez et générez des rapports sur les limites et l'utilisation des ressources par les processus.
  4. Contrôle : contrôle l'état du processus, par exemple : en cours d'exécution, suspendu, repris.

Les concepts de base de la conception et de la mise en œuvre des Cgroups sont illustrés dans la figure ci-dessous, notamment :

  1. libcgroups : Fournit un ensemble de bibliothèques et d'applications d'interface de programmation.
  2. Tâches : Abstraction unifiée du processus utilisateur et du thread noyau. Étant donné que le processus utilisateur ou le thread du noyau dans le noyau ne se distinguent en fait que par les paramètres passés par clone() SCI, ils utilisent tous la description task_struct.
  3. Sous-systèmes : définitions de type pour les ressources contrôlables.
  4. Groupe de contrôle (cgroup) : C'est une description de groupe de contrôle de ressource utilisée pour associer plusieurs Tâches et Sous-systèmes. Le groupe de contrôle en minuscules est utilisé ci-dessous pour décrire un groupe de contrôle spécifique.
  5. Cgroup Filesystem : fournit une entrée de configuration de cgroup à l'espace utilisateur via l'interface de fichiers unifiée VFS (Virtual File System).

insérez la description de l'image ici

Sous-systèmes de Cgroup

Cgroups définit différents types de ressources système pouvant être contrôlées en tant que sous-systèmes (sous-systèmes), notamment :

  • cpu : limite le taux d'utilisation d'un seul cœur de processeur d'une tâche.
  • cpuset : Limite l'ensemble de cœurs de processeur utilisés par la tâche.
  • cpuacct : rapport d'utilisation du processeur de la tâche de statistiques (comptabilité).
  • memory : limite la capacité mémoire utilisée par la tâche.
  • énormetlb : limite la capacité de mémoire de page énorme de la tâche.
  • devices : limitez les périphériques auxquels la tâche peut accéder.
  • blkio : Limite l'utilisation des blocs d'E/S de la tâche.
  • net_cls : limite le type de paquet réseau de la tâche (Network Classifier) ​​​​et l'utilisation des E/S réseau.
  • net_prio : définit la priorité de traitement du trafic réseau de la tâche (trafic réseau).
  • espace de noms : restreignez les tâches pour qu'elles utilisent différents espaces de noms.
  • freezer : suspend ou reprend la tâche spécifiée.
  • perf_event : Permet la surveillance avec l'outil perf.
  • pids : Limite le nombre de Tâches associées à un cgroup.
  • etc.

La définition de ces sous-systèmes consiste principalement à fournir des entrées de configuration correspondantes, et la mise en œuvre de restrictions de ressources système spécifiques consiste à réutiliser entièrement divers modules fonctionnels du noyau lui-même, par exemple :

  • Le sous-système cpu s'appuie sur l'implémentation du planificateur de processus du noyau.
  • Le sous-système de mémoire s'appuie sur l'implémentation du gestionnaire de mémoire du noyau.
  • Le sous-système net_cls dépend de l'implémentation de Kerne Traffic Control.
  • etc.

Vous pouvez afficher les sous-systèmes Cgroup pris en charge dans le système via la CLI :

$ sudo yum install libcgroup-tools

$ lssubsys -a
cpuset
cpu,cpuacct
blkio
memory
devices
freezer
net_cls,net_prio
perf_event
hugetlb
pids
rdma

Système de fichiers CgroupComment

Cgroups fournit une entrée de configuration de groupe de contrôle unifiée à Userspace via l'interface de fichiers Kernel VFS (Virtual File System, système de fichiers virtuel).

Vous pouvez afficher le chemin de montage et le contenu du système de fichiers Cgroup actuel via la CLI :

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
...
tmpfs            16G     0   16G   0% /sys/fs/cgroup

$ ll /sys/fs/cgroup/
总用量 0
drwxr-xr-x. 4 root root  0 61 16:22 blkio
lrwxrwxrwx. 1 root root 11 61 16:22 cpu -> cpu,cpuacct
lrwxrwxrwx. 1 root root 11 61 16:22 cpuacct -> cpu,cpuacct
drwxr-xr-x. 4 root root  0 61 16:22 cpu,cpuacct
drwxr-xr-x. 2 root root  0 61 16:22 cpuset
drwxr-xr-x. 4 root root  0 61 16:22 devices
drwxr-xr-x. 2 root root  0 61 16:22 freezer
drwxr-xr-x. 2 root root  0 61 16:22 hugetlb
drwxr-xr-x. 4 root root  0 61 16:22 memory
lrwxrwxrwx. 1 root root 16 61 16:22 net_cls -> net_cls,net_prio
drwxr-xr-x. 2 root root  0 61 16:22 net_cls,net_prio
lrwxrwxrwx. 1 root root 16 61 16:22 net_prio -> net_cls,net_prio
drwxr-xr-x. 2 root root  0 61 16:22 perf_event
drwxr-xr-x. 4 root root  0 61 16:22 pids
drwxr-xr-x. 4 root root  0 61 16:22 systemd

On peut voir que par défaut, les Cgroups créeront leur propre système de fichiers Cgroup pour les sous-systèmes, qui contient les fichiers nécessaires pour définir des quotas de ressources et s'associer à plusieurs tâches. Comme suit.

$ ll /sys/fs/cgroup/memory/
总用量 0
-rw-r--r--.  1 root root 0 61 16:22 cgroup.clone_children
--w--w--w-.  1 root root 0 61 16:22 cgroup.event_control
-rw-r--r--.  1 root root 0 61 16:22 cgroup.procs
-r--r--r--.  1 root root 0 61 16:22 cgroup.sane_behavior
-rw-r--r--.  1 root root 0 61 16:22 memory.failcnt
--w-------.  1 root root 0 61 16:22 memory.force_empty
-rw-r--r--.  1 root root 0 61 16:22 memory.kmem.failcnt
-rw-r--r--.  1 root root 0 61 16:22 memory.kmem.limit_in_bytes
-rw-r--r--.  1 root root 0 61 16:22 memory.kmem.max_usage_in_bytes
-r--r--r--.  1 root root 0 61 16:22 memory.kmem.slabinfo
-rw-r--r--.  1 root root 0 61 16:22 memory.kmem.tcp.failcnt
-rw-r--r--.  1 root root 0 61 16:22 memory.kmem.tcp.limit_in_bytes
-rw-r--r--.  1 root root 0 61 16:22 memory.kmem.tcp.max_usage_in_bytes
-r--r--r--.  1 root root 0 61 16:22 memory.kmem.tcp.usage_in_bytes
-r--r--r--.  1 root root 0 61 16:22 memory.kmem.usage_in_bytes
-rw-r--r--.  1 root root 0 61 16:22 memory.limit_in_bytes
-rw-r--r--.  1 root root 0 61 16:22 memory.max_usage_in_bytes
-rw-r--r--.  1 root root 0 61 16:22 memory.memsw.failcnt
-rw-r--r--.  1 root root 0 61 16:22 memory.memsw.limit_in_bytes
-rw-r--r--.  1 root root 0 61 16:22 memory.memsw.max_usage_in_bytes
-r--r--r--.  1 root root 0 61 16:22 memory.memsw.usage_in_bytes
-rw-r--r--.  1 root root 0 61 16:22 memory.move_charge_at_immigrate
-r--r--r--.  1 root root 0 61 16:22 memory.numa_stat
-rw-r--r--.  1 root root 0 61 16:22 memory.oom_control
----------.  1 root root 0 61 16:22 memory.pressure_level
-rw-r--r--.  1 root root 0 61 16:22 memory.soft_limit_in_bytes
-r--r--r--.  1 root root 0 61 16:22 memory.stat
-rw-r--r--.  1 root root 0 61 16:22 memory.swappiness
-r--r--r--.  1 root root 0 61 16:22 memory.usage_in_bytes
-rw-r--r--.  1 root root 0 61 16:22 memory.use_hierarchy
-rw-r--r--.  1 root root 0 61 16:22 notify_on_release
-rw-r--r--.  1 root root 0 61 16:22 release_agent
drwxr-xr-x. 55 root root 0 61 16:23 system.slice
-rw-r--r--.  1 root root 0 61 16:22 tasks
drwxr-xr-x.  2 root root 0 61 16:23 user.slice

Parmi eux, le fichier d'interface Core de cgroup est préfixé par cgroup :

  • cgroup.clone_children : Identifie si le cgroup enfant héritera du cgroup parent. La valeur par défaut est 0, ce qui signifie qu'il n'y a pas d'héritage.
  • cgroup.procs : Lorsqu'il s'agit du groupe de contrôle racine, tous les PID de la hiérarchie seront enregistrés.
  • etc.

Celui préfixé par memory est le fichier d'interface du contrôleur, qui est le contrôleur conçu par le modèle d'allocation de ressources Cgroups, comprenant :

  1. Pondération : allouer les ressources selon le ratio de pondération.
  2. limit(max) : limiter la surutilisation des ressources.
  3. Protection : Il peut s'agir d'une protection dure ou d'une protection souple.
  4. Allocation : Paramètres d'allocation des ressources.

Le reste a également un fichier d'interface de gestion, par exemple :

  • notify_on_release : indique s'il faut exécuter release_agent lorsque la dernière tâche de ce groupe de contrôle se termine.
  • release_agent : C'est un chemin, qui est utilisé pour nettoyer automatiquement les cgroups inutilisés après la sortie de la tâche.
  • tâches : enregistre la liste des tâches associées à ce groupe de contrôle.

Hiérarchie des groupes de contrôle

Les Cgroups utilisent la méthode Filesystem pour fournir une entrée d'opération, et un autre avantage qu'elle apporte est qu'elle prend en charge la forme organisationnelle de Cgroup Hierarchy (hiérarchique), qui est représentée sous la forme d'une structure arborescente.

Lorsque l'utilisateur crée un groupe de contrôle enfant dans le groupe de contrôle parent, le groupe de contrôle enfant crée également automatiquement les fichiers de configuration requis et peut configurer s'il doit hériter de la configuration pertinente du groupe de contrôle parent. Comme indiqué ci-dessous.

$ mkdir /sys/fs/cgroup/memory/cgrp1/

$ ls /sys/fs/cgroup/memory/cgrp1/
cgroup.clone_children  memory.kmem.limit_in_bytes          memory.kmem.tcp.usage_in_bytes  memory.memsw.max_usage_in_bytes  memory.soft_limit_in_bytes  tasks
cgroup.event_control   memory.kmem.max_usage_in_bytes      memory.kmem.usage_in_bytes      memory.memsw.usage_in_bytes      memory.stat
cgroup.procs           memory.kmem.slabinfo                memory.limit_in_bytes           memory.move_charge_at_immigrate  memory.swappiness
memory.failcnt         memory.kmem.tcp.failcnt             memory.max_usage_in_bytes       memory.numa_stat                 memory.usage_in_bytes
memory.force_empty     memory.kmem.tcp.limit_in_bytes      memory.memsw.failcnt            memory.oom_control               memory.use_hierarchy
memory.kmem.failcnt    memory.kmem.tcp.max_usage_in_bytes  memory.memsw.limit_in_bytes     memory.pressure_level            notify_on_release

insérez la description de l'image ici

Enfin, un fichier de tâches est inclus dans le système de fichiers de chaque groupe de contrôle, qui est utilisé pour enregistrer la liste des tâches associées au groupe de contrôle courant. Si nous voulons ajouter un processus utilisateur à un groupe de contrôle, nous pouvons écrire son PID dans le fichier de tâches. comme suit:

$ cd /sys/fs/cgroup/memory/cgrp1    # 进入 cgrp1
$ echo 1029 > tasks                 # 将 PID 1029 的 Process 添加到 cgrp1 的 tasks 列表

Règles de fonctionnement des Cgroups

Lors de l'utilisation de Cgroups, les utilisateurs doivent suivre certaines règles de fonctionnement, sinon des erreurs se produiront. Le but des règles de fonctionnement est d'éviter les conflits dans la configuration des quotas de ressources.

  1. Une hiérarchie peut attacher plusieurs sous-systèmes, comme illustré dans la figure ci-dessous, les sous-systèmes de processeur et de mémoire sont attachés à la même hiérarchie.
    insérez la description de l'image ici

  2. Un sous-système qui a été attaché ne peut être à nouveau attaché qu'à une hiérarchie vide et ne peut pas être attaché à une hiérarchie qui a été attachée à d'autres sous-systèmes. Comme illustré dans la figure ci-dessous, le sous-système cpu a été attaché à la hiérarchie A, et le Le sous-système de mémoire a été attaché à la hiérarchie B. Par conséquent, le sous-système cpu ne peut plus être attaché à la hiérarchie B, mais peut uniquement être attaché à une autre hiérarchie C vide.
    insérez la description de l'image ici

  3. Chaque tâche ne peut se trouver que dans les seules tâches de groupe de contrôle de la même hiérarchie et peut se trouver dans plusieurs tâches de groupe de contrôle de hiérarchie différente. Comme illustré dans la figure ci-dessous, cela garantit que le même quota de groupe de contrôle pour une tâche est unique.
    insérez la description de l'image ici

  4. Lorsque le processus enfant est forké, il hérite automatiquement des cgroups du processus parent, mais après le fork, il peut être ajusté à d'autres cgroups selon les besoins, comme illustré dans la figure suivante :
    insérez la description de l'image ici

Implémentation du code des Cgroups

Revenons maintenant à la déclaration et à la définition de cgroup dans Kernel, qui est conçu comme une structure de données arborescente :

struct cgroup {
    
    
    ...
    // 下面 3 个字段把 cgroup 设计成了一个树数据结构
    struct list_head sibling;   // 兄弟节点
    struct list_head children;  // 子节点
    struct cgroup *parent;      // 父节点

    struct dentry *dentry;      // cgroup 对应的目录对象

    // cgroup 关联的 subsystems 对象
    struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; 
    ...
};

insérez la description de l'image ici

Par défaut, lors du démarrage du noyau, un rootnode (nœud racine) est automatiquement instancié, et tous les FS du cgroup des sous-systèmes sont associés à ce rootnode.

static struct cgroupfs_root rootnode;

struct cgroupfs_root {
    
    
    struct super_block *sb;            // Root cgroup FS 的挂载点(VFS 使用)
    ...
    struct list_head subsys_list;      // Root cgroup 绑定的 Subsystems 列表
    struct cgroup top_cgroup;          // Root cgroup 对象
    int number_of_cgroups;             // Root cgroup 拥有的 cgroups 的数量
    ...
};

Si les utilisateurs souhaitent monter manuellement des sous-systèmes sur d'autres FS de groupe de contrôle, ils peuvent également utiliser la commande mount pour monter, comme indiqué dans la commande suivante :

$ mount -t cgroup -o memory memory /sys/fs/cgroup/memory1

De plus, le champ cgroup_subsys_state dans cgroup est utilisé pour s'associer à une liste d'état de sous-systèmes (structure de statistiques de ressources de sous-systèmes), puis s'associer à plusieurs sous-systèmes spécifiques.

struct cgroup_subsys_state {
    
    
    struct cgroup *cgroup; // 指向 cgroup 对象
    atomic_t refcnt;       // 引用计数器
    unsigned long flags;   // 标志位
};

struct mem_cgroup {
    
    
    // 资源统计对象通用部分
    struct cgroup_subsys_state css;

    // 资源统计对象私有部分
    struct res_counter res;  // 用于统计 tasks 的内存使用情况
    struct mem_cgroup_lru_info info;
    int prev_priority;
    struct mem_cgroup_stat stat;
};

insérez la description de l'image ici

On peut voir que cgroup et les sous-systèmes ont une relation un-à-plusieurs, comme illustré dans la figure ci-dessous.
insérez la description de l'image ici

Dans le même temps, comme une tâche peut être associée à plusieurs groupes de contrôle, la relation plusieurs-à-plusieurs entre les tâches et les sous-systèmes est finalement réalisée. Comme indiqué ci-dessous:

  • ProcessA appartient à /sys/fs/cgroup/memory/cgrp1/cgrp3 et /sys/fs/cgroup/cpu/cgrp2/cgrp3, donc ProcessA est associé à deux états de sous-systèmes Cgroup, mem_groupA et task_groupA.
  • ProcessB appartient à /sys/fs/cgroup/memory/cgrp1/cgrp4 et /sys/fs/cgroup/cpu/cgrp2/cgrp3, donc ProcessB est associé aux deux états des sous-systèmes Cgroup mem_groupB et task_groupA.

insérez la description de l'image ici

Dans la structure task_struct de la tâche, enregistrez la liste d'état des sous-systèmes Cgroup qui lui est associée via le champ css_set, comme suit :

struct task_struct {
    
    
    ...
    struct css_set *cgroups;
    ...
};

struct css_set {
    
    
    ...
    // 用于收集不同 cgroup 的资源统计对象
    struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
};

Enfin, une structure de relation de mappage de liaison M × N est formée entre le processus utilisateur et les groupes C. Comme indiqué ci-dessous.

insérez la description de l'image ici

Espaces de noms

Les espaces de noms Linux (espace de noms) sont une technologie d'isolation de la vue des ressources au niveau du système d'exploitation, qui peut diviser les ressources globales de Linux en ressources visibles dans la portée de l'espace de noms.

Il existe de nombreux types d'espaces de noms, qui couvrent essentiellement les éléments de base requis pour former un système d'exploitation :

  1. Espace de noms UTS (nom d'hôte du système)
  2. Espace de noms de temps (heure système)
  3. Espace de noms PID (numéro de processus système)
  4. Espace de noms IPC (communication interprocessus système)
  5. Monter l'espace de noms (système de fichiers système)
  6. Espace de noms réseau (réseau système)
  7. Espace de noms d'utilisateur (autorisations d'utilisateur système)
  8. Espace de noms Cgroup (système Cgroup)

Le processus utilisateur est l'objet de service principal de l'espace de noms, et il existe trois principaux SCI qui lui sont liés :

  1. clone() : créez un processus et définissez le paramètre de type de l'instance d'espace de noms en même temps.
  2. setns() : ajoute un processus à l'instance d'espace de noms spécifiée.
  3. unshare() : supprimez un processus de l'instance d'espace de noms spécifiée.

Comme le montre la figure ci-dessous, chaque Namespaces a son propre paramètre de type de clone :
insérez la description de l'image ici

Grâce au fichier /proc/{pid}/ns, vous pouvez voir dans quelles instances d'espaces de noms le processus spécifié s'exécute, et chaque instance d'espace de noms a un identifiant unique.

$ ls -l --time-style='+' /proc/$$/ns
总用量 0
lrwxrwxrwx. 1 root root 0  ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 root root 0  mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 root root 0  net -> net:[4026531956]
lrwxrwxrwx. 1 root root 0  pid -> pid:[4026531836]
lrwxrwxrwx. 1 root root 0  user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0  uts -> uts:[4026531838]

En fin de compte, les utilisateurs peuvent créer une variété de différents types d'instances d'espaces de noms pour fournir une isolation des ressources du système d'exploitation, combinées à la création d'une variété de différents types de groupes de contrôle pour fournir des quotas de ressources du système d'exploitation, cela constitue un conteneur de système d'exploitation de base. Conteneur de processus.

Espace de noms UTS

L'espace de noms UTS fournit l'isolation du nom d'hôte et du nom de domaine pour le conteneur.

Le processus dans le conteneur peut être configuré en appelant les commandes sethostname et setdomainname selon les besoins, de sorte que chaque conteneur puisse être considéré comme un nœud indépendant dans le réseau.

Espace de noms PID

L'espace de noms PID fournit l'isolation de l'ID de processus pour le conteneur.

Chaque conteneur a son propre environnement de processus et le processus d'initialisation du conteneur est le processus PID n ° 1, qui agit en tant que processus parent de tous les processus enfants. Afin d'obtenir l'isolation des processus, vous devez d'abord créer un processus avec le PID 1, qui présente les caractéristiques suivantes :

  • Si un processus enfant quitte le processus parent (le processus parent ne l'attend pas), alors le processus init sera responsable de la récupération des ressources et de la fin du processus enfant.
  • Si le processus d'initialisation est terminé, le noyau appellera SIGKILL pour terminer tous les processus dans cet espace de noms PID.

Espace de noms IPC

L'espace de noms IPC fournit l'isolation des mécanismes de communication IPC (inter-processus) pour les conteneurs, y compris des mécanismes tels que les sémaphores, les files d'attente de messages et la mémoire partagée.

Chaque conteneur possède l'interface de fichier /proc suivante :

  • /proc/sys/fs/mqueue : type d'interface des files d'attente de messages POSIX ;
  • /proc/sys/kernel : type d'interface System V IPC ;
  • /proc/sysvipc : type d'interface System V IPC.

Monter l'espace de noms

L'espace de noms Mount fournit l'isolation du point de montage du système de fichiers pour le conteneur, puis réalise l'isolation du VFS.

Chaque conteneur possède l'interface de fichier /proc suivante, qui peut former un rootfs indépendant (système de fichiers racine) :

  • /proc/[pid]/montages
  • /proc/[pid]/mountinfo
  • /proc/[pid]/mountstats

En fait, l'espace de noms Mount est développé sur la base de l'amélioration continue de Chroot. Le rootfs créé pour Container ne comprend que les fichiers, répertoires et configurations contenus dans une distribution de système d'exploitation, et n'inclut pas les fichiers Kernel.

Espace de noms réseau

L'espace de noms réseau fournit l'isolation des ressources réseau pour Container, notamment :

  • Périphériques réseau
  • Piles de protocoles IPv4 et IPv6 (pile de protocoles IPv4, IPv6)
  • Tables de routage IP
  • Règles de pare-feu
  • Prises
  • /proc/[pid]/net
  • /sys/classe/net
  • /proc/sys/net

Il convient de noter que le même périphérique réseau ne peut exister que dans une seule instance d'espace de noms, il est donc souvent utilisé en combinaison avec des périphériques réseau virtuels.

insérez la description de l'image ici

Espace de noms d'utilisateur

L'espace de noms d'utilisateur fournit à Container une isolation liée aux autorisations utilisateur et aux attributs de sécurité, notamment : l'ID utilisateur, l'ID de groupe d'utilisateurs, le répertoire racine et les autorisations spéciales.

Chaque conteneur possède l'interface de fichier /proc suivante :

  • /proc/[pid]/uid_map
  • /proc/[pid]/gid_map

Application de Docker aux Cgroups et aux espaces de noms

Lorsque nous créons un conteneur Docker, nous pouvons afficher les cgroups et les espaces de noms du conteneur.

  1. Vérifiez la configuration de l'ID de conteneur (cfca1212d140) et du PID (2240).
$ docker ps
CONTAINER ID   IMAGE                   COMMAND   CREATED         STATUS       PORTS     NAMES
cfca1212d140   centos:centos7.9.2009   "bash"    18 months ago   Up 2 hours             vim-ide

$ docker inspect --format='{
    
    {.State.Pid}}' cfca1212d140
2240
  1. Vérifiez la configuration des groupes de contrôle du conteneur.
$ ll /sys/fs/cgroup/memory/docker/
总用量 0
drwxr-xr-x. 2 root root 0 62 03:40 cfca1212d1407a89632a439e974e246d1f6edd0bbef9079f06addf2613e1d46f

$ cat /sys/fs/cgroup/memory/docker/cfca1212d1407a89632a439e974e246d1f6edd0bbef9079f06addf2613e1d46f/cgroup.procs 
2240

$ cat /sys/fs/cgroup/memory/docker/cfca1212d1407a89632a439e974e246d1f6edd0bbef9079f06addf2613e1d46f/memory.limit_in_bytes
9223372036854771712
  1. Consultez la configuration des espaces de noms du conteneur.
$ ls -l --time-style='+' /proc/2240/ns
总用量 0
lrwxrwxrwx. 1 root root 0  ipc -> ipc:[4026532433]
lrwxrwxrwx. 1 root root 0  mnt -> mnt:[4026532431]
lrwxrwxrwx. 1 root root 0  net -> net:[4026531956]
lrwxrwxrwx. 1 root root 0  pid -> pid:[4026532434]
lrwxrwxrwx. 1 root root 0  user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0  uts -> uts:[4026532432]

documents de référence

  • https://mp.weixin.qq.com/s/EdRVEJ0i5j9eHwd8QK-cDg
  • https://juejin.cn/post/6921299245685276686
  • https://zhuanlan.zhihu.com/p/388101355

Je suppose que tu aimes

Origine blog.csdn.net/Jmilk/article/details/130993558
conseillé
Classement