# GNU/Linux ## Namespaces & cgroups ### Isolation du système #### Mount Namespace Isole la vue des partitions montées. #### UTS Namespace Identification du système : nom de machine et de domaine. #### PID Namespace Crée un arbre d'exécution parallèle où le premier process à être exécuté devient le PID 1 de cet arbre. ### Isolation du système #### Network Namespace Isole la pile réseau ; crée un nouveau groupe d'interfaces. #### User Namespace Crée une liste d'utilisateurs et de groupe distincte. #### IPC Namespace Isolation des files de messages de communication interprocessus (IPC). ### Implémentation ```c #include #define STACKSIZE (1024*1024) static char child_stack[STACKSIZE]; int clone_flags = CLONE_NEWNET | SIGCHLD; pid_t pid = clone(do_execvp, child_stack + STACKSIZE, clone_flags, &args); ``` ### cgroups `/sys/fs/cgroup/` #### Block I/O * Limitation de la bande passante lecture/écriture ; * poids d'un groupe ; * métriques: IOPS, latence, file d'attente. #### CPU * Poids d'utilisation du CPU ; * statistiques d'utilisation ### cgroups `/sys/fs/cgroup/` #### Mémoire * Limite de taille ; * métriques : total rss, swap, nb pages in/out #### Autres Réseau, périphériques, gel de processus, ... ### cgroups #### Création de cgroups ``` mkdir -p /sys/fs/cgroup/blkio/test1/ /sys/fs/cgroup/blkio/test2 ``` #### Altération d'une valeur ``` echo 1000 > /sys/fs/cgroup/blkio/test1/blkio.weight echo 500 > /sys/fs/cgroup/blkio/test2/blkio.weight ``` #### Assignation des tâches aux cgroups ``` dd if=/mnt/sdb/zerofile1 of=/dev/null & echo $! > /sys/fs/cgroup/blkio/test1/tasks dd if=/mnt/sdb/zerofile2 of=/dev/null & echo $! > /sys/fs/cgroup/blkio/test2/tasks ``` ## Capabilities ### Résumé #### Historiquement * Processus privilégiés : `UID == 0`. * Processus non-privilégiés : `UID != 0`. #### Depuis Linux 2.2 * Séparation des privilèges de l'UID 0. * Chaque thread peut posséder ses propres capacités. * `prctl(2)`, `execve(2)`, `clone(2)`, ... ### Principales capacités #### Ne pas oublier de désactiver * `CAP_MKNOD` : `mknod` * `CAP_NET_RAW` : permet d'écouter tout le réseau * `CAP_SYS_MODULE` : charge et décharge des modules noyau * `CAP_SYS_RAWIO` : accès brut aux entrées/sorties * `CAP_SYS_RESOURCE` : dépassement des quotas, utilisation de l'espace réservé, ... * `CAP_SYS_TIME` : changer l'heure de la machine * `CAP_SYS_ADMIN` : misc * ... ## Isolateurs ### `systemd` * Chaque service est démarré dans un cgroup ; * on peut appliquer des limites au groupe en modifiant le `.service` ; * `systemd-nspawn` pour créer manuellement un nouveau namespace. ```ini [Service] CPUShares=1500 MemoryLimit=1G BlockIOWeight=500 ``` ### LXC * Lance un système complet à partir de `/sbin/init` ; * se configure via un fichier de configuration : ```ini lxc.rootfs = /var/lib/lxc/toto/rootfs lxc.utsname = toto lxc.network.type = veth lxc.network.hwaddr = 00:16:3e:c6:0e:04 lxc.network.flags = up lxc.network.link = tap0 lxc.network.name = eth0 lxc.tty = 4 lxc.pts = 1024 lxc.cap.drop = mac_admin mac_override ``` ### Docker * Lance une application, packagée dans son environnement ; * création d'environnement possible à partir de `Dockerfile` : ``` FROM debian:wheezy RUN groupadd -r mysql && useradd -r -g mysql mysql RUN apt-get update && apt-get install -y perl ENV MYSQL_MAJOR 5.7 VOLUME /var/lib/mysql COPY docker-entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] EXPOSE 3306 CMD ["mysqld", "--datadir=/var/lib/mysql"] ``` ## Réseau ### Réseaux physiques #### empty Loopback uniquement, n'ajoute aucune interface. #### phys Utilisation d'une interface physique directement. #### vlan Assignation d'un VLAN à chaque conteneur. ### Réseaux virtuels #### veth On crée une interface virtuelle sur l'hôte que l'on connecte à un bridge. #### MAC VLAN * **VEPA :** tous les paquets sortants sortent, y compris ceux à destination d'une autre machine locale. Le switch derrière doit rerouter les paquets vers la machine. * **Bridge :** le noyau analyse les paquets avant de les transmettre.