Rework TP2

This commit is contained in:
nemunaire 2016-09-14 22:51:14 +02:00 committed by Pierre-Olivier Mercier
parent 3b55c0671d
commit ef5ffaa782
7 changed files with 160 additions and 112 deletions

View File

@ -7,7 +7,7 @@ bien cette dernière bonne pratique d'un seul processus par conteneur
:-(
L'intérêt est de permettre à chaque conteneur d'effectuer une tâche
générique, de manière à pouvoir être réutilisé pour d'autres projet
générique, de manière à pouvoir être réutilisé pour d'autres projets
dans le futur. Par exemple, notre conteneur InfluxDB pourra être
utilisé pour stocker des relevés de métriques systèmes ou des logs.
Grafana peut également afficher davantage d'informations ou combiner
@ -22,10 +22,11 @@ nous allons garder la partie InfluxDB, de l'autre la partie Grafana.
Il va vous falloir créer deux dossiers distincts, il en faut un par
`Dockerfile`.
Profitez en pour rajouter les Data Volume Container.
Profitez en pour rajouter les Data Volume Container, si vous ne l'avez
pas fait dans la partie précédente !
## Automatiser le lancement
## Automatiser la construction et le lancement
Commencez par lancer tous vos conteneurs à la main pour voir les
étapes que vous allez devoir automatiser.
@ -34,3 +35,35 @@ Au lieu de faire un script pour construire et lancer tous vos
conteneurs, définissez à la racine de votre projet un fichier
`docker-compose.yml` qui contiendra les méthodes de construction et
les paramètres d'exécution.
```
influxdb:
...
grafana:
build: grafana/
image: nginx
ports:
- "3000:3000"
volumes:
- ./:/tmp/toto
links:
- influxdb
```
Ce fichier est un condensé des options que vous passez habituellement
au `docker run`.
L'exemple ci-dessus est à adapter largement, consultez
<http://docs.docker.com/compose/yml/> pour une liste exhaustive des
options que vous pouvez utiliser.
Une fois que votre `docker-compose.yml` sera prêt, lancez tout d'abord
`docker-compose build` pour commencer la phase de build de tous les
conteneurs listés dans le fichier.
Une fois le build terminé, vous pouvez lancer la commande suivante pour admirer le résultat :
```
docker-compose up
```

View File

@ -2,82 +2,82 @@
# Premiers pas
Dans un premier temps, nous allons créer une image Docker comme si
l'on réalisait l'installation sur une machine classique : en suivant
une recette. La machine (notre première image Docker) contient tout le
nécessaire pour faire fonctionner notre service.
Dans un premier temps, nous allons créer une image Docker comme si l'on
réalisait l'installation sur une machine classique : en suivant les méthodes
habituelles, mais tout en écrivant notre recette dans le `Dockerfile`. La
machine (notre première image Docker) contiendra tout le nécessaire pour faire
fonctionner notre service.
## Les caches
Nous avons vu que chaque instruction de notre `Dockerfile` génère une
couche. Chaque couche sert de cache d'une construction de conteneur à
l'autre. Ainsi, lorsque vous modifiez une instruction dans votre
`Dockerfile`, les instructions précédentes ne sont pas réexécutées
mais sont ressorties du cache.
l'autre. Ainsi, lorsque vous modifiez une instruction dans votre `Dockerfile`,
les instructions précédentes ne sont pas réexécutées mais sont ressorties du
cache.
Le cache se basant principalement sur le contenu de chaque instruction
dans le `Dockerfile` (pour les `COPY` et `ADD`, il va aussi regarder
la date de dernière modification de fichier copié ou ajouté). Donc
tant qu'une instruction n'est pas modifiée dans le `Dockerfile`, le
cache sera utilisé.
Le cache se base principalement sur le contenu de chaque instruction dans le
`Dockerfile` (pour les `COPY` et `ADD`, il va aussi regarder la date de
dernière modification de fichier copié ou ajouté). Donc tant qu'une instruction
n'est pas modifiée dans le `Dockerfile`, le cache sera utilisé.
Il est possible de ne pas utiliser le cache et de relancer toutes les
étapes du `Dockerfile` en ajoutant l'option `--no-cache` au moment du
`docker build`.
Il est possible de ne pas utiliser le cache et de relancer toutes les étapes du
`Dockerfile` en ajoutant l'option `--no-cache` au moment du `docker build`.
Les couches du cache peuvent être partagées entre plusieurs conteneur,
c'est ainsi que vous pouvez partager facilement une plus grosse partie
du système de fichier (afin de profiter du cache du système de
fichiers au moment de l'exécution du conteneur).
Les couches du cache peuvent être partagées entre plusieurs conteneur, c'est
ainsi que vous pouvez partager facilement une plus grosse partie du système de
fichiers (afin de profiter du cache du système de fichiers au moment de
l'exécution du conteneur).
\vspace{1.5em}
## `apt-get`
Pour profiter du cache, il faut donc placer les étapes les plus génériques (qui
seraient susceptibles d'apparaître dans plusieurs conteneur), en haut du
`Dockerfile`.
Pour profiter du cache, il faut donc placer les étapes les plus
génériques (qui seraient susceptibles d'apparaître dans plusieurs
conteneur), en haut du `Dockerfile`.
Commençons donc notre `Dockerfile` : choisissez une image de base pour
votre `FROM`, et indiquez votre nom avec l'instruction `MAINTAINER`,
pour indiquez que c'est vous qui maintenez ce conteneur (si d'autres
gens ont besoin qu'il faut le mettre à jour par exemple).
Commençons donc notre `Dockerfile` : choisissez une image de base pour votre
`FROM`, et indiquez votre nom avec l'instruction `MAINTAINER`, pour indiquez
que c'est vous qui maintenez ce conteneur (si d'autres gens ont besoin qu'il
faut le mettre à jour par exemple).
## `RUN` ou script ?
### InfluxDB
Ensuite viens l'installation d'InfluxDB. Le paquet n'est pas
disponible dans les dépôts. La
[https://influxdb.com/docs/v0.9/introduction/installation.html](procédure
décrite sur le site) incite à télécharger le paquet mis à disposition
puis à l'installer via `dpkg -i`.
Ensuite vient l'installation d'InfluxDB. Le paquet n'est pas disponible dans
les dépôts. La
[procédure décrite sur le site](https://influxdb.com/docs/v0.9/introduction/installation.html)
incite à télécharger le paquet mis à disposition puis à l'installer via `dpkg
-i`.
Deux solutions s'offrent à nous : télécharger le paquet hors du
conteneur, le copier, puis l'installer. Ou faire un `RUN` avec toutes
ces opérations (sans oublier l'installation de `wget`/`curl`).
Deux solutions s'offrent à nous : télécharger le paquet hors du conteneur, le
copier, puis l'installer. Ou faire un `RUN` avec toutes ces opérations (sans
oublier l'installation de `wget`/`curl`).
La copie étant définitive (supprimer le fichier ne le supprimera pas
des couches où il a pu exister), donc la seconde solution semble
préférable (mais `wget` restera en déchet).
La copie étant définitive (supprimer le fichier ne le supprimera pas des
couches où il a pu exister), donc la seconde solution semble préférable (mais
`wget` restera en déchet).
Écrivez une commande `RUN` qui va télécharger la dernière version
d'InfluxDB, qui va l'installer et supprimer le fichier.
Écrivez une commande `RUN` qui va télécharger la dernière version d'InfluxDB,
qui va l'installer et supprimer le fichier.
\vspace{1em}
À ce stade, nous pouvons déjà terminer le conteneur et tester
qu'InfluxDB est bien utilisable : `EXPOSE`, `CMD`, ... Il est possible
que vous ayez à écraser le fichier de configuration via un
`COPY`. Garder la ligne qui vous permet de lancer votre serveur web
dans un coin, en attendant la partie suivante.
À ce stade, nous pouvons déjà terminer le conteneur et tester qu'InfluxDB est
bien utilisable : `EXPOSE`, `CMD`, ...
Il est possible que vous ayez à écraser le fichier de configuration via un
`COPY` (ou de manière plus maline en utilisant `--volume` au moment du `docker
run`, cela fonctionne pas qu'avec les dossiers). Garder la ligne qui vous
permet de lancer votre serveur web dans un coin, en attendant la partie
suivante.
### Grafana
Une fois InfluxDB configuré, nous allons avoir la même réflexion avec
Grafana.
Une fois InfluxDB configuré, nous allons avoir la même réflexion avec Grafana.
De la même manière, téléchargez, installez et supprimez le paquet.

View File

@ -2,7 +2,8 @@
# Retour sur les bonnes pratiques
http://docs.docker.com/articles/dockerfile_best-practices/
Pour chacune des bonnes pratiques ci-dessous, vérifiez que vous les respectez
bien, faites les modifications nécessaires.
## Utilisez le fichier `.dockerignore`
@ -105,7 +106,7 @@ Il y a un certain nombre de règles à connaître pour bien utiliser ce mécanis
## Concevez des conteneur éphémères
Les conteneurs que vous générez doivent aussi éphémères que possible : ils
devraient pouvoir être arrêtés, détruits et recréés sans nécessité d'étape de
devraient pouvoir être arrêtés, détruits et recréés sans nécessiter d'étape de
reconfiguration. La configuration devrait se faire au lancement du conteneur ou
lors de sa construction.
@ -149,32 +150,32 @@ L'entrypoint peut être utilisé de deux manières différentes :
après le nom de l'image, corresponde aux arguments attendu par le programme
indiqué dans l'entrypoint. Par exemple pour nginx :
```
ENTRYPOINT ["nginx"]
CMD ["-g daemon off;"]
```
```
ENTRYPOINT ["nginx"]
CMD ["-g daemon off;"]
```
- Vous pouvez aussi utiliser un script qui servira à faire les initialisations
ou les configurations nécessaire au bon fonctionnement du conteneur
(rappelez-vous, il doit être éphémère !). Par exemple, le `Dockerfile` pour
l'image de PostgreSQL possède cet entrypoint :
```
#!/bin/bash
set -e
```
#!/bin/bash
set -e
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec gosu postgres "$@"
fi
exec "$@"
```
exec "$@"
```
## `[""]`, `'` et sans `[]`
@ -194,7 +195,7 @@ pouvez pas utiliser les simple quotes.
## Volumes
L'instruction `VOLUME` doit être utilisée pour exposer tous les espaces de
stockage
stockage de données, configuration, ...
## Réduisez les privilèges
@ -205,6 +206,18 @@ réclame pas de privilège particulier.
Il vous faudra sans doute créer l'utilisateur et son groupe dans le Dockerfile.
## Profitez du système de liaison et de résolution de nom
Dès lors que vous effectuez un lien avec un autre conteneur, son nom (ou son
alias) est ajouté au fichier `/etc/hosts`. Cela signifie que lorsqu'un nom de
domaine correspondant au nom du conteneur (ou son alias) sera recherché, l'IP
sera bien celle du conteneur. Lorsque vous configurez un conteneur, utilisez de
préférence un nom plutôt qu'une IP, qui changera à coup sûr.
Au moment du `docker run`, vous pouvez préciser d'autres noms d'ĥôtes
particuliers en utilisant l'option `--add-host`.
## Exécutez un seul processus par conteneur
Dans la majorité des cas, vous ne devriez jamais lancer plus d'un seul

View File

@ -8,7 +8,8 @@ L'équipe en charge de Docker compose met à disposition un binaire contenant
tous les scripts. Nous pouvons l'installer en suivant la procédure suivante :
```
curl -L https://github.com/docker/compose/releases/download/1.3.3/docker-compose-Linux-x86_64 > /usr/bin/docker-compose
curl -L https://github.com/docker/compose/releases/download/1.3.3/docker-compose-Linux-x86_64 \
> /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose
```

View File

@ -2,6 +2,16 @@
# Rendu
## Avis
Dans le courriel que vous enverrez, je serais ravi de connaître votre avis sur
ce cours : aussi bien les choses que vous avez apprécié que celles que vous
n'avez pas aimés.
Cela ne rentrera pas en compte dans la notation, mais permettra d'améliorer ce
cours.
## TP
Rendez le contenu de votre dossier à la dernière étape du TP : avec le
@ -13,9 +23,9 @@ annexes.
De la même manière que nous avons réaliser un groupe de conteneurs utilisant
`grafana` et `InfluxDB`, qui permet d'afficher facilement des métriques sous
forme de graphiques, vous allez réaliser, à l'aide des images Docker
présentent sur le hub, une interface web de recherche et de visualisation de
logs, utilisant
forme de graphiques, vous allez réaliser, à l'aide des images Docker présentent
sur le hub, une interface web de recherche et de visualisation de logs,
utilisant
[Kibana](https://www.digitalocean.com/community/tutorials/how-to-install-elasticsearch-logstash-and-kibana-4-on-ubuntu-14-04).
Toutes la chaîne d'image Docker est déjà présente sur le hub :

View File

@ -4,21 +4,21 @@
## Script d'init
Lors du dernier TP, nous avons vu que les conteneurs étaient détruits
dès que le premier processus du conteneur (celui qui a le PID 1, à la
place d'`init`) terminer son exécution, quelque soit le statut de ses
éventuels fils.
Lors du dernier TP, nous avons vu que les conteneurs étaient détruits dès que
le premier processus du conteneur (celui qui a le PID 1, à la place d'`init`)
terminer son exécution, quelque soit le statut de ses éventuels fils.
Pour lancer tous nos daemon,
Pour lancer tous nos daemon, nous allons donc besoin d'écrire un script qui
lance puis attend que les deux deamons aient terminés de s'exécuter
## Autorestart
L'avantage de détruire le conteneur à la mort du père, est que s'il
s'agit de notre processus principal et qu'il est seul (par exemple
`nginx` pour un conteneur qui délivre des pages web), il va être
possible de redémarrer le conteneur automatiquement grâce à la
*restart policy* que l'on peut définir au moment du `docker run` :
L'avantage de détruire le conteneur à la mort du père, est que s'il s'agit de
notre processus principal et qu'il est seul (par exemple `nginx` pour un
conteneur qui délivre des pages web), il va être possible de redémarrer le
conteneur automatiquement grâce à la *restart policy* que l'on peut définir au
moment du `docker run` :
```
docker run -d -p 80:80 --restart=on-failure nginx
@ -26,28 +26,26 @@ docker run -d -p 80:80 --restart=on-failure nginx
Il existe trois règles de redémarrage différentes :
- **`no` :** il s'agit de la règle par défaut. Lorsque l'exécution du
conteneur se termine, il n'est pas redémarré.
- **`on-failure[:max-retries]` :** redémarre uniquement si le code de
sortie du conteneur n'est pas 0. Il est possible de préciser pour
cette option le nombre maximum de redémarrage qui sera tenté.
- **`always` :** redémarre le conteneur dans tous les cas, quelque
soit son code de sortie et indéfiniment.
- **`no` :** il s'agit de la règle par défaut. Lorsque l'exécution du conteneur
se termine, il n'est pas redémarré.
- **`on-failure[:max-retries]` :** redémarre uniquement si le code de sortie du
conteneur n'est pas 0. Il est possible de préciser pour cette option le
nombre maximum de redémarrage qui sera tenté.
- **`always` :** redémarre le conteneur dans tous les cas, quelque soit son
code de sortie et indéfiniment.
Le script d'init que vous avez réalisé ne tient sans doute pas compte
de cela. Mais plein de gens ont cette problématique et `supervisor`
Le script d'init que vous avez réalisé ne tient sans doute pas compte de
cela. Mais plein de gens ont cette problématique et l'application `supervisor`
répond parfaitement à notre problématique !
## `supervisor`
Première étape : installer `supervisor`, le paquet se trouve dans les
dépôts.
Première étape : installer `supervisor`, le paquet se trouve dans les dépôts.
L'étape suivante consiste à remplir puis copier le fichier de
configuration dans le conteneur. Vous allez devoir écraser dans votre
conteneur le fichier `/etc/supervisord.conf` pour démarrer à la fois
`grafana` et `influxdb`.
L'étape suivante consiste à remplir puis copier le fichier de configuration
dans le conteneur. Vous allez devoir écraser dans votre conteneur le fichier
`/etc/supervisord.conf` pour démarrer à la fois `grafana` et `influxdb`.
Vous pouvez vous aider de la documentation disponible à :
<http://supervisord.org/configuration.html>
@ -55,6 +53,6 @@ Vous pouvez vous aider de la documentation disponible à :
## C'est parti !
Votre conteneur doit maintenant être parfaitement fonctionnel : vous
devriez pouvoir lancer votre script de monitoring et voir apparaître
vos données dans Grafana !
Votre conteneur doit maintenant être parfaitement fonctionnel : vous devriez
pouvoir lancer votre script de monitoring et voir apparaître vos données dans
Grafana !

View File

@ -1,5 +1,3 @@
\newpage
# But du TP
Aujourd'hui, nous allons terminer notre système de monitoring commencé lors du
@ -8,11 +6,6 @@ premier TP.
Le résultat attendu d'ici la fin du TP, est un groupe de conteneurs
indépendants les uns des autres, réutilisables en fonction des besoins.
TODO image de graphana
Nous reprendrons le script de monitoring que vous avez rendu au premier TP. Les
données collectées seront envoyés vers [https://influxdb.com/](InfluxDB), puis
elles seront affichées sous forme de graphique dans
[http://grafana.org/](Grafana). L'interface sera servie par un reverse-proxy
qui vous permettra de n'ouvrir que le port 80 ou 443, pour accéder à
l'interface d'administration d'InfluxDB et à l'interface de Grafana.
Les données collectées seront envoyés vers
[InfluxDB](https://influxdb.com/), puis elles seront affichées sous
forme de graphique dans [Grafana](http://grafana.org/).