Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédente | |||
elearning:workbooks:docker3:drf08 [2021/11/23 08:59] – removed admin | elearning:workbooks:docker3:drf08 [2023/12/17 05:36] (Version actuelle) – created admin | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ~~PDF: | ||
+ | Version : **2022.01** | ||
+ | |||
+ | Dernière mise-à-jour : ~~LASTMOD~~ | ||
+ | |||
+ | ======DOF601 - La Virtualisation par Isolation====== | ||
+ | |||
+ | =====Contenu du Module===== | ||
+ | |||
+ | * **DOF601 - La Virtualisation par Isolation** | ||
+ | * Contenu du Module | ||
+ | * Présentation de la Virtualisation par Isolation | ||
+ | * Historique | ||
+ | * Présentation des Namespaces | ||
+ | * Présentation des CGroups | ||
+ | * LAB #1 - cgroups v1 | ||
+ | * 1.1 - Préparation | ||
+ | * 1.2 - Présentation | ||
+ | * 1.3 - Limitation de la Mémoire | ||
+ | * 1.4 - La Commande cgcreate | ||
+ | * 1.5 - La Commande cgexec | ||
+ | * 1.6 - La Commande cgdelete | ||
+ | * 1.7 - Le Fichier / | ||
+ | * 1.8 - La Commande cgconfigparser | ||
+ | * LAB #2 - cgroups v2 | ||
+ | * 2.1 - Préparation | ||
+ | * 2.2 - Présentation | ||
+ | * 2.3 - Limitation de la CPU | ||
+ | * 2.4 - La Commande systemctl set-property | ||
+ | * Présentation de Linux Containers | ||
+ | * LAB #3 - Travailler avec LXC | ||
+ | * 3.1 - Installation | ||
+ | * 3.2 - Création d'un Conteneur Simple | ||
+ | * 3.3 - Démarrage d'un Conteneur Simple | ||
+ | * 3.4 - S' | ||
+ | * 3.5 - Commandes LXC de Base | ||
+ | * La Commande lxc-console | ||
+ | * La Commande lxc-stop | ||
+ | * La Commande lxc-execute | ||
+ | * La Commande lxc-info | ||
+ | * La Commande lxc-freeze | ||
+ | * La Commande lxc-unfreeze | ||
+ | * Autres commandes | ||
+ | * 3.6 - Création d'un Conteneur Éphémère | ||
+ | * La Commande lxc-copy | ||
+ | * 3.7 - Sauvegarde des Conteneurs | ||
+ | * La Commande lxc-snapshot | ||
+ | |||
+ | =====Présentation de la Virtualisation par Isolation===== | ||
+ | |||
+ | Un isolateur est un logiciel qui permet d' | ||
+ | |||
+ | ====Historique==== | ||
+ | |||
+ | * **1979** - [[https:// | ||
+ | * **2000** - [[https:// | ||
+ | * **2004** - [[https:// | ||
+ | * **2005** - [[https:// | ||
+ | * **2008** - [[https:// | ||
+ | * **2013** - [[https:// | ||
+ | * **2014** - [[https:// | ||
+ | |||
+ | =====Présentation des Namespaces===== | ||
+ | |||
+ | Les espaces de noms permettent de regrouper des processus dans un même espace et d' | ||
+ | |||
+ | =====Présentation des CGroups===== | ||
+ | |||
+ | ====LAB #1 - cgroups v1==== | ||
+ | |||
+ | === 1.1 - Préparation=== | ||
+ | |||
+ | Debian 11 utilise cgroups v2 par défault. Pour revenir à l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | # If you change this file, run ' | ||
+ | # / | ||
+ | # For full documentation of the options in this file, see: | ||
+ | # info -f grub -n ' | ||
+ | |||
+ | GRUB_DEFAULT=0 | ||
+ | GRUB_TIMEOUT=5 | ||
+ | GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` | ||
+ | GRUB_CMDLINE_LINUX_DEFAULT=" | ||
+ | GRUB_CMDLINE_LINUX="" | ||
+ | |||
+ | # Uncomment to enable BadRAM filtering, modify to suit your needs | ||
+ | # This works with Linux (no patch required) and with any kernel that obtains | ||
+ | # the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...) | ||
+ | # | ||
+ | |||
+ | # Uncomment to disable graphical terminal (grub-pc only) | ||
+ | # | ||
+ | |||
+ | # The resolution used on graphical terminal | ||
+ | # note that you can use only modes which your graphic card supports via VBE | ||
+ | # you can see them in real GRUB with the command `vbeinfo' | ||
+ | # | ||
+ | |||
+ | # Uncomment if you don't want GRUB to pass " | ||
+ | # | ||
+ | |||
+ | # Uncomment to disable generation of recovery mode menu entries | ||
+ | # | ||
+ | |||
+ | # Uncomment to get a beep at grub start | ||
+ | # | ||
+ | |||
+ | root@debian11: | ||
+ | Generating grub configuration file ... | ||
+ | Found background image: / | ||
+ | Found linux image: / | ||
+ | Found initrd image: / | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | Redémarrez ensuite votre VM : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | === 1.2 - Présentation=== | ||
+ | |||
+ | Les **Groupes de Contrôles** (//Control Groups//) aussi appelés **CGroups**, | ||
+ | |||
+ | Les groupes de contrôle sont organisés de manière hiérarchique, | ||
+ | |||
+ | Ces hiérarchies multiples et séparés sont necéssaires parce que chaque hiérarchie est attaché à un ou plusieurs **sous-système(s)** aussi appelés des **Contrôleurs de Ressources** ou simplement des **Contrôleurs**. Les contrôleurs disponibles sous Debian 11 sont : | ||
+ | |||
+ | * **blkio** - utilisé pour établir des limites sur l' | ||
+ | * **cpu** - utilisé pour fournir aux tâches des groupes de contrôle accès au CPU grâce au planificateur, | ||
+ | * **cpuacct** - utilisé pour produire des rapports automatiques sur les ressources CPU utilisées par les tâches dans un groupe de contrôle, | ||
+ | * **cpuset** - utilisé pour assigner des CPU individuels sur un système multicoeur et des noeuds de mémoire à des tâches dans un groupe de contrôle, | ||
+ | * **devices** - utilisé pour autoriser ou pour refuser l' | ||
+ | * **freezer** - utilisé pour suspendre ou pour réactiver les tâches dans un groupe de contrôle, | ||
+ | * **memory** - utilisé pour établir les limites d' | ||
+ | * **net_cls** - utilisé pour repèrer les paquets réseau avec un identifiant de classe (// | ||
+ | * **perf_event** | ||
+ | * **hugetlb** - utilisé pour limiter des ressources sur des pages de mémoire virtuelle de grande taille. | ||
+ | |||
+ | Il est à noter que : | ||
+ | |||
+ | * chaque processus du système appartient à un cgroup et seulement à un cgroup à la fois, | ||
+ | * tous les threads d'un processus appartiennent au même cgroup, | ||
+ | * à la création d'un processus, celui-ci est mis dans le même cgroup que son processus parent, | ||
+ | * un processus peut être migré d'un cgroup à un autre cgroup. Par contre, la migration d'un processus n'a pas d' | ||
+ | |||
+ | Commencez par installer le paquet **cgroup-tools** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Pour visualiser les hiérarchies, | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | cpuset / | ||
+ | cpu,cpuacct / | ||
+ | blkio / | ||
+ | memory / | ||
+ | devices / | ||
+ | freezer / | ||
+ | net_cls, | ||
+ | perf_event / | ||
+ | hugetlb / | ||
+ | pids / | ||
+ | rdma / | ||
+ | </ | ||
+ | |||
+ | Sous Debian 11, **Systemd** organise les processus dans chaque CGroup. Par exemple tous les processus démarrés par le serveur Apache se trouveront dans le même CGroup, y compris les scripts CGI. Ceci implique que la gestion des ressources en utilisant des hiérarchies est couplé avec l' | ||
+ | |||
+ | En haut de l' | ||
+ | |||
+ | * le **system.slice** - l' | ||
+ | * le **user.slice** - l' | ||
+ | * le **machine.slice** - l' | ||
+ | |||
+ | En dessous des tranches peuvent se trouver : | ||
+ | |||
+ | * des **scopes** - des processus crées par **fork**, | ||
+ | * des **services** - des processus créés par une **Unité**. | ||
+ | |||
+ | Les slices peuvent être visualisés avec la commande suivante : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | UNIT | ||
+ | -.slice | ||
+ | system-getty.slice | ||
+ | system-lvm2\x2dpvscan.slice | ||
+ | system-modprobe.slice | ||
+ | system-systemd\x2dcryptsetup.slice loaded active active Cryptsetup Units Slice | ||
+ | system.slice | ||
+ | user-1000.slice | ||
+ | user.slice | ||
+ | |||
+ | LOAD = Reflects whether the unit definition was properly loaded. | ||
+ | ACTIVE = The high-level unit activation state, i.e. generalization of SUB. | ||
+ | SUB = The low-level unit activation state, values depend on unit type. | ||
+ | 8 loaded units listed. Pass --all to see loaded but inactive units, too. | ||
+ | To show all installed unit files use ' | ||
+ | </ | ||
+ | |||
+ | L' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | Control group /: | ||
+ | -.slice | ||
+ | ├─user.slice | ||
+ | │ └─user-1000.slice | ||
+ | │ | ||
+ | │ │ ├─app.slice | ||
+ | │ │ │ ├─pulseaudio.service | ||
+ | │ │ │ │ └─974 / | ||
+ | │ │ │ ├─pipewire.service | ||
+ | │ │ │ │ ├─973 / | ||
+ | │ │ │ │ └─984 / | ||
+ | │ │ │ └─dbus.service | ||
+ | │ │ │ | ||
+ | │ │ └─init.scope | ||
+ | │ | ||
+ | │ | ||
+ | │ | ||
+ | │ │ ├─ 993 sshd: trainee [priv] | ||
+ | │ │ ├─ 999 sshd: trainee@pts/ | ||
+ | │ │ ├─1000 -bash | ||
+ | │ │ ├─1003 su - | ||
+ | │ │ ├─1004 -bash | ||
+ | │ │ ├─1010 systemd-cgls | ||
+ | │ │ └─1011 less | ||
+ | │ | ||
+ | │ | ||
+ | │ | ||
+ | │ | ||
+ | │ | ||
+ | ├─init.scope | ||
+ | │ └─1 /sbin/init | ||
+ | └─system.slice | ||
+ | ├─apache2.service | ||
+ | │ ├─595 / | ||
+ | │ ├─597 / | ||
+ | │ └─598 / | ||
+ | ├─systemd-udevd.service | ||
+ | │ └─317 / | ||
+ | ├─cron.service | ||
+ | │ └─491 / | ||
+ | ├─polkit.service | ||
+ | │ └─495 / | ||
+ | ├─rtkit-daemon.service | ||
+ | │ └─979 / | ||
+ | ├─auditd.service | ||
+ | │ └─460 / | ||
+ | ├─wpa_supplicant.service | ||
+ | │ └─498 / | ||
+ | ├─ModemManager.service | ||
+ | │ └─515 / | ||
+ | ├─inetd.service | ||
+ | │ └─694 / | ||
+ | ├─systemd-journald.service | ||
+ | │ └─296 / | ||
+ | ├─mdmonitor.service | ||
+ | │ └─432 /sbin/mdadm --monitor --scan | ||
+ | ├─ssh.service | ||
+ | │ └─580 sshd: / | ||
+ | lines 1-58 | ||
+ | [q] | ||
+ | </ | ||
+ | |||
+ | En utilisant Systemd, plusieurs ressources peuvent être limitées : | ||
+ | |||
+ | * **CPUShares** - par défault 1024, | ||
+ | * **MemoryLimit** - limite exprimée en Mo ou en Go. Pas de valeur par défaut, | ||
+ | * **BlockIOWeight** - valeur entre 10 et 1000. Pas de valeur par défaut, | ||
+ | * **StartupCPUShares** - comme CPUShares mais uniquement appliqué pendant le démarrage, | ||
+ | * **StartupBlockIOWeight** - comme BlockIOWeight mais uniquement appliqué pendant le démarrage, | ||
+ | * **CPUQuota** - utilisé pour limiter le temps CPU, même quand le système ne fait rien. | ||
+ | |||
+ | === 1.3 - Limitation de la Mémoire=== | ||
+ | |||
+ | Commencez par créer le script **hello-world.sh** qui servira à générer un processus pour travailler avec les CGroups : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | #!/bin/bash | ||
+ | while [ 1 ]; do | ||
+ | echo "hello world" | ||
+ | sleep 360 | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | Rendez le script exécutable et testez-le : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | hello world | ||
+ | ^C | ||
+ | </ | ||
+ | |||
+ | Créez maintenant un CGroup dans le sous-système **memory** appelé **helloworld** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Par défaut, ce CGroup héritera de l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | 39997440 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Notez que les 40 000 000 demandés sont devenus 39 997 440 ce qui correspond à un nombre entier de pages mémoire du noyau de 4Ko. ( 39 997 440 / 4096 = 9 765 ). | ||
+ | </ | ||
+ | |||
+ | Lancez maintenant le script **helloworld.sh** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | [1] 1073 | ||
+ | root@debian11: | ||
+ | [Entrée] | ||
+ | |||
+ | root@debian11: | ||
+ | root 1073 0.0 0.0 | ||
+ | root 1077 0.0 0.0 | ||
+ | </ | ||
+ | |||
+ | Notez qu'il n'y a pas de limite de la mémoire, ce qui implique l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | CGROUP | ||
+ | 8: | ||
+ | </ | ||
+ | |||
+ | Insérer le PID de notre script dans le CGroup **helloworld** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Notez maintenant l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | CGROUP | ||
+ | 8: | ||
+ | </ | ||
+ | |||
+ | Constatez ensuite l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | 274432 | ||
+ | </ | ||
+ | |||
+ | Tuez le script **hello-world.sh** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | root 1086 0.0 0.0 | ||
+ | [1]+ Terminated | ||
+ | </ | ||
+ | |||
+ | Créez un second CGroup beaucoup plus restrictif : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | 4096 | ||
+ | </ | ||
+ | |||
+ | Relancez le script **hello-world.sh** et insérez-le dans le nouveau CGroup : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | [1] 1089 | ||
+ | |||
+ | root@debian11: | ||
+ | [Entrée] | ||
+ | |||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Attendez la prochaine sortie de **hello world** sur le canal standard puis constatez que le script s' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root 1100 0.0 0.0 | ||
+ | [1]+ Killed | ||
+ | </ | ||
+ | |||
+ | Notez la trace dans le fichier **/ | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012423] workingset_nodereclaim 0 | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012423] pgfault 0 | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012423] pgmajfault 0 | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012423] pgrefill 0 | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012423] pgscan 0 | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012423] pgsteal 0 | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012425] Tasks state (memory values in pages): | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012426] [ pid ] | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012428] [ | ||
+ | May 4 06:44:43 debian11 kernel: [ 994.012430] oom-kill: | ||
+ | </ | ||
+ | |||
+ | ===1.4 - La Commande cgcreate=== | ||
+ | |||
+ | Cette commande permet la création d'un CGroup : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | total 0 | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 cgroup.clone_children | ||
+ | --w--w--w- 1 root root 0 May 4 06:47 cgroup.event_control | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 cgroup.procs | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.failcnt | ||
+ | --w------- 1 root root 0 May 4 06:47 memory.force_empty | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.kmem.failcnt | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.kmem.limit_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.kmem.max_usage_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:47 memory.kmem.slabinfo | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.kmem.tcp.failcnt | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.kmem.tcp.limit_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.kmem.tcp.max_usage_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:47 memory.kmem.tcp.usage_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:47 memory.kmem.usage_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.limit_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.max_usage_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.memsw.failcnt | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.memsw.limit_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.memsw.max_usage_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:47 memory.memsw.usage_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.move_charge_at_immigrate | ||
+ | -r--r--r-- 1 root root 0 May 4 06:47 memory.numa_stat | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.oom_control | ||
+ | ---------- 1 root root 0 May 4 06:47 memory.pressure_level | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.soft_limit_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:47 memory.stat | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.swappiness | ||
+ | -r--r--r-- 1 root root 0 May 4 06:47 memory.usage_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 memory.use_hierarchy | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 notify_on_release | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:47 tasks | ||
+ | </ | ||
+ | |||
+ | Il n' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | ===1.5 - La Commande cgexec=== | ||
+ | |||
+ | Cette commande permet d' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | [1] 1106 | ||
+ | |||
+ | root@debian11: | ||
+ | [Entrée] | ||
+ | |||
+ | root@debian11: | ||
+ | 1106 | ||
+ | 1107 | ||
+ | root@debian11: | ||
+ | root 1106 0.0 0.0 | ||
+ | root 1107 0.0 0.0 | ||
+ | root 1108 0.0 0.0 0 0 ? I 06:49 0:00 [kworker/ | ||
+ | root 1113 0.0 0.0 | ||
+ | </ | ||
+ | |||
+ | ===1.6 - La Commande cgdelete== | ||
+ | |||
+ | Une fois le script terminé, cette commande permet de supprimer le cgroup : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | root 1107 0.0 0.0 | ||
+ | root 1108 0.0 0.0 0 0 ? I 06:49 0:00 [kworker/ | ||
+ | root 1115 0.0 0.0 | ||
+ | [1]+ Terminated | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | ls: cannot access '/ | ||
+ | </ | ||
+ | |||
+ | ===1.7 - Le Fichier / | ||
+ | |||
+ | Afin de les rendre persistants, | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | group helloworld2 { | ||
+ | cpu { | ||
+ | cpu.shares = 100; | ||
+ | } | ||
+ | memory { | ||
+ | memory.limit_in_bytes = 40000; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Notez la création de **deux** limitations, | ||
+ | </ | ||
+ | |||
+ | Créez donc les deux CGroups concernés : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | total 0 | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 cgroup.clone_children | ||
+ | --w--w--w- 1 root root 0 May 4 06:53 cgroup.event_control | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 cgroup.procs | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.failcnt | ||
+ | --w------- 1 root root 0 May 4 06:53 memory.force_empty | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.kmem.failcnt | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.kmem.limit_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.kmem.max_usage_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:53 memory.kmem.slabinfo | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.kmem.tcp.failcnt | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.kmem.tcp.limit_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.kmem.tcp.max_usage_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:53 memory.kmem.tcp.usage_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:53 memory.kmem.usage_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.limit_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.max_usage_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.memsw.failcnt | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.memsw.limit_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.memsw.max_usage_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:53 memory.memsw.usage_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.move_charge_at_immigrate | ||
+ | -r--r--r-- 1 root root 0 May 4 06:53 memory.numa_stat | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.oom_control | ||
+ | ---------- 1 root root 0 May 4 06:53 memory.pressure_level | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.soft_limit_in_bytes | ||
+ | -r--r--r-- 1 root root 0 May 4 06:53 memory.stat | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.swappiness | ||
+ | -r--r--r-- 1 root root 0 May 4 06:53 memory.usage_in_bytes | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 memory.use_hierarchy | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 notify_on_release | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:53 tasks | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | total 0 | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:54 cgroup.clone_children | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:54 cgroup.procs | ||
+ | -r--r--r-- 1 root root 0 May 4 06:54 cpuacct.stat | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:54 cpuacct.usage | ||
+ | -r--r--r-- 1 root root 0 May 4 06:54 cpuacct.usage_all | ||
+ | -r--r--r-- 1 root root 0 May 4 06:54 cpuacct.usage_percpu | ||
+ | -r--r--r-- 1 root root 0 May 4 06:54 cpuacct.usage_percpu_sys | ||
+ | -r--r--r-- 1 root root 0 May 4 06:54 cpuacct.usage_percpu_user | ||
+ | -r--r--r-- 1 root root 0 May 4 06:54 cpuacct.usage_sys | ||
+ | -r--r--r-- 1 root root 0 May 4 06:54 cpuacct.usage_user | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:54 cpu.cfs_period_us | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:54 cpu.cfs_quota_us | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:54 cpu.shares | ||
+ | -r--r--r-- 1 root root 0 May 4 06:54 cpu.stat | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:54 notify_on_release | ||
+ | -rw-r--r-- 1 root root 0 May 4 06:54 tasks | ||
+ | </ | ||
+ | |||
+ | ===1.8 - La Commande cgconfigparser=== | ||
+ | |||
+ | Appliquez le contenu du fichier **/ | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | 36864 | ||
+ | |||
+ | root@debian11: | ||
+ | 100 | ||
+ | </ | ||
+ | |||
+ | ====LAB #2 - cgroups v2==== | ||
+ | |||
+ | ===2.1 - Préparation=== | ||
+ | |||
+ | Pour revenir à l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | # If you change this file, run ' | ||
+ | # / | ||
+ | # For full documentation of the options in this file, see: | ||
+ | # info -f grub -n ' | ||
+ | |||
+ | GRUB_DEFAULT=0 | ||
+ | GRUB_TIMEOUT=5 | ||
+ | GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` | ||
+ | GRUB_CMDLINE_LINUX_DEFAULT=" | ||
+ | GRUB_CMDLINE_LINUX="" | ||
+ | |||
+ | # Uncomment to enable BadRAM filtering, modify to suit your needs | ||
+ | # This works with Linux (no patch required) and with any kernel that obtains | ||
+ | # the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...) | ||
+ | # | ||
+ | |||
+ | # Uncomment to disable graphical terminal (grub-pc only) | ||
+ | # | ||
+ | |||
+ | # The resolution used on graphical terminal | ||
+ | # note that you can use only modes which your graphic card supports via VBE | ||
+ | # you can see them in real GRUB with the command `vbeinfo' | ||
+ | # | ||
+ | |||
+ | # Uncomment if you don't want GRUB to pass " | ||
+ | # | ||
+ | |||
+ | # Uncomment to disable generation of recovery mode menu entries | ||
+ | # | ||
+ | |||
+ | # Uncomment to get a beep at grub start | ||
+ | # | ||
+ | |||
+ | root@debian11: | ||
+ | Generating grub configuration file ... | ||
+ | Found background image: / | ||
+ | Found linux image: / | ||
+ | Found initrd image: / | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | Redémarrez ensuite votre VM : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | ===2.2 - Présentation=== | ||
+ | |||
+ | A l' | ||
+ | |||
+ | Pour vérifier l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | cgroup2 on / | ||
+ | </ | ||
+ | |||
+ | et de consulter le contenu de ce point de montage : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | total 0 | ||
+ | -r--r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -r--r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -r--r--r-- | ||
+ | -r--r--r-- | ||
+ | -r--r--r-- | ||
+ | drwxr-xr-x | ||
+ | drwxr-xr-x | ||
+ | drwxr-xr-x | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -r--r--r-- | ||
+ | -r--r--r-- | ||
+ | -rw-r--r-- | ||
+ | -r--r--r-- | ||
+ | drwxr-xr-x | ||
+ | drwxr-xr-x | ||
+ | drwxr-xr-x | ||
+ | drwxr-xr-x | ||
+ | drwxr-xr-x 23 root root 0 Jul 6 11:26 system.slice | ||
+ | drwxr-xr-x | ||
+ | </ | ||
+ | |||
+ | Dans la version 2 de cgroup, certains noms ont changé par rapport à ceux utilisés dans la version 1 : | ||
+ | |||
+ | ^ Version 1 ^ Version 2 ^ | ||
+ | | CPUShares | CPUWeight | | ||
+ | | StartupCPUShares | StartupCPUWeight | | ||
+ | | MemoryLimit | MemoryMax | | ||
+ | |||
+ | Commencez par créer le cgroup enfant **pids** dans le cgroup racine : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Placez le PID du terminal courant dans le fichier **cgroup.procs** du cgroup enfant : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | 1230 | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Contrôlez maintenant le contenu du fichier cgroup.procs ainsi que le nombre de PIDs dans le cgroup **pids** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | 1230 | ||
+ | 1281 | ||
+ | |||
+ | root@debian11: | ||
+ | 2 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Notez que le fichier cgroup.procs contient **deux** PIDs. Le premier est celui du Shell tandis que le deuxième est celui de la commande cat. | ||
+ | </ | ||
+ | |||
+ | Injectez maintenant la valeur de **5** dans le fichier **pids.max** du cgroup ** pids** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Lancez la commande suivante pour créer 6 pids dans le cgroup : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | [1] 1290 | ||
+ | [2] 1291 | ||
+ | [3] 1292 | ||
+ | [4] 1293 | ||
+ | -bash: fork: retry: Resource temporarily unavailable | ||
+ | -bash: fork: retry: Resource temporarily unavailable | ||
+ | -bash: fork: retry: Resource temporarily unavailable | ||
+ | -bash: fork: retry: Resource temporarily unavailable | ||
+ | -bash: fork: Resource temporarily unavailable | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Notez qu'à la tentative de création du 6ème processus, une erreur est retournée. Le système tente ensuite 4 fois de plus puis renonce finalement avec le message d' | ||
+ | </ | ||
+ | |||
+ | Dernièrement, | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | rmdir: failed to remove '/ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Notez qu'il n'est pas possible de supprimer un cgroup tant que celui-ci contient un processus. | ||
+ | </ | ||
+ | |||
+ | Déplacez le processus du terminal courant dans le cgroup racine : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Il est maintenant possible de supprimer le cgroup **pids** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | ===2.3 - Limitation de la CPU=== | ||
+ | |||
+ | Il existe deux façons de limiter les ressources de la CPU : | ||
+ | |||
+ | * **CPU bandwidth**, | ||
+ | * un système de limitation basé sur un pourcentage de CPU pour un ou plusieurs processus, | ||
+ | * **CPU weight**, | ||
+ | * un système de limitation basé sur la prioritisassion d'un ou de plusieurs processus par rapports aux autres processus. | ||
+ | |||
+ | Dans l' | ||
+ | |||
+ | Commencez par créer un service appelé **foo** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | [Unit] | ||
+ | Description=The foo service that does nothing useful | ||
+ | After=remote-fs.target nss-lookup.target | ||
+ | |||
+ | [Service] | ||
+ | ExecStart=/ | ||
+ | ExecStop=/ | ||
+ | |||
+ | [Install] | ||
+ | WantedBy=multi-user.target | ||
+ | </ | ||
+ | |||
+ | Démarrez et activez le service : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | Created symlink / | ||
+ | root@debian11: | ||
+ | ● foo.service - The foo service that does nothing useful | ||
+ | | ||
+ | | ||
+ | Main PID: 997 (sha1sum) | ||
+ | Tasks: 1 (limit: 19155) | ||
+ | | ||
+ | CPU: 19.114s | ||
+ | | ||
+ | | ||
+ | |||
+ | Jul 06 11:41:18 debian11 systemd[1]: Started The foo service that does nothing useful. | ||
+ | </ | ||
+ | |||
+ | Utilisez la commande **ps** pour voir le pourcentage de la CPU utilisé par ce service : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | PID COMMAND | ||
+ | 997 sha1sum | ||
+ | </ | ||
+ | |||
+ | Créez maintenant un autre service dénommé **bar** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | [Unit] | ||
+ | Description=The bar service that does nothing useful | ||
+ | After=remote-fs.target nss-lookup.target | ||
+ | |||
+ | [Service] | ||
+ | ExecStart=/ | ||
+ | ExecStop=/ | ||
+ | |||
+ | [Install] | ||
+ | WantedBy=multi-user.target | ||
+ | </ | ||
+ | |||
+ | Démarrez et activez le service : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | Created symlink / | ||
+ | |||
+ | root@debian11: | ||
+ | ● bar.service - The bar service that does nothing useful | ||
+ | | ||
+ | | ||
+ | Main PID: 1020 (md5sum) | ||
+ | Tasks: 1 (limit: 19155) | ||
+ | | ||
+ | CPU: 15.079s | ||
+ | | ||
+ | | ||
+ | |||
+ | Jul 06 11:45:24 debian11 systemd[1]: Started The bar service that does nothing useful. | ||
+ | </ | ||
+ | |||
+ | Utilisez la commande **ps** pour voir le pourcentage de la CPU utilisé par ce service : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | PID COMMAND | ||
+ | 1020 md5sum | ||
+ | </ | ||
+ | |||
+ | Vérifiez maintenant la présence des contrôleurs **cpuset** et **cpu** dans l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | cpuset cpu io memory hugetlb pids rdma | ||
+ | </ | ||
+ | |||
+ | Activez maintenant les deux contrôleurs **cpuset** et **cpu** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | memory pids | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | cpuset cpu memory pids | ||
+ | </ | ||
+ | |||
+ | Créez le cgroup **enfant** appelé **FooBar** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | total 0 | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 cgroup.controllers | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 cgroup.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cgroup.freeze | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cgroup.max.depth | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cgroup.max.descendants | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cgroup.procs | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 cgroup.stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cgroup.subtree_control | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cgroup.threads | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cgroup.type | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cpu.max | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cpu.pressure | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cpuset.cpus | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 cpuset.cpus.effective | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cpuset.cpus.partition | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cpuset.mems | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 cpuset.mems.effective | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 cpu.stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cpu.weight | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 cpu.weight.nice | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 io.pressure | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 memory.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 memory.events | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 memory.events.local | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 memory.high | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 memory.low | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 memory.max | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 memory.min | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 memory.numa_stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 memory.oom.group | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 memory.pressure | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 memory.stat | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 memory.swap.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 memory.swap.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 memory.swap.high | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 memory.swap.max | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 pids.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:18 pids.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:18 pids.max | ||
+ | </ | ||
+ | |||
+ | Activez les contrôleurs **cpuset** et **cpu** pour le cgroup **FooBar** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | cpuset cpu memory pids | ||
+ | cpuset cpu | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Notez qu'il n'est pas possible d' | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le répertoire **/ | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | total 0 | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:20 cgroup.controllers | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:20 cgroup.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cgroup.freeze | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cgroup.max.depth | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cgroup.max.descendants | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cgroup.procs | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:20 cgroup.stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cgroup.subtree_control | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cgroup.threads | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cgroup.type | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cpu.max | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cpu.pressure | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cpuset.cpus | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:20 cpuset.cpus.effective | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cpuset.cpus.partition | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cpuset.mems | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:20 cpuset.mems.effective | ||
+ | -r--r--r-- 1 root root 0 Jul 6 12:20 cpu.stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cpu.weight | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 cpu.weight.nice | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 io.pressure | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 12:20 memory.pressure | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Le répertoire **/ | ||
+ | </ | ||
+ | |||
+ | De façon à ce que les deux processus issus des services **foo** et **bar** se font concurrence sur la même CPU, injectez la valeur de **1** dans le fichier **/ | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | 1 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Notez que dans les faits, le contrôleur **cpu** n'est activé **que** dans le cas où le cgroup contient au moins 2 processus qui se font concurrence sur la même CPU. | ||
+ | </ | ||
+ | |||
+ | Mettez en place une limitation des ressources de la CPU avec la commande suivante : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Dans la commande ci-dessus, le premier nombre est un quota en microsecondes pendant lequel les processus dans le cgroup peuvent s' | ||
+ | </ | ||
+ | |||
+ | Ajoutez maintenant les processus des services **foo** et **bar** au cgroup **FooBar** : | ||
+ | |||
+ | < | ||
+ | echo " | ||
+ | |||
+ | echo " | ||
+ | </ | ||
+ | |||
+ | Vérifiez la prise en compte par le système de la commande précédente : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | 0::/ | ||
+ | 0::/ | ||
+ | </ | ||
+ | |||
+ | Dernièrement, | ||
+ | |||
+ | < | ||
+ | top - 12:36:33 up 1:37, 2 users, | ||
+ | Tasks: 154 total, | ||
+ | %Cpu(s): | ||
+ | MiB Mem : 16007.9 total, | ||
+ | MiB Swap: 975.0 total, | ||
+ | |||
+ | PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND | ||
+ | 997 root 20 | ||
+ | 1020 root 20 | ||
+ | </ | ||
+ | |||
+ | ===2.4 - La Commande systemctl set-property=== | ||
+ | |||
+ | Comme déjà vu, systemd organise les processus dans des **slices**, par exemple les utilisateurs sont regroupés dans **/ | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | total 0 | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 cgroup.controllers | ||
+ | -r--r--r-- 1 root root 0 Jul 6 10:58 cgroup.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cgroup.freeze | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cgroup.max.depth | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cgroup.max.descendants | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cgroup.procs | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 cgroup.stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 15:05 cgroup.subtree_control | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cgroup.threads | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cgroup.type | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cpu.max | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cpu.pressure | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cpuset.cpus | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 cpuset.cpus.effective | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cpuset.cpus.partition | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cpuset.mems | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 cpuset.mems.effective | ||
+ | -r--r--r-- 1 root root 0 Jul 6 10:58 cpu.stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cpu.weight | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 cpu.weight.nice | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 io.pressure | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 memory.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 memory.events | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 memory.events.local | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 10:58 memory.high | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 10:58 memory.low | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 10:58 memory.max | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 10:58 memory.min | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 memory.numa_stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 10:58 memory.oom.group | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 memory.pressure | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 memory.stat | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 memory.swap.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 memory.swap.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:13 memory.swap.high | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 10:58 memory.swap.max | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 pids.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:13 pids.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 10:58 pids.max | ||
+ | drwxr-xr-x 8 root root 0 Jul 6 15:22 user-1000.slice | ||
+ | drwxr-xr-x 5 root root 0 Jul 6 11:41 user-113.slice | ||
+ | </ | ||
+ | |||
+ | et les processus d'un utilisateur spécifique dans un slice dénommé **user-UID.slice** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | total 0 | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 cgroup.controllers | ||
+ | -r--r--r-- 1 root root 0 Jul 6 11:30 cgroup.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 cgroup.freeze | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 cgroup.max.depth | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 cgroup.max.descendants | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 cgroup.procs | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 cgroup.stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 15:05 cgroup.subtree_control | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 cgroup.threads | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 cgroup.type | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 cpu.pressure | ||
+ | -r--r--r-- 1 root root 0 Jul 6 11:30 cpu.stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 io.pressure | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 memory.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 memory.events | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 memory.events.local | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 11:30 memory.high | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 11:30 memory.low | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 11:30 memory.max | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 11:30 memory.min | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 memory.numa_stat | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 11:30 memory.oom.group | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 memory.pressure | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 memory.stat | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 memory.swap.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 memory.swap.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 16:14 memory.swap.high | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 11:30 memory.swap.max | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 pids.current | ||
+ | -r--r--r-- 1 root root 0 Jul 6 16:14 pids.events | ||
+ | -rw-r--r-- 1 root root 0 Jul 6 11:30 pids.max | ||
+ | drwxr-xr-x 2 root root 0 Jul 6 14:56 session-13.scope | ||
+ | drwxr-xr-x 2 root root 0 Jul 6 15:22 session-15.scope | ||
+ | drwxr-xr-x 2 root root 0 Jul 6 11:30 session-4.scope | ||
+ | drwxr-xr-x 2 root root 0 Jul 6 12:12 session-6.scope | ||
+ | drwxr-xr-x 4 trainee trainee 0 Jul 6 11:30 user@1000.service | ||
+ | drwxr-xr-x 2 root root 0 Jul 6 11:41 user-runtime-dir@1000.service | ||
+ | </ | ||
+ | |||
+ | De ce fait, il est possible d' | ||
+ | |||
+ | ==CPU== | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | 40000 100000 | ||
+ | </ | ||
+ | |||
+ | ==Mémoire== | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | root@debian11: | ||
+ | 1073741824 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50% > | ||
+ | **Important** - Notez que l' | ||
+ | </ | ||
+ | |||
+ | =====Présentation de Linux Containers===== | ||
+ | |||
+ | ====LAB #3 - Travailler avec LXC==== | ||
+ | |||
+ | ===3.1 - Installation=== | ||
+ | |||
+ | Les outils indispensables à l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | Reading package lists... Done | ||
+ | Building dependency tree... Done | ||
+ | Reading state information... Done | ||
+ | The following packages were automatically installed and are no longer required: | ||
+ | libopengl0 linux-headers-5.10.0-15-amd64 linux-headers-5.10.0-15-common | ||
+ | Use 'apt autoremove' | ||
+ | The following additional packages will be installed: | ||
+ | arch-test bridge-utils busybox-static cloud-image-utils debootstrap distro-info | ||
+ | fakechroot genisoimage libaio1 libdistro-info-perl libfakechroot liblxc1 | ||
+ | libpam-cgfs lxc-templates lxcfs mmdebstrap qemu-utils rsync uidmap uuid-runtime | ||
+ | Suggested packages: | ||
+ | ubuntu-archive-keyring squid-deb-proxy-client shunit2 wodim cdrkit-doc btrfs-progs | ||
+ | lvm2 python3-lxc qemu-user-static apt-transport-tor binfmt-support perl-doc proot | ||
+ | qemu-user squashfs-tools-ng qemu-block-extra | ||
+ | The following packages will be REMOVED: | ||
+ | busybox | ||
+ | The following NEW packages will be installed: | ||
+ | arch-test bridge-utils busybox-static cloud-image-utils debootstrap distro-info | ||
+ | fakechroot genisoimage libaio1 libdistro-info-perl libfakechroot liblxc1 | ||
+ | libpam-cgfs lxc lxc-templates lxcfs mmdebstrap qemu-utils rsync uidmap | ||
+ | uuid-runtime | ||
+ | 0 upgraded, 21 newly installed, 1 to remove and 5 not upgraded. | ||
+ | Need to get 6,127 kB of archives. | ||
+ | After this operation, 33.2 MB of additional disk space will be used. | ||
+ | Do you want to continue? [Y/n] y | ||
+ | </ | ||
+ | |||
+ | L' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | config | ||
+ | |||
+ | root@debian11: | ||
+ | alpine.common.conf | ||
+ | alpine.userns.conf | ||
+ | archlinux.common.conf | ||
+ | archlinux.userns.conf | ||
+ | centos.common.conf | ||
+ | centos.userns.conf | ||
+ | common.conf | ||
+ | common.conf.d | ||
+ | common.seccomp | ||
+ | debian.common.conf | ||
+ | debian.userns.conf | ||
+ | fedora.common.conf | ||
+ | fedora.userns.conf | ||
+ | gentoo.common.conf | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-alpine | ||
+ | lxc-altlinux | ||
+ | lxc-archlinux | ||
+ | lxc-busybox | ||
+ | lxc-centos | ||
+ | </ | ||
+ | |||
+ | ===3.2 - Création d'un Conteneur Simple=== | ||
+ | |||
+ | Créez un conteneur simple en utilisant la commande suivante : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50%> | ||
+ | **Important** - Notez l' | ||
+ | </ | ||
+ | |||
+ | Le **backingstore** (// méthode de stockage//) utilisé par défaut est **dir** ce qui implique que le **rootfs** du conteneur se trouve sur disque dans le répertoire **/ | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | lxc-bb | ||
+ | |||
+ | root@debian11: | ||
+ | config | ||
+ | |||
+ | root@debian11: | ||
+ | bin dev etc home lib lib64 mnt proc root sbin selinux | ||
+ | </ | ||
+ | |||
+ | Il est à noter que LXC peut également utiliser des backingstores de type : | ||
+ | |||
+ | * ZFS | ||
+ | * Brtfs | ||
+ | * LVM | ||
+ | * Loop | ||
+ | * rbd (CephFS) | ||
+ | |||
+ | ===3.3 - Démarrage d'un Conteneur Simple=== | ||
+ | |||
+ | Pour démarrer le conteneur, il convient d' | ||
+ | |||
+ | < | ||
+ | root@debian9: | ||
+ | </ | ||
+ | |||
+ | ===3.4 - S' | ||
+ | |||
+ | Pour s' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-attach: lxc-bb: terminal.c: lxc_terminal_create_native: | ||
+ | |||
+ | |||
+ | BusyBox v1.30.1 (Debian 1: | ||
+ | Enter ' | ||
+ | |||
+ | ~ # which passwd | ||
+ | /bin/passwd | ||
+ | ~ # | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 50%> | ||
+ | **Important** - Notez l' | ||
+ | </ | ||
+ | |||
+ | Pour sortir du conteneur, il convient d' | ||
+ | |||
+ | < | ||
+ | ~ # [Ctrl+d] | ||
+ | ~ # root@debian11: | ||
+ | </ | ||
+ | |||
+ | Le fait de sortir du conteneur ne l' | ||
+ | |||
+ | < | ||
+ | ~ # root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-bb | ||
+ | |||
+ | root@debian11: | ||
+ | NAME | ||
+ | lxc-bb RUNNING 0 | ||
+ | </ | ||
+ | |||
+ | ===3.5 - Commandes LXC de Base=== | ||
+ | |||
+ | ==La Commande lxc-console== | ||
+ | |||
+ | Pour lancer une console attachée à un TTY dans le conteneur, il convient d' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | Connected to tty 1 | ||
+ | Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself | ||
+ | |||
+ | lxc-bb login: | ||
+ | </ | ||
+ | |||
+ | Pour sortir de la console, il faut utiliser la combinaison de touches **< | ||
+ | |||
+ | < | ||
+ | lxc-bb login: [Ctrl+a] [q] root@debian11: | ||
+ | </ | ||
+ | |||
+ | ==La Commande lxc-stop== | ||
+ | |||
+ | Pour arrêter le conteneur, utilisez la commande **lxc-stop** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | lxc-bb | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | ==La Commande lxc-execute== | ||
+ | |||
+ | La commande **lxc-execute** démarre un conteneur (qui doit être créé mais arrêté), exécute la commande passée en argument grâce aux caractères **--** puis arrête le conteneur : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | Linux lxc-bb 5.10.0-24-amd64 #1 SMP Debian 5.10.179-5 (2023-08-08) x86_64 GNU/Linux | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | ==La Commande lxc-info== | ||
+ | |||
+ | Cette commande donne des informations sur un conteneur : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | Name: | ||
+ | State: | ||
+ | </ | ||
+ | |||
+ | ==La Commande lxc-freeze== | ||
+ | |||
+ | La commande **lxc-freeze** met en pause tous les processus du conteneur : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-bb | ||
+ | |||
+ | root@debian11: | ||
+ | Name: | ||
+ | State: | ||
+ | PID: 28581 | ||
+ | IP: | ||
+ | Link: | ||
+ | TX bytes: | ||
+ | RX bytes: | ||
+ | Total bytes: | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | Name: | ||
+ | State: | ||
+ | PID: 28581 | ||
+ | IP: | ||
+ | Link: | ||
+ | TX bytes: | ||
+ | RX bytes: | ||
+ | Total bytes: | ||
+ | |||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | ==La Commande lxc-unfreeze== | ||
+ | |||
+ | La commande **lxc-unfreeze** annule l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | Name: | ||
+ | State: | ||
+ | PID: 28581 | ||
+ | IP: | ||
+ | Link: | ||
+ | TX bytes: | ||
+ | RX bytes: | ||
+ | Total bytes: | ||
+ | </ | ||
+ | |||
+ | ==Autres Commandes== | ||
+ | |||
+ | Les autres commandes dont il faut avoir une connaissance sont : | ||
+ | |||
+ | ^ Commande ^ Description ^ | ||
+ | | lxc-destroy | Permet de détruire complètement un conteneur | | ||
+ | | lxc-autostart | Permet de rebooter, tuer ou arrêter les conteneurs dont le drapeau **lxc.start.auto** est fixé dans le fichier **/ | ||
+ | | lxc-cgroup | Permet de manipuler à chaud les CGroups pour un conteneur donné | | ||
+ | | lxc-device | Permet de rajouter à chaud les devices à un conteneur | | ||
+ | | lxc-usernsexec | Permet d' | ||
+ | | lxc-wait | Permet d' | ||
+ | |||
+ | ===3.6 - Création d'un Conteneur Éphémère=== | ||
+ | |||
+ | Par défaut les conteneurs LXC sont permanents. Il est possible de créer un conteneur éphémère, | ||
+ | |||
+ | ==La Commande lxc-copy== | ||
+ | |||
+ | Notez que le conteneur d' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | NAME | ||
+ | lxc-bb RUNNING 0 | ||
+ | | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Arrêtez donc le conteneur **lxc-bb** puis créez la copie : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | Created lxc-bb-eph as clone of lxc-bb | ||
+ | |||
+ | root@debian11: | ||
+ | NAME | ||
+ | lxc-bb-eph RUNNING 0 | ||
+ | </ | ||
+ | |||
+ | Attachez-vous au conteneur **lxc-bb-eph** : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | NAME | ||
+ | lxc-bb-eph RUNNING 0 | ||
+ | root@debian11: | ||
+ | lxc-attach: lxc-bb-eph: terminal.c: lxc_terminal_create_native: | ||
+ | |||
+ | |||
+ | BusyBox v1.30.1 (Debian 1: | ||
+ | Enter ' | ||
+ | |||
+ | ~ # | ||
+ | </ | ||
+ | |||
+ | Créez un fichier de contrôle appelé **testdata** : | ||
+ | |||
+ | < | ||
+ | ~ # ls -l | ||
+ | total 0 | ||
+ | |||
+ | ~ # pwd | ||
+ | /root | ||
+ | |||
+ | ~ # echo " | ||
+ | |||
+ | ~ # ls -l | ||
+ | total 4 | ||
+ | -rw-r--r-- | ||
+ | |||
+ | ~ # | ||
+ | </ | ||
+ | |||
+ | Déconnectez-vous du conteneur puis attachez-vous de nouveau : | ||
+ | |||
+ | < | ||
+ | ~ # exit | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-attach: lxc-bb-eph: terminal.c: lxc_terminal_create_native: | ||
+ | |||
+ | |||
+ | BusyBox v1.30.1 (Debian 1: | ||
+ | Enter ' | ||
+ | |||
+ | ~ # ls -l | ||
+ | total 4 | ||
+ | -rw-r--r-- | ||
+ | |||
+ | ~ # | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important> | ||
+ | **Important** - Notez que le fichier **testdata** est toujours présent. | ||
+ | </ | ||
+ | |||
+ | Déconnectez-vous de nouveau et arrêtez le conteneur : | ||
+ | |||
+ | < | ||
+ | ~ # exit | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-bb | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-start: lxc-bb-eph: tools/ | ||
+ | |||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important> | ||
+ | **Important** - Notez que le conteneur **lxc-bb-eph** a été détruit. | ||
+ | </ | ||
+ | |||
+ | ===3.7 - Sauvegarde des Conteneurs=== | ||
+ | |||
+ | Un conteneur LXC peut être sauvegardé de trois façons différentes : | ||
+ | |||
+ | * utiliser la commande **tar** ou **cpio** pour créer un archive du répertoire **rootfs** et du fichier **config** associés au conteneur | ||
+ | * utiliser la commande **lxc-copy** sans l' | ||
+ | * utiliser la commande **lxc-snapshot** | ||
+ | |||
+ | ==La Commande lxc-snapshot== | ||
+ | |||
+ | Cette commande permet de gérer des instantanées des conteneurs. A noter que les conteneurs doivent être arrêtés avant de prendre une instantanée : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | </ | ||
+ | |||
+ | Les snapshots sont stockés dans le sous-répertoire **snaps** du répertoire **/ | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | total 12 | ||
+ | -rw-r----- | ||
+ | drwxr-xr-x 17 root root 4096 Aug 20 10:38 rootfs | ||
+ | drwxr-xr-x | ||
+ | |||
+ | root@debian11: | ||
+ | total 4 | ||
+ | drwxrwx--- 3 root root 4096 Aug 20 12:35 snap0 | ||
+ | |||
+ | root@debian11: | ||
+ | total 12 | ||
+ | -rw-r----- | ||
+ | drwxr-xr-x 17 root root 4096 Aug 20 10:38 rootfs | ||
+ | -rw-r--r-- | ||
+ | </ | ||
+ | |||
+ | L' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | 2023:08:20 12: | ||
+ | </ | ||
+ | |||
+ | En comparant la taille du **rootfs** du conteneur d' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | 2.1M / | ||
+ | |||
+ | root@debian11: | ||
+ | 2.1M / | ||
+ | </ | ||
+ | |||
+ | Pour restaurer un conteneur identique à l' | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-bb | ||
+ | |||
+ | root@debian11: | ||
+ | |||
+ | root@debian11: | ||
+ | lxc-attach: lxc-bb-snap0: | ||
+ | |||
+ | |||
+ | BusyBox v1.30.1 (Debian 1: | ||
+ | Enter ' | ||
+ | |||
+ | ~ # exit | ||
+ | |||
+ | root@debian11: | ||
+ | </ | ||
+ | ----- | ||
+ | |||
+ | Copyright © 2023 Hugh Norris. |