virli/slides/slides.md
2015-09-26 11:51:10 +02:00

8.1 KiB

% Virtualisation légère % Pierre-Olivier Mercier % Samedi 29 novembre 2014

Table des matières

Virtualisation légère

  1. Rappels & historique
  2. GNU/Linux, implementations
  3. 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 de l'hôte ;
  • 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 fichiers ;
  • 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ée ;
  • 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é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.
[Service]
CPUShares=1500
MemoryLimit=1G
BlockIOWeight=500

LXC

  • Lance un système complet à partir de /sbin/init ;
  • se configure via un fichier de configuration :
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.

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.