Conteneurs avec les namespaces sous Linux
Ce TD est à réaliser dans une machine virtuelle Ubuntu avec le démon Docker installé et activé. Avec les machines vagrant :
$ vagrant up ubuntu
$ vagrant ssh ubuntu
Objectifs
- Découvrir le principe des conteneurs à l’aide de Docker
Introduction aux conteneurs avec Docker
Vérifiez que le démon Docker est bien démarré :
$ sudo systemctl status docker
Lancement d’un conteneur interactif
Pour récupérer directement du registre de conteneurs public proposé par Docker (DockerHub) l’image officielle de conteneur Ubuntu, utilisez :
$ sudo docker pull ubuntu
Vérifiez qu’elle a bien été importée avec la commande :
$ sudo docker images
Par défaut, la dernière version publiée de l’image est téléchargée. Lancez un shell interactif dans un conteneur en utilisant cette image :
$ sudo docker run -it ubuntu bash
Essayez les commandes suivantes : ps aux
, id
, findmnt
, lsns
et comparez le résultat obtenu à l’intérieur et à l’extérieur du conteneur.
Quitter le conteneur avant de passer à la suite.
Construction d’un conteneur
Nous allons créer un conteneur qui contiendra un serveur HTTP hébergeant un site Web statique.
Pour commencer, voici un programme en Go qui mets à disposition sur le réseau le contenu du dossier www
en HTTP sur le port 8000
:
app.go
(télécharger) :
package main
import (
"log"
"net/http"
)
func main() {
fs := http.FileServer(http.Dir("www"))
http.Handle("/", fs)
log.Println("Listening...")
http.ListenAndServe(":8000", nil)
}
Créez un site Web minimal :
$ mkdir www
$ echo "Hello world" > www/index.html
Compilez et testez le bon fonctionnement du programme avec les commandes :
$ go build -o app app.go
$ ./app
Testez votre application avec curl
(ou avec un navigateur web) :
$ curl http://localhost:8000
Maintenant que notre application est prête, nous pouvons la mettre dans un conteneur. Pour que notre application puisse fonctionner, nous allons lister les bibliothèques dont elle a besoin pour les inclure ensuite dans le conteneur:
$ ldd app
linux-vdso.so.1 (0x00007ffea02a0000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4f9e080000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4f9e275000)
La librairie linux-vdso.so.1
“n’hexiste pas” car elle est fournie directement par le noyau aux processus (voir vdso(7)). Nous récupérons les autres dépendances:
$ cp /<chemin-complet-bilbiothèques> .
Pour décrire le contenu d’une image de conteneur avec Docker, nous allons utiliser un Dockerfile
. Voici un Dockerfile
qui crée un conteneur avec notre application et le site web :
Dockerfile
(télécharger) :
# Partir d'une image vide
FROM scratch
# Copier les bibliothèques et le binaire de notre application
COPY ld-linux-x86-64.so.2 /<chemin-complet-bibliothèque>
COPY libc.so.6 /<chemin-complet-bibliothèque>
COPY app app
# Copier le répertoire www avec la page web
COPY www www
# L'application utilise le port 8000
EXPOSE 8000
# La commande à lancer pour démarrer ce conteneur
CMD ["./app"]
Créer ensuite l’image du conteneur à partir du Dockerfile
:
$ sudo docker build --tag app .
Lancez le conteneur :
$ sudo docker run -ti app
Pour vérifier que nous avons bien accés à notre application, listez tous les conteneurs en cours d’exécution :
$ sudo docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
79c533003fe8 app "./app" ... 8000/tcp loving_goldwasser
Récupérez l’adresse IP du conteneur qui nous intéresse à l’aide de son container id
:
$ sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container id>
172.17.0.2
Récupérez la page Web avec curl (ou un navigateur web) :
$ curl 172.17.0.2:8000