Tuto 1: wip

This commit is contained in:
nemunaire 2015-10-07 03:45:39 +02:00
commit 50913a7493
8 changed files with 419 additions and 602 deletions

19
tutorial/1/Makefile Normal file
View file

@ -0,0 +1,19 @@
SOURCES = tutorial.md installation.md lxc.md cgroups.md namespaces.md
TEMPLATE = ../../template.tex
PANDOCOPTS = --latex-engine=xelatex \
--standalone \
--normalize \
--number-sections \
-M lang=frenchb \
-M fontsize=12pt \
-M papersize=a4paper \
--template=${TEMPLATE}
all: tutorial.pdf
tutorial.pdf: ${SOURCES}
pandoc ${PANDOCOPTS} -o $@ $+
clean::
rm tutorial.pdf

50
tutorial/1/cgroups.md Normal file
View file

@ -0,0 +1,50 @@
\newpage
# Utiliser les *cgroups*
## Premiers tests
### Création d'un nouveau groupe
### Rattachement de processus
### Consultatation de l'état
### Changement d'état
## Script de monitoring
### Monitoring instantanné vers la console
#### Option pour choisir l'intervalle de polling
### Monitoring vers InfluxDB
### Permettre à l'utilisateur de monitorer des process
#### Séparer en deux scripts
#### Ajouter les bonnes capabilities sur le premier script
#### Rendre ok avec les exécutions concurrentes du second script
### Monitorer chaque fils indépendamment
## Rendu
### Script de monitoring
Rendez la révision la plus avancées de vos scripts de monitoring de process via
les *cgroups*.
### Questions
1. Un même processus peut-il être dans plusieurs cgroups de type différents (freezer et cpuacct par exemple) ?
1. Que sera-t-il possible de limiter via un nouveau cgroup dans la prochaine
version du noyau (4.3) ?
1. Comment peut-on limiter le nombre de processus lancés par un utilisateur ou
un groupe ?

View file

@ -0,0 +1,52 @@
\newpage
# Installation
## Noyau Linux
Ce TP requiert d'avoir un noyau Linux en version 3.8 au minimum. De plus, il
doit être compilé avec les options suivantes :
```
General setup --->
[*] Control Group support --->
[*] Freezer cgroup subsystem
[*] Device controller for cgroups
[*] Cpuset support
[*] Include legacy /proc/<pid>/cpuset file
[*] Simple CPU accounting cgroup subsystem
[*] Group CPU scheduler --->
[*] Group scheduling for SCHED_OTHER
[*] Group scheduling for SCHED_RR/FIFO
<*> Block IO controller
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace
[*] PID Namespaces
[*] Network namespace
[*] Networking support --->
Networking options --->
<*> 802.1d Ethernet Bridging
<M> 802.1Q VLAN Support
Device Drivers --->
[*] Network device support --->
<M> MAC-VLAN support
<*> Virtual ethernet pair device
Character devices --->
-*- Unix98 PTY support
[*] Support multiple instances of devpts
```
Une fois que vous aurez installé LXC, vous pouvez vérifier la compatibilité de
la configuration de votre noyau en utilisant la commande `lxc-checkconfig`.
## LXC
Pour installer LXC, utilisez le gestionnaire de paquets de votre
distribution. Toute les bonnes distributions fournissent un paquet `lxc`.
Aucune configuration ne devrait vous être demandé durant l'installation. Une
fois l'installation terminée, exécutez la commande `lxc-checkconfig` pour
vérifier que votre noyau possède bien toutes les options nécessaires.

148
tutorial/1/lxc.md Normal file
View file

@ -0,0 +1,148 @@
\newpage
# Utiliser LXC
Le but de cette première partie est d'appréhender la virtualisation légère au
travers d'un programme, `lxc`, qui va mettre en place pour nous un
environnement distinct.
## Lancer un conteneur
Avec le paquet LXC que vous avez installé, vous avez également récupéré un
certain nombre de modèles de système (souvent installés dans le dossier
`/usr/share/lxc/templates/`).
La méthode la plus simple pour lancer un conteneur LXC est d'utiliser l'un de
ces modèles qui va installer tout un environnement pour vous. On utilise pour
cela la commande `lxc-create` :
```
lxc-create --name toto_first --template ubuntu
```
Ce modèle va créer un dossier dans `/var/lib/lxc/` portant le nom que vous avez
précisé. Ce dossier va contenir la configuration LXC du conteneur (`config`),
la table des partitions (`fstab`) s'il y a besoin de faire des montages
particuliers et enfin le dossier `rootfs` contenant le système en lui-même.
Une fois l'installation terminée, on peut démarrer le conteneur :
```
lxc-start --name toto_first
```
LXC va appeler `/sbin/init` et démarrer tous les services que l'on peut
s'attendre à trouver dans n'importe quelle machine virtuelle plus classique (la
seule différence réside donc dans le fait que le noyau est partagé avec
l'hôte).
Généralement on lance `lxc-start` avec l'option `--daemon`, car on ne s'attend
pas à ce que la machine s'arrête lorsque l'on va quitter notre terminal. Dans
ce cas, utiliser la commande `lxc-console` pour vous attacher à votre
conteneur. À tout moment, vous pouvez vous détacher de la console (sans que
cela n'affecte l'état du conteneur) en pressant les touches : `^A q`.
Connectez-vous, lancez quelques commandes puis éteignez la machine avec `sudo
poweroff` dans le conteneur. Vous pouvez aussi lancer la commande `lxc-stop
--name toto_first` dans un autre terminal, depuis la machine hôte.
## Le réseau
Le modèle ubuntu que vous avez utilisé initialise un fichier de configuration
sans paramètres pour le réseau. Vous n'avez donc pas d'interface dans le
conteneur pour le connecter au réseau.
Un excellent article détaillant les différents types de réseau est accessible à
<https://blog.flameeyes.eu/2010/09/linux-containers-and-networking>.
N'ayant qu'une seule interface physique sur la machine et n'ayant pas accès à
la configuration des VLAN de la pièce, il ne nous reste que deux méthodes pour
obtenir du réseau dans nos conteneurs : Virtual Ethernet ou
MACVLAN. Malheureusement, ces deux méthodes nécessitent de mettre en place un
pont Ethernet sur votre machine :
### Installation du pont réseau
#### Bridge interface
#### Port forwarding
### Virtual Ethernet
Virtual Ethernet est la configuration la plus simple. On met en place un pont
sur la machine hôte, puis on crée une interface `veth` par conteneur que l'on
veut lancer. On n'oubliera pas d'ajouter ces interfaces au pont.
Voici un extrait de configuration correspondant au paramétrage d'une interface
`eth0` pour un conteneur donné :
```
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
```
Cette technique a pour inconvénient de laisser au noyau le soin de router les
paquets selon leur adresse IP, ce qui peut être lent et coûteux étant donné que
la carte est placé en mode de promiscuité.
### MACVLAN
Ici, le noyau va orienter les paquets en fonction de leur adresse MAC de
destination.
```
lxc.network.type = macvlan
lxc.network.macvlan.mode = bridge
lxc.network.flags = up
lxc.network.link = br0
```
## Utilisation du conteneur
### Redémarrage du conteneur
### Installation de InFluxDB et Graphana
### Test de l'installation
## Rendu
### Configuration du conteneur
En plus des modifications que vous avez effectuées durant le TP, modifiez la
configuration du conteneur afin qu'il ne puisse pas utiliser plus que 256 MB de
RAM et 512 MB de swap.
Limitez ensuite les `capabilities(7)` de ce conteneur afin qu'il s'exécute avec
le strict minimum de droits, nécessaire au bon fonctionnement des programmes
installés.
**Rendez le fichier `config` de ce premier conteneur.** N'hésitez pas à laisser
des commentaires justifiant vos éventuels choix.
### Questions
1. Quel type de virtualisation réseau avez-vous utilisé ? pourquoi ?
1. Quels sont les autres types de virtualisation réseau existants ? Expliquez
en chacun une phrase leurs particularités.
1. Dans quel langage InfluxDB a-t-il était écrit ? Quelle est la particularité
des binaires générés par ce langage ?
1. Quels sont les avantages et les inconvénients associés au linkage statique
et au linkage dynamique ? (pas forcément que dans le cadre de la
virtualisation légère).
1. J'ai utilisé la méthode *Virtual Ethernet* pour relier mes conteneurs à
Internet, via un PAT (`br0`). Quelle(s) règle(s) `iptables` devrais-je
écrire sur mon hôte afin de permettre l'accès à InfluxDB depuis une autre
machine ?

129
tutorial/1/namespaces.md Normal file
View file

@ -0,0 +1,129 @@
\newpage
# Utiliser les *namespaces*
## Comparaison de *namespace*
Écrivez un script ou un programme, `cmpns`, dans le langage courant de votre
choix, permettant de déterminer si deux programmes s'exécutent dans les mêmes
*namespaces*.
### Exemples
```sh
42sh$ cmpns $(pgrep influxdb) $(pgrep init)
- ipc: differ
- mnt: differ
- net: differ
- pid: differ
- user: same
- uts: same
```
```sh
42sh$ cmpns $(pgrep init) self
- ipc: same
- mnt: same
- net: same
- pid: same
- user: same
- uts: same
```
Ici, `self` fait référence au processus actuellement exécuté.
## Rejoindre un *namespace*
Dans le langage courant de votre choix, écrivez un programme : `setns`,
permettant, à la manière de `unshare(1)` et `unshare(2)`, d'utiliser `setns(2)`
via votre interpréteur.
Les options attendues sont :
* rejoindre un namespace IPC : `-i`, `--ipc` ;
* rejoindre un namespace mount : `-m`, `--mount` ;
* rejoindre un namespace net : `-n`, `--net` ;
* rejoindre un namespace PID : `-p`, `--pid` ;
* rejoindre un namespace UTS : `-u`, `--uts` ;
* rejoindre un namespace user : `-U`, `--user`.
### Exemples
```sh
42sh# setns /bin/bash
bash# _
```
#### IPC and PID Namespaces
```sh
42sh# setns --ipc=/proc/42/ns/ipc -p /proc/42/ns/pid /bin/echo toto
toto
```
#### Net Namespace
```sh
42sh# setns --net=/proc/42/ns/net ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00::00
inet 127.0.0.1/8 brd 127.255.255.255 scope lo
valid_lft forever preferred_lft
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
```
#### UTS Namespace
```sh
42sh# hostname --fqdn
koala.zoo.paris
42sh# setns --uts=/proc/42/ns/uts hostname --fqdn
lynx.zoo.paris
```
## My Little Container
En utilisant le langage courant de votre choix, concevez l'exécutable `mlc`,
permettant de lancer une application dans un environnement différent (comme un
`chroot`, mais sans permettre de s'en échapper) et avec des privilèges réduits.
Votre solution doit créer au moins un nouveau *namespace* mount et PID.
Vous aurez sans doute besoin de : `clone(2)`, `capabilities(7)`, `capset(2)`, `pivot_root(2)`,
### Exemples
```sh
42sh# ls newroot
bin etc home usr root proc var
42sh# mlc newroot/ /bin/bash
bash# ls ../../../
bin etc home usr root proc var
bash# escape_chroot ls
bin etc home usr root proc var
bash# ls -ld /proc/[0-9]* | wc -l
2
bash# curl http://www.linuxcontainers.org/ | md5sum
0123456789abcdef
bash# ping 8.8.8.8
Operation not permitted
```
## Rendu
Pour chaque exercice de cette partie, vous pouvez rendre un seul fichier s'il
s'agit d'un script ; sinon, vous devez rendre une tarball contenant un
`Makefile` permettant de générer les éventuels exécutables et/ou un `README`
expliquant comment s'en servir.
Vous devez donc rendre 3 fichiers : `cmpns` ou `cmpns.tar.bz2`, `setns` ou
`setns.tar.bz2` et `mlc` ou `mlc.tar.bz2`.

21
tutorial/1/tutorial.md Normal file
View file

@ -0,0 +1,21 @@
% Virtualisation légère -- TP n^o^ 1
% Pierre-Olivier *nemunaire* Mercier
% Jeudi 8 octobre 2015
Le but de ce premier TP est d'utiliser les commandes et les appels systèmes vu
durant le cours.
Tous les éléments de ce TP (exercices et questions) sont à rendre à
<virli@nemunai.re> au plus tard le mercredi 21 octobre 2015 à 23 h 42. Consultez la
dernière section de chaque partie pour plus d'information sur les éléments à
rendre. Vous pouvez placer les réponses aux questions dans le corps du courriel
ou dans un fichier joint.
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devriez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
[me](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96) faire
signer votre clef et n'hésitez pas à
[faire signer votre clef](http://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
\hypersetup{linkcolor=black}
\tableofcontents