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. | ||