8.1 KiB
% Virtualisation légère % Pierre-Olivier Mercier % Samedi 29 novembre 2014
Table des matières
Virtualisation légère
- Rappels & historique
- GNU/Linux, implementations
- Cas en production
Rappels & historique
Rappels sur la virtualisation classique
Prémices
Au départ
Exécuter simultanément plusieurs environnements distinct sur un mainframe IBM.
IBM System/370
- Virtualisation grâce au système CP/CMS ;
- permis par la présence d'une MMU et par l'ajout d'un mode supervisor au processeur.
Vocabulaire
- Machine hôte/host machine
- Machine invité/guest machine
Virtualisation vs. émulation
- Émulation : simulation logiciel de matériel (potentiellement une architecture différente) : pas d'accès direct au matériel ;
- Virtualisation : accès direct, mais restrint, au matériel.
Technologies de virtualisation matérielle
- Intel VT-x/AMD-V/ARM Virtualization Extensions
- partitionne le processeur pour exécuter plusieurs système d'exploitation via le même processeur.
Comment virtualiser ?
- Full virtualisation : hyperviseurs ;
- Paravirtualisation ;
- Isolateurs/conteneurs ;
- Conteneurs applicatifs.
Hyperviseurs
Hyperviseurs
Contrôlent l'utilisation faite des ressources de la machine hôte par les machines virtuelles.
Type 1
-
L'hyperviseur contrôle directement le matériel ;
-
Tous les systèmes lancés par la suite passent par l'hyperviseur.
-
Microsoft Hyper-V, XenServer, VMware ESX, ...
Type 2
-
L'hyperviseur s'appuie sur le système d'exploitation déjà lancé pour accéder au matériel ;
-
Linux KVM, VirtualBox, BHyVe, ...
Paravirtualisation
Caractéristiques
- Nécessite un noyau patché ;
- l'hôte expose une API accessible aux invités ;
- les invités accèdent au matériel via l'API de l'hôte.
Exemple
- Xen
Virtualisation légère
Conteneur
Conteneur
Caractéristiques
- Isolation faite par le noyau du système d'exploitation ;
- le noyau est partagé entre tous les invités ;
- les périphériques sont déjà en place (pas besoin d'en émuler) ;
- l'invité démarre à partir de
/sbin/init
.
Conteneurs applicatifs
Conteneurs applicatifs
Caractéristiques
- Noyau est partagé avec l'hôte ;
- on utilise tout en place : fs, sockets, périphériques ;
- lance directement une application, pas
init
.
Versus chroot
- Simple isolation d'une partie du système de fichier ;
- pas de limitation sur les ressources utilisés ;
- pas d'isolation de l'arbre des processus ;
- implémentations douteuses (GrSecurity !).
Différentes implémentations
Points communs
Environnement virtualisé
- Arborescence de fichiers séparé ;
- arbre de processus isolé ;
- comptes utilisateurs distincts ;
- pile réseau et nom de machine propre.
Diversité
Unix
- FreeBSD : Jails lancées en 1998 ;
- Solaris : Zones lancées en 2005 ;
GNU/Linux
- OpenVZ : 2005, nécessite de patcher son kernel ;
- Linux Containers (LXC) : 2008, basé sur les namespaces et les cgroups ;
- Docker : 2013, en pleine croissance !
Et Windows ?
Isolation
- Parallels Virtuozzo Containers ;
- Sandboxie.
Dérivés
- Boot2Docker : Docker dans une VM.
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
#include <sched.h>
#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éseauCAP_SYS_MODULE
: charge et décharge des modules noyauCAP_SYS_RAWIO
: accès brut aux entrées/sortiesCAP_SYS_RESOURCE
: dépassement des quotas, utilisation de l'espace réservé, ...CAP_SYS_TIME
: changer l'heure de la machineCAP_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.
[Service]
CPUShares=1500
MemoryLimit=1G
BlockIOWeight=500
LXC
- Lance un système complet à partir de
/sbin/init
; - se configure via un fichier de conf :
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é dans un 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.
En production
LXC API
import lxc
import sys
# Setup the container object
c = lxc.Container("apicontainer")
# Create the container rootfs
c.create("download", lxc.LXC_CREATE_QUIET,
{"dist": "ubuntu", "release": "trusty",
"arch": "i386"})
# Start the container
if not c.start():
print("Failed to start the container")
sys.exit(1)
Projets naissants
Core OS
- Système d'exploitation minimaliste ;
- fleet : systemd administrable à distance ;
- lance des conteneur via fichiers de service Systemd.
Citadel
- Interaction avec un cluster Docker ;
- schedule l'emplacement d'exécution des conteneurs.
Shipyard
- Interface web pour gérer son cluster Docker.