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 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 dans le futur. Par exemple, notre conteneur InfluxDB pourra être
utilisé pour stocker des relevés de métriques systèmes ou des logs. utilisé pour stocker des relevés de métriques systèmes ou des logs.
Grafana peut également afficher davantage d'informations ou combiner 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 Il va vous falloir créer deux dossiers distincts, il en faut un par
`Dockerfile`. `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 Commencez par lancer tous vos conteneurs à la main pour voir les
étapes que vous allez devoir automatiser. é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 conteneurs, définissez à la racine de votre projet un fichier
`docker-compose.yml` qui contiendra les méthodes de construction et `docker-compose.yml` qui contiendra les méthodes de construction et
les paramètres d'exécution. 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 # Premiers pas
Dans un premier temps, nous allons créer une image Docker comme si Dans un premier temps, nous allons créer une image Docker comme si l'on
l'on réalisait l'installation sur une machine classique : en suivant réalisait l'installation sur une machine classique : en suivant les méthodes
une recette. La machine (notre première image Docker) contient tout le habituelles, mais tout en écrivant notre recette dans le `Dockerfile`. La
nécessaire pour faire fonctionner notre service. machine (notre première image Docker) contiendra tout le nécessaire pour faire
fonctionner notre service.
## Les caches ## Les caches
Nous avons vu que chaque instruction de notre `Dockerfile` génère une Nous avons vu que chaque instruction de notre `Dockerfile` génère une
couche. Chaque couche sert de cache d'une construction de conteneur à couche. Chaque couche sert de cache d'une construction de conteneur à
l'autre. Ainsi, lorsque vous modifiez une instruction dans votre l'autre. Ainsi, lorsque vous modifiez une instruction dans votre `Dockerfile`,
`Dockerfile`, les instructions précédentes ne sont pas réexécutées les instructions précédentes ne sont pas réexécutées mais sont ressorties du
mais sont ressorties du cache. cache.
Le cache se basant principalement sur le contenu de chaque instruction Le cache se base principalement sur le contenu de chaque instruction dans le
dans le `Dockerfile` (pour les `COPY` et `ADD`, il va aussi regarder `Dockerfile` (pour les `COPY` et `ADD`, il va aussi regarder la date de
la date de dernière modification de fichier copié ou ajouté). Donc dernière modification de fichier copié ou ajouté). Donc tant qu'une instruction
tant qu'une instruction n'est pas modifiée dans le `Dockerfile`, le n'est pas modifiée dans le `Dockerfile`, le cache sera utilisé.
cache sera utilisé.
Il est possible de ne pas utiliser le cache et de relancer toutes les Il est possible de ne pas utiliser le cache et de relancer toutes les étapes du
étapes du `Dockerfile` en ajoutant l'option `--no-cache` au moment du `Dockerfile` en ajoutant l'option `--no-cache` au moment du `docker build`.
`docker build`.
Les couches du cache peuvent être partagées entre plusieurs conteneur, Les couches du cache peuvent être partagées entre plusieurs conteneur, c'est
c'est ainsi que vous pouvez partager facilement une plus grosse partie ainsi que vous pouvez partager facilement une plus grosse partie du système de
du système de fichier (afin de profiter du cache du système de fichiers (afin de profiter du cache du système de fichiers au moment de
fichiers au moment de l'exécution du conteneur). 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 Commençons donc notre `Dockerfile` : choisissez une image de base pour votre
génériques (qui seraient susceptibles d'apparaître dans plusieurs `FROM`, et indiquez votre nom avec l'instruction `MAINTAINER`, pour indiquez
conteneur), en haut du `Dockerfile`. 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 ? ## `RUN` ou script ?
### InfluxDB ### InfluxDB
Ensuite viens l'installation d'InfluxDB. Le paquet n'est pas Ensuite vient l'installation d'InfluxDB. Le paquet n'est pas disponible dans
disponible dans les dépôts. La les dépôts. La
[https://influxdb.com/docs/v0.9/introduction/installation.html](procédure [procédure décrite sur le site](https://influxdb.com/docs/v0.9/introduction/installation.html)
décrite sur le site) incite à télécharger le paquet mis à disposition incite à télécharger le paquet mis à disposition puis à l'installer via `dpkg
puis à l'installer via `dpkg -i`. -i`.
Deux solutions s'offrent à nous : télécharger le paquet hors du Deux solutions s'offrent à nous : télécharger le paquet hors du conteneur, le
conteneur, le copier, puis l'installer. Ou faire un `RUN` avec toutes copier, puis l'installer. Ou faire un `RUN` avec toutes ces opérations (sans
ces opérations (sans oublier l'installation de `wget`/`curl`). oublier l'installation de `wget`/`curl`).
La copie étant définitive (supprimer le fichier ne le supprimera pas La copie étant définitive (supprimer le fichier ne le supprimera pas des
des couches où il a pu exister), donc la seconde solution semble couches où il a pu exister), donc la seconde solution semble préférable (mais
préférable (mais `wget` restera en déchet). `wget` restera en déchet).
Écrivez une commande `RUN` qui va télécharger la dernière version Écrivez une commande `RUN` qui va télécharger la dernière version d'InfluxDB,
d'InfluxDB, qui va l'installer et supprimer le fichier. qui va l'installer et supprimer le fichier.
\vspace{1em} \vspace{1em}
À ce stade, nous pouvons déjà terminer le conteneur et tester À ce stade, nous pouvons déjà terminer le conteneur et tester qu'InfluxDB est
qu'InfluxDB est bien utilisable : `EXPOSE`, `CMD`, ... Il est possible bien utilisable : `EXPOSE`, `CMD`, ...
que vous ayez à écraser le fichier de configuration via un
`COPY`. Garder la ligne qui vous permet de lancer votre serveur web Il est possible que vous ayez à écraser le fichier de configuration via un
dans un coin, en attendant la partie suivante. `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 ### Grafana
Une fois InfluxDB configuré, nous allons avoir la même réflexion avec Une fois InfluxDB configuré, nous allons avoir la même réflexion avec Grafana.
Grafana.
De la même manière, téléchargez, installez et supprimez le paquet. 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 # 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` ## 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 ## Concevez des conteneur éphémères
Les conteneurs que vous générez doivent aussi éphémères que possible : ils 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 reconfiguration. La configuration devrait se faire au lancement du conteneur ou
lors de sa construction. 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 après le nom de l'image, corresponde aux arguments attendu par le programme
indiqué dans l'entrypoint. Par exemple pour nginx : indiqué dans l'entrypoint. Par exemple pour nginx :
``` ```
ENTRYPOINT ["nginx"] ENTRYPOINT ["nginx"]
CMD ["-g daemon off;"] CMD ["-g daemon off;"]
``` ```
- Vous pouvez aussi utiliser un script qui servira à faire les initialisations - Vous pouvez aussi utiliser un script qui servira à faire les initialisations
ou les configurations nécessaire au bon fonctionnement du conteneur ou les configurations nécessaire au bon fonctionnement du conteneur
(rappelez-vous, il doit être éphémère !). Par exemple, le `Dockerfile` pour (rappelez-vous, il doit être éphémère !). Par exemple, le `Dockerfile` pour
l'image de PostgreSQL possède cet entrypoint : l'image de PostgreSQL possède cet entrypoint :
``` ```
#!/bin/bash #!/bin/bash
set -e set -e
if [ "$1" = 'postgres' ]; then if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA" chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb gosu postgres initdb
fi fi
exec gosu postgres "$@" exec gosu postgres "$@"
fi fi
exec "$@" exec "$@"
``` ```
## `[""]`, `'` et sans `[]` ## `[""]`, `'` et sans `[]`
@ -194,7 +195,7 @@ pouvez pas utiliser les simple quotes.
## Volumes ## Volumes
L'instruction `VOLUME` doit être utilisée pour exposer tous les espaces de L'instruction `VOLUME` doit être utilisée pour exposer tous les espaces de
stockage stockage de données, configuration, ...
## Réduisez les privilèges ## 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. 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 ## Exécutez un seul processus par conteneur
Dans la majorité des cas, vous ne devriez jamais lancer plus d'un seul 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 : 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 chmod +x /usr/bin/docker-compose
``` ```

View file

@ -2,6 +2,16 @@
# Rendu # 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 ## TP
Rendez le contenu de votre dossier à la dernière étape du TP : avec le 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 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 `grafana` et `InfluxDB`, qui permet d'afficher facilement des métriques sous
forme de graphiques, vous allez réaliser, à l'aide des images Docker forme de graphiques, vous allez réaliser, à l'aide des images Docker présentent
présentent sur le hub, une interface web de recherche et de visualisation de sur le hub, une interface web de recherche et de visualisation de logs,
logs, utilisant utilisant
[Kibana](https://www.digitalocean.com/community/tutorials/how-to-install-elasticsearch-logstash-and-kibana-4-on-ubuntu-14-04). [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 : Toutes la chaîne d'image Docker est déjà présente sur le hub :

View file

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

View file

@ -1,5 +1,3 @@
\newpage
# But du TP # But du TP
Aujourd'hui, nous allons terminer notre système de monitoring commencé lors du 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 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. indépendants les uns des autres, réutilisables en fonction des besoins.
TODO image de graphana Les données collectées seront envoyés vers
[InfluxDB](https://influxdb.com/), puis elles seront affichées sous
Nous reprendrons le script de monitoring que vous avez rendu au premier TP. Les forme de graphique dans [Grafana](http://grafana.org/).
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.