2020 done
This commit is contained in:
parent
fafac06b23
commit
a75f4b43b7
@ -1,22 +1,26 @@
|
||||
FROM debian
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
software-properties-common \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \
|
||||
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
containerd.io \
|
||||
docker-ce \
|
||||
docker-ce-cli \
|
||||
python \
|
||||
systemd-sysv \
|
||||
udev \
|
||||
vim.tiny \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl -L -o /tmp/wireguard.deb http://httpredir.debian.org/debian/pool/main/w/wireguard/wireguard-tools_0.0.20190227-1_amd64.deb && dpkg -i /tmp/wireguard.deb; rm /tmp/wireguard.deb
|
||||
|
||||
RUN rm -rf /etc/init.d/ && \
|
||||
mkdir /overlay && \
|
||||
ln -sf /init /sbin/init && \
|
||||
|
Binary file not shown.
@ -1,220 +0,0 @@
|
||||
[file]
|
||||
1-docker's basis.pdf
|
||||
[skip]
|
||||
4,5,6,7,8,10,11,12,13,18,21,22,23,29,30,36,37,38,
|
||||
[end_user_slide]
|
||||
22
|
||||
[notes]
|
||||
### 1
|
||||
Après la piscine, on reste dans un thème aquatique, puisqu'on va parler de Docker aujourd'hui !
|
||||
|
||||
Sondage de repérage
|
||||
|
||||
* Qui a déjà entendu parlé de Docker ?
|
||||
* Qui a déjà utilisé au moins une fois ?
|
||||
* Est-ce que certain l'utilisent tous les jours ou presque ?
|
||||
|
||||
C'est vrai qu'une fois compris les principes, peut plus s'en passer.
|
||||
|
||||
* qqn déjà essayé un autre programme de virli ?
|
||||
|
||||
Pour les autres,
|
||||
on va p-e commencer par expliquer ce que c'est, la virli.### 2
|
||||
Déjà, la virtualisation ...
|
||||
|
||||
* La virtualisation classique
|
||||
|
||||
** gros serveur répondre pic de trafic quotidient, passe son temps à rien faire hors de ce pic => besoin d'optim
|
||||
** Déploiement fastidieux de services concurrent (ex. un serveur web) :
|
||||
- partager le port = partager la config
|
||||
- reverse proxy : ok tant que c'est deux soft différents
|
||||
- installation en parallèle de deux versions différentes hasardeuses et complexe
|
||||
|
||||
** Création du principe de machine virtuelle
|
||||
- émulation du matériel
|
||||
- gain en terme de sécu
|
||||
|
||||
** Aidé des instructions de virtualisation
|
||||
- le matériel reste émulé, mais prends des raccourcis lorsque supporté par l'hôte et l'invité (virtio)
|
||||
### 3
|
||||
* Quelles sont les grandes étapes de boot d'une machine moderne ?
|
||||
ground PS_ON, reset CPU, bootloader (BIOS/UEFI), chargeur d'amorce (GRUB, ...), noyau de l'OS, espace utilisateur (init, systemd, ...), daemons et applications utilisateur (logind, Xorg, ...)
|
||||
|
||||
* différences avec une machine virtuelle
|
||||
- création d'un espace d'adressage
|
||||
- vmenter
|
||||
|
||||
* Optimisation du reboot ?
|
||||
|
||||
* Pas encore très léger comme virtualisation
|
||||
on veut pas vraiment des multiples noyaux et système, simplement pour un daemon qui écoute sur une autre IP
|
||||
|
||||
* Virtualisation légère : le noyau peut isoler des systèmes différents
|
||||
- On a plus que l'espace utilisateur à recharger
|
||||
- Plein de technos font ça : OpenVZ, LXC, ...
|
||||
DEMO LXC VPS
|
||||
|
||||
* C'est mieux, mais on a encore des éléments inutiles : cron, init, ...
|
||||
=> Et si on lançait uniquement notre deamon ?
|
||||
DEMO docker owncloud, telegraf/graphana/... SRS FIC ?
|
||||
|
||||
* pub pour les cours 3 et 4 sur Linux Internals : NS + cg
|
||||
### 4
|
||||
* Scheduling simplifié
|
||||
* RAM mieux utilisée
|
||||
|
||||
- kernel unique
|
||||
- libc partagées
|
||||
- cache de fichiers unique (s'adapte à l'espace restant)
|
||||
### 5
|
||||
* Acteurs historiques
|
||||
- Zones Solaris
|
||||
- Jails BSD
|
||||
- OpenVZ
|
||||
|
||||
* Arnaques
|
||||
- Docker4mac
|
||||
- Docker4windows
|
||||
Microsoft Hyper-V
|
||||
Windows 10 Pro 64 bits
|
||||
|
||||
* En développement/test
|
||||
- Windows Containers
|
||||
Windows Server 2016
|
||||
Windows 10 Anniversary Edition
|
||||
### 6
|
||||
Questions ?
|
||||
### 7
|
||||
DAEMON
|
||||
* REST API
|
||||
* qui gère des Docker objects
|
||||
- images, conteneurs, services
|
||||
- réseaux, nœux de cluster
|
||||
- volumes
|
||||
* local registry
|
||||
* containerd/runc
|
||||
|
||||
CLIENT
|
||||
|
||||
Open Container Initiative
|
||||
|
||||
Docker hub/store
|
||||
### 8
|
||||
Image
|
||||
* Modèle en lecture seule
|
||||
* utilisé pour pour créer les conteneurs
|
||||
|
||||
Conteneur
|
||||
* Instance d'une image
|
||||
* isolé de tout de base, on règle après ce que l'on souhaite partager (réseau, stockage, ...)
|
||||
|
||||
Services
|
||||
* groupe de conteneurs qui forme une application
|
||||
### 9
|
||||
Démo
|
||||
|
||||
docker run touch /toto
|
||||
voir que dans un autre docker run, ls / ne montre pas foo
|
||||
### 10
|
||||
Commence par regarder en local si on a pas l'image
|
||||
|
||||
Ensuite il va interroger son registre par défaut, sans configuration, il s'agit du Docker Store.
|
||||
|
||||
Si l'on désucre le nom du conteneur, on obtient ce chemin
|
||||
|
||||
Le but de Docker étant de récupérer un fichier manifests
|
||||
|
||||
|
||||
On utilise la forme complètement quand on a un registre privé
|
||||
### 11
|
||||
Parler de l'ancienne syntaxe toujours d'actualité, mais beaucoup plus documentée
|
||||
### 12
|
||||
Démo
|
||||
|
||||
docker image ls
|
||||
docker image rm
|
||||
|
||||
docker container ls
|
||||
docker container rm
|
||||
docker container create
|
||||
### 13
|
||||
Comment fait-on pour créer une image ?
|
||||
|
||||
On va pouvoir créer une image (qui pourra donc servir de modèle pour créer d'autre cntr) à partir d'un conteneur que l'on décidera de figer à un instant donné.
|
||||
|
||||
=> docker commit
|
||||
|
||||
On indique lors du commit le conteneur à figer ainsi que lenom de l'image que l'on souhaite créer.### 14
|
||||
* CoW
|
||||
* layers/couches (docker image history IMAGE)
|
||||
* unionfs
|
||||
### 15
|
||||
Maintenant, comment faire en sorte que deux conteneur puissent se parler ?
|
||||
|
||||
On commence par lancer deux cntrs. et l'on demande explicitement à ce que le compteur nous expose son port 80.
|
||||
--
|
||||
On crée ensuite un objet Docker network, dans lequel on vient placer nos deux conteneurs.
|
||||
Ils peuvent alors se parler.
|
||||
--
|
||||
Mieux encore, un serveur DNS permet de résoudre le nom des conteneurs dans ce réseau, pour simplifier la configuration.
|
||||
|
||||
Si trop de temps :
|
||||
docker container run -P nginx
|
||||
docker container ls
|
||||
docker container port $ID
|
||||
go with firefox
|
||||
### 16
|
||||
On utilisé juste avant docker commit pour créer une nouvelle image à partir d'un conteneur. Mais on peut aussi utiliser ce qu'on appel des Dockerfile.
|
||||
|
||||
- fichier texte
|
||||
- instructions de base : FROM, RUN, COPY, CMD
|
||||
|
||||
DEMO hello srs 1
|
||||
|
||||
- passage du contexte au daemon
|
||||
- .dockerignore
|
||||
|
||||
- cache de construction
|
||||
|
||||
- bonnes pratiques à propos des installs :
|
||||
- minimise le nombre de couches
|
||||
faire la part des choses entre relecture/maintenabilité et nombre de couches
|
||||
### 17
|
||||
Dockerfile hello srs
|
||||
|
||||
À propos du linkage statique vs. dynamique
|
||||
### 18
|
||||
chaque ligne est exécutée dans un conteneur distinct
|
||||
les commandes ne servent qu'à modifier le système de fichier
|
||||
on ne peut pas lancer un programme, il sera fermé avec le conteneur
|
||||
|
||||
- bonnes pratiques à propos des installs :
|
||||
- pas d'upgrade
|
||||
- on clean les couches
|
||||
### 19
|
||||
Lorsqu'on a besoin de compiler un programme avant de le mettre dans un conteneur, pas besoin d'inclure le compilateur !
|
||||
### 20
|
||||
|
||||
|
||||
* volumes : une couche simple
|
||||
* bind mounts : partagés avec l'hôte
|
||||
|
||||
* volume-from : partage de volumes entre conteneurs
|
||||
|
||||
* tmpfs mounts : non persistant, uniquement dans la mémoire de l'hôte
|
||||
### 21
|
||||
Questions ?
|
||||
|
||||
- limiter les ressources
|
||||
- arrêter un conteneur
|
||||
- commandes détachées du terminal (-d) + docker logs
|
||||
### 22
|
||||
* Questionnaire sur Epitaf sur les notions de cours + recherches perso (pour éviter un partiel)
|
||||
* Demandez pour un partage de flux intéressants, d'articles cools sur le sujet, ...
|
||||
|
||||
* Rendus des exercices du TP + projet complémentaire par mail
|
||||
- signature PGP
|
||||
|
||||
* Correction au début du prochain cours => limite du rendu
|
||||
|
||||
* Sondage de satisfaction à la fin du cours : notez vos feedbacks !
|
Binary file not shown.
@ -1,146 +0,0 @@
|
||||
[file]
|
||||
2-docker advanced.pdf
|
||||
[skip]
|
||||
8,11,12,13,14,17,18,21,23,24,
|
||||
[notes]
|
||||
### 1
|
||||
Bonjour, aujourd'hui, on va continuer de découvrir Docker, et plus particulièrement : ce qui touche à l'orchestration.
|
||||
|
||||
Ça va, vous vous en êtes sorti avec le petit projet ?
|
||||
|
||||
C'est le dernier cours que l'on va faire sur Docker, donc le projet est un peu plus long.### 2
|
||||
Normalement, vous aviez des questions de cours à préparer sur Epitaf, on fera sans et on trouvera une solution pour la prochaine fois.
|
||||
|
||||
Du coup, peut-être que je vais donner plein de réponses durant ce cours, vous avez bien fait de venir y assister !
|
||||
|
||||
Commençons par faire un point sur les signatures PGP ....### 3
|
||||
Quelques statistiques qui parlent d'elles-même : seulement 7 d'entre-vous ont réussi à envoyer un mail sans se tromper. Bravo !
|
||||
|
||||
2 d'entre vous ne comprennent pas le fonctionnement des bi-clefs.
|
||||
=> pour signer, on chiffre un condensat du mail avec ... ? clef privée, pour que n'importe qui possédant la clef publique puisse faire l'op inverse
|
||||
=> pour chiffrer, on chiffre la clef de chiffrement symét. avec ... ? clef pub. du destinataire, car seule la clef privée pourra le déchiffrer.
|
||||
|
||||
Quels sont les algo qui fonctionnent comme ça ? RSA, et puis ?
|
||||
=> ECDSA, ED25519, ...
|
||||
|
||||
À propos de RSA, qui peut m'expliquer la vulnérabilité découverte lundi ?
|
||||
ROCA, Infineon, nitrokey 4, carte d'identitée estonienne, ...
|
||||
=====
|
||||
|
||||
Sylvio, qui m'a envoyé son certificat de révocation, à quoi ça sert un certif de révocation ?### 4
|
||||
Vous avez globalement tous eu du mal à partager votre clef publique.
|
||||
|
||||
Le plus simple était sans doute de l'envoyer sur un serveur de clef...### 5
|
||||
Si vous aimez la sécurité, venez rencontrer des gens dans les cryptoparties !
|
||||
|
||||
La prochaine chez Mozilla est annuelle, sur inscription et va ameuter beaucoup de monde.
|
||||
|
||||
Tous les mois, aux Halles, on parle sécurité informatique pendant 1h, en signant les gens qui viennent que ce soit PGP ou CAcert
|
||||
|
||||
Et plein d'autres événements organise souvent en parallèle des KSP### 6
|
||||
Est-ce que vous voulez savoir comment on signe une clef PGP ?
|
||||
|
||||
C'est un réseau de confiance, vous êtes entièrement responsable de la manière dont vous gérez votre réseau.
|
||||
Vous pouvez signer n'importe qui sans faire de vérification.
|
||||
Ce qui importe, c'est la confiance qu'on accorde aux gens que l'on signe. Est-ce que l'on souhaite leur accorder notre confiance pour étendre notre réseau ou pas ?
|
||||
|
||||
Une signature, ça se fait toujours en face à face. Avec une ou deux pièces d'identitées dont on sait valider l'authenticité.
|
||||
|
||||
Lorsque l'on valide la clef sur sa machine, il faut vérifier chaque chiffre de l'empreinte.
|
||||
|
||||
Les bonnes pratiques veulent que l'on renvoie la clef signée à son propriétaire qui choisi de publier ou non la signature.
|
||||
|
||||
Problème des métadonnées : cela expose nos connaissances### 7
|
||||
Il y avait une question sur Epitaf pourtant sur le nombre de couches que possédait votre image web server.
|
||||
|
||||
Ici donc, 4.
|
||||
|
||||
Comment on peut afficher explicitement le nombre de couches ?### 8
|
||||
Une autre question qui était posée :
|
||||
Est-ce que c'est mieux en haut où en bas ?
|
||||
|
||||
1 RUN = 1 couche
|
||||
|
||||
FROM plus précis en haut : ça a plus de chance de perdurer dans le temps
|
||||
|
||||
RUN inutile en bas, car la suppression ne supprimera pas les fichiers des couches précédentes### 9
|
||||
Est-ce que certains d'entre vous ont creusé pour savoir comment effectuer une action privilégiée sans être root, uniquement via Docker ?
|
||||
|
||||
--privileged
|
||||
|
||||
monté un volume de la racine et chroot dedans
|
||||
|
||||
utiliser le réseau de l'hote pour changer les interfaces
|
||||
|
||||
s'ajouter quelques capabilities sympa (on y reviendra la semaine prochaine)
|
||||
|
||||
seccomp : mécanisme de filtrage des syscall :
|
||||
- soit liste blanche,
|
||||
- soit liste noire.
|
||||
|
||||
Par défaut Docker : retire beaucoup de capabilities et limite les appels système, en particulier aux mécanismes qui ne sont pas isolés.### 10
|
||||
DEMO nanosleep### 11
|
||||
Pendant qu'on parle sécu, avez-vous regardé comment limiter l'usage CPU ou RAM avec Docker ?
|
||||
|
||||
CPU shares, n'est actif que si le CPU est à 100%, dans ce cas, le conteneur ne pourra s'en octroyer que la moitié au maximum par rapport aux autres processus.
|
||||
|
||||
Memory, facile, on peut aussi l'appliquer à la swap dans les versions récentes du noyau
|
||||
|
||||
PID limit, noyau récent aussi, on fait un test ?!
|
||||
### 12
|
||||
DEMO fork-bomb controlé### 13
|
||||
Voici le script qu'il fallait écrire, en gros, pour lancer owncloud
|
||||
|
||||
On crée un volume pour la base de données
|
||||
On lance la base de données avec ce volume et le pass root dans l'env
|
||||
|
||||
On crée un volume pour les données owncloud (dit dans le readme du cntr)
|
||||
On lance le conteneur lié au mysql => il hérite de l'env
|
||||
|
||||
Enfin, on fait un coup de docker inspect, format template Golang et voilà
|
||||
|
||||
=====
|
||||
|
||||
Je parlais de docker-compose, vous avez jeté un œil du coup ? c'est le sujet du TP aujourd'hui !
|
||||
|
||||
Voilà à quoi ça ressemble donc. on déclare des services, en YAML, et on les décrits : quels images, comment les builds, quelle politique de restart appliquer, quels ports exposer, comment les lier
|
||||
|
||||
DEMO un vrai ....### 14
|
||||
Image
|
||||
* modèle en lecture seule
|
||||
* utilisé pour créer des conteneurs
|
||||
|
||||
Conteneur
|
||||
* instance d'une image
|
||||
* isolé de tout de base, on règle après ce que l'on souhaite partager (réseau, stockage, ...)
|
||||
|
||||
Tâche (à partir d'un cluster)
|
||||
* une instance d'une image qui tourne pour un conteneur
|
||||
* propriétés très similaire aux conteneurs
|
||||
|
||||
Service (à partir d'un cluster)
|
||||
* un groupe de tâches partageant la même image
|
||||
|
||||
Stack (à partir d'un cluster)
|
||||
* un groupe de services, différents, formant un projet avec tous ses composants.### 15
|
||||
De plus en plus de nos jours, on a besoin de faire de l'orchestration :
|
||||
- bcp de serveur
|
||||
- bcp de conteneur
|
||||
aux carac. différentes
|
||||
=> certain + RAM, d'autre + CPU, + disque, ...
|
||||
|
||||
Faire la répartition à la main, n'est plus possible.
|
||||
|
||||
Mesos, Nomad, Kubernetes, Swarm, ...
|
||||
|
||||
Pendant le TP, on va passer un peu de temps sur Swarm.
|
||||
|
||||
À savoir qu'actuellement:
|
||||
Les bases de données ça se clusterise pas bien pour l'instant.### 16
|
||||
Dockerfile hello srs
|
||||
|
||||
À propos du linkage statique vs. dynamique### 17
|
||||
### 18
|
||||
C'est parti pour le TP !
|
||||
|
||||
Parler un peu des serveurs du FIC ?
|
Binary file not shown.
@ -1,4 +0,0 @@
|
||||
[file]
|
||||
4-linux internals.pdf
|
||||
[skip]
|
||||
5,8,9,10,11,12,14,
|
@ -3,7 +3,7 @@
|
||||
Une vision plus Clair de la sécurité
|
||||
====================================
|
||||
|
||||
Nous avons vu, au travers de tous les précédents TP, que Docker nous apportait
|
||||
Nous avons vu, au travers de nos TPs jusqu'à présent, que Docker nous apportait
|
||||
un certain degré de sécurité d'emblée au lancement du conteneur. Cela peut sans
|
||||
doute paraître quelque peu rassurant pour la personne chargée d'administrer la
|
||||
machine hébergeant les conteneurs, car cela lui apporte des garanties quant à
|
||||
@ -62,7 +62,7 @@ services:
|
||||
|
||||
clair:
|
||||
container_name: clair_clair
|
||||
image: quay.io/coreos/clair:v2.0.6
|
||||
image: quay.io/coreos/clair:v2.0.9
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- postgres
|
||||
@ -77,13 +77,29 @@ services:
|
||||
```
|
||||
</div>
|
||||
|
||||
Vous trouverez un exemple de configuration dans le [dépôt du
|
||||
projet](https://raw.githubusercontent.com/coreos/clair/master/config.yaml.sample). N'oubliez
|
||||
Prenez quelques minutes pour comprendre ce `docker-compose.yml` : notez la
|
||||
présence de la variable d'environnement `POSTGRES_PASSWORD`, non définie : ce
|
||||
sera la variable présente dans votre environnement, au moment du
|
||||
`docker-compose up` qui sera utilisée. N'oubliez pas de la définir :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
export POSTGRES_PASSWORD=$(openssl rand -base64 16)
|
||||
```
|
||||
</div>
|
||||
|
||||
Parmi les volumes partagés avec `clair`, il y a un dossier
|
||||
`./clair_config`. Notez le `./` au début, qui indique que le dossier sera
|
||||
recherché relativement par rapport à l'emplacement du `docker-compsose.yml`.
|
||||
|
||||
Dans ce dossier, vous devez placer un exemplaire du fichier de configuration
|
||||
dont un [exemple se trouve dans le dépôt du
|
||||
projet](https://raw.githubusercontent.com/coreos/clair/master/config.yaml.sample). **N'oubliez
|
||||
pas de changer le nom d'hôte et le mot de passe pour se connecter au conteneur
|
||||
de base de données.
|
||||
de base de données.**
|
||||
|
||||
Une fois lancé, la base nécessite d'être initialisée. L'opération peut prendre
|
||||
plusieurs minutes. Vous pouvez suivre l'avancement de l'ajout :
|
||||
plusieurs minutes. Vous pouvez suivre l'avancement de l'ajout via :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
@ -151,4 +167,4 @@ High: 4
|
||||
|
||||
Déterminez le nombre de vulnérabilités dans les principales images officielles
|
||||
du [Docker Hub](https://hub.docker.com/explore), notamment `nginx`, `golang`,
|
||||
`reddis`, ...
|
||||
`redis`, ...
|
||||
|
@ -1,3 +1,5 @@
|
||||
\newpage
|
||||
|
||||
Registres
|
||||
=========
|
||||
|
||||
@ -17,11 +19,10 @@ L'authentification est facultative et est laissée à l'appréciation du
|
||||
fournisseur de service. Étant donné que nous allons utiliser le [Docker
|
||||
Hub](https://hub.docker.com/), le registre par défaut de `docker`, nous allons
|
||||
devoir nous plier à leur mécanisme d'authentification : chaque requête au
|
||||
registre doivent être effectuées avec un jeton, que l'on obtient en
|
||||
s'authentifiant auprès d'un service dédié. Ce service peut délivrer un jeton
|
||||
sans authentifier l'interlocuteur, en restant anonyme ; dans ce cas, on ne
|
||||
pourra accéder qu'aux images publiques. Ça tombe bien, c'est ce qui nous
|
||||
intéresse aujourd'hui !
|
||||
registre doit être effectuée avec un jeton, que l'on obtient en s'authentifiant
|
||||
auprès d'un service dédié. Ce service peut délivrer un jeton sans authentifier
|
||||
l'interlocuteur, en restant anonyme ; dans ce cas, on ne pourra accéder qu'aux
|
||||
images publiques. Ça tombe bien, c'est ce qui nous intéresse aujourd'hui !
|
||||
|
||||
Il n'en reste pas moins que le jeton est forgé pour un service donné (dans
|
||||
notre cas `registry.docker.io`) et avec un objectif bien cerné (pour nous, on
|
||||
@ -34,7 +35,7 @@ souhaite récupérer le contenu du dépôt[^quiddepot] `hello-world` :
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
42sh$ curl "https://auth.docker.io/token?service=registry.docker.io&"\
|
||||
> "scope=repository:library/hello-world:pull" | jq .
|
||||
"scope=repository:library/hello-world:pull" | jq .
|
||||
```
|
||||
```json
|
||||
{
|
||||
@ -57,6 +58,12 @@ Avec `jq`, on peut l'extraire grâce à :
|
||||
```
|
||||
</div>
|
||||
|
||||
**Attention :** le token expire ! Pensez à le renouveler régulièrement.
|
||||
|
||||
En cas d'erreur inexplicable, vous pouvez ajouter un `-v` à la ligne de
|
||||
commande `curl`, afin d'afficher les en-têtes. Prêtez une attention toute
|
||||
particulière à `Www-Authenticate`.
|
||||
|
||||
|
||||
## Lecture de l'index d'images
|
||||
|
||||
@ -98,7 +105,9 @@ constater qu'il n'a bien qu'une seule couche, ouf !
|
||||
## Récupération de la configuration et de la première couche
|
||||
|
||||
Les deux éléments que l'on cherche à récupérer vont se trouver dans le
|
||||
répertoire `blobs`, il ne s'agit en effet plus de manifest. Si les manifests sont toujours stockés par le registre lui-même, les blobs peuvent être délégués à un autre service, par exemple dans le cloud, chez Amazon S3, un CDN, etc.
|
||||
répertoire `blobs`, il ne s'agit en effet plus de manifest. Si les manifests
|
||||
sont toujours stockés par le registre lui-même, les blobs peuvent être délégués
|
||||
à un autre service, par exemple dans le cloud, chez Amazon S3, un CDN, etc.
|
||||
|
||||
Pour récupérer la configuration de l'image :
|
||||
|
||||
@ -153,7 +162,7 @@ Réalisez un script pour automatiser l'ensemble de ces étapes :
|
||||
```bash
|
||||
42sh$ cd $(mktemp)
|
||||
|
||||
42sh$ ~/workspace/registry_play.sh library/hello-world
|
||||
42sh$ ~/workspace/registry_play.sh library/hello-world:latest
|
||||
|
||||
42sh$ find
|
||||
.
|
||||
@ -165,3 +174,6 @@ Hello from Docker!
|
||||
[...]
|
||||
```
|
||||
</div>
|
||||
|
||||
Pensez également à tester avec d'autres images, comme par exemple
|
||||
`nemunaire/youp0m`. Il vous faudra alors extraire plusieurs couches.
|
||||
|
@ -4,11 +4,10 @@
|
||||
======
|
||||
|
||||
`runc` est le programme qui est responsable de la création effective du
|
||||
conteneur : c'est lui qui va mettre en place les *namespaces*, les
|
||||
*capabilities*, les points de montages ou volumes, ... Attention, son rôle
|
||||
reste limité à la mise en place de l'environnement conteneurisé, ce n'est pas
|
||||
lui qui télécharge l'image, ni fait l'assemblage des couches de système de
|
||||
fichiers, entre autres.
|
||||
conteneur : c'est lui qui va mettre en place toute la machinerie, les points de
|
||||
montages ou volumes, ... Attention, son rôle reste limité à la mise en place de
|
||||
l'environnement conteneurisé, ce n'est pas lui qui télécharge l'image, ni fait
|
||||
l'assemblage des couches de système de fichiers, entre autres.
|
||||
|
||||
Aujourd'hui, le lancement de conteneur est faite avec `runc`, mais il est
|
||||
parfaitement possible d'utiliser n'importe quel autre programme à sa place, à
|
||||
@ -23,7 +22,7 @@ essayer de lancer un shell `alpine` avec un volume dans notre home.
|
||||
|
||||
Vous devriez avoir le binaire `runc` ou `docker-runc`. Si ce n'est pas le cas,
|
||||
vous pouvez télécharger la dernière version :
|
||||
<https://github.com/opencontainers/runc/releases>. La 1.0.0-rc5 est Ok.
|
||||
<https://github.com/opencontainers/runc/releases>. La 1.0.0-rc9 est Ok.
|
||||
|
||||
|
||||
## Extraction du rootfs
|
||||
@ -56,6 +55,9 @@ runc spec
|
||||
Pour savoir à quoi correspondent tous ces éléments, vous pouvez consulter :
|
||||
<https://github.com/opencontainers/runtime-spec/blob/master/config.md>
|
||||
|
||||
Nous verrons dans les prochains TP, plus en détails tout ce qui porte sur les
|
||||
*namespaces*, rassurez-vous, il n'y a que très peu de champs à modifier
|
||||
aujourd'hui.
|
||||
|
||||
## Test brut
|
||||
|
||||
@ -127,11 +129,22 @@ ajouter un élément à cette liste, demandant de *bind* :
|
||||
|
||||
## Exercice {-}
|
||||
|
||||
Serez-vous capable de continuer l'édition de votre `config.json` afin d'obtenir
|
||||
les mêmes restrictions que votre projet de moulette ?
|
||||
À vous maintenant d'éditer votre `config.json`, pour lancer le service youp0m.
|
||||
|
||||
* CGroups : 1\ GB RAM, 100\ PIDs, ...
|
||||
* strict minimum de capabilities ;
|
||||
* filtres `seccomp` ;
|
||||
* carte réseau `veth` ;
|
||||
* ...
|
||||
Dans un premier temps, assurez-vous de pouvoir télécharger et d'assembler
|
||||
rapidement les couches du conteneur.
|
||||
|
||||
À partir du fichier `config.json` fourni, adaptez la ligne de commande à lancer
|
||||
et le dossier courant par défaut (`cwd`). Pensez également à faire un volume
|
||||
entre un dossier de votre home (ou temporaire, peu importe), afin de pouvoir
|
||||
stocker les photos (dossier `/srv/images`)[^chmod].
|
||||
|
||||
[^chmod]: faites attention aux droits du dossier que vous partagez. Le plus
|
||||
simple pour l'instant serait d'attribuer les permissions `0777` à la
|
||||
source, temporairement.
|
||||
|
||||
Pour ce TP, considérez que vous avez réussi si vous voyez s'afficher :
|
||||
|
||||
> `Ready, listening on :8080`
|
||||
|
||||
Il faudra attendre les TP suivants pour avoir du réseau dans notre conteneur.
|
||||
|
@ -1,11 +0,0 @@
|
||||
/var/log/telegraf/telegraf.log
|
||||
{
|
||||
rotate 6
|
||||
daily
|
||||
missingok
|
||||
dateext
|
||||
copytruncate
|
||||
notifempty
|
||||
compress
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,208 +0,0 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
# chkconfig: 2345 99 01
|
||||
# description: Telegraf daemon
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: telegraf
|
||||
# Required-Start: $all
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start telegraf at boot time
|
||||
### END INIT INFO
|
||||
|
||||
# this init script supports three different variations:
|
||||
# 1. New lsb that define start-stop-daemon
|
||||
# 2. Old lsb that don't have start-stop-daemon but define, log, pidofproc and killproc
|
||||
# 3. Centos installations without lsb-core installed
|
||||
#
|
||||
# In the third case we have to define our own functions which are very dumb
|
||||
# and expect the args to be positioned correctly.
|
||||
|
||||
# Command-line options that can be set in /etc/default/telegraf. These will override
|
||||
# any config file values.
|
||||
TELEGRAF_OPTS=
|
||||
|
||||
USER=telegraf
|
||||
GROUP=telegraf
|
||||
|
||||
if [ -r /lib/lsb/init-functions ]; then
|
||||
source /lib/lsb/init-functions
|
||||
fi
|
||||
|
||||
DEFAULT=/etc/default/telegraf
|
||||
|
||||
if [ -r $DEFAULT ]; then
|
||||
source $DEFAULT
|
||||
fi
|
||||
|
||||
if [ -z "$STDOUT" ]; then
|
||||
STDOUT=/dev/null
|
||||
fi
|
||||
if [ ! -f "$STDOUT" ]; then
|
||||
mkdir -p `dirname $STDOUT`
|
||||
fi
|
||||
|
||||
if [ -z "$STDERR" ]; then
|
||||
STDERR=/var/log/telegraf/telegraf.log
|
||||
fi
|
||||
if [ ! -f "$STDERR" ]; then
|
||||
mkdir -p `dirname $STDERR`
|
||||
fi
|
||||
|
||||
OPEN_FILE_LIMIT=65536
|
||||
|
||||
function pidofproc() {
|
||||
if [ $# -ne 3 ]; then
|
||||
echo "Expected three arguments, e.g. $0 -p pidfile daemon-name"
|
||||
fi
|
||||
|
||||
if [ ! -f "$2" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local pidfile=`cat $2`
|
||||
|
||||
if [ "x$pidfile" == "x" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ps --pid "$pidfile" | grep -q $(basename $3); then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function killproc() {
|
||||
if [ $# -ne 3 ]; then
|
||||
echo "Expected three arguments, e.g. $0 -p pidfile signal"
|
||||
fi
|
||||
|
||||
pid=`cat $2`
|
||||
|
||||
kill -s $3 $pid
|
||||
}
|
||||
|
||||
function log_failure_msg() {
|
||||
echo "$@" "[ FAILED ]"
|
||||
}
|
||||
|
||||
function log_success_msg() {
|
||||
echo "$@" "[ OK ]"
|
||||
}
|
||||
|
||||
# Process name ( For display )
|
||||
name=telegraf
|
||||
|
||||
# Daemon name, where is the actual executable
|
||||
daemon=/usr/bin/telegraf
|
||||
|
||||
# pid file for the daemon
|
||||
pidfile=/var/run/telegraf/telegraf.pid
|
||||
piddir=`dirname $pidfile`
|
||||
|
||||
if [ ! -d "$piddir" ]; then
|
||||
mkdir -p $piddir
|
||||
chown $USER:$GROUP $piddir
|
||||
fi
|
||||
|
||||
# Configuration file
|
||||
config=/etc/telegraf/telegraf.conf
|
||||
confdir=/etc/telegraf/telegraf.d
|
||||
|
||||
# If the daemon is not there, then exit.
|
||||
[ -x $daemon ] || exit 5
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
# Checked the PID file exists and check the actual status of process
|
||||
if [ -e $pidfile ]; then
|
||||
pidofproc -p $pidfile $daemon > /dev/null 2>&1 && status="0" || status="$?"
|
||||
# If the status is SUCCESS then don't need to start again.
|
||||
if [ "x$status" = "x0" ]; then
|
||||
log_failure_msg "$name process is running"
|
||||
exit 0 # Exit
|
||||
fi
|
||||
fi
|
||||
|
||||
# Bump the file limits, before launching the daemon. These will carry over to
|
||||
# launched processes.
|
||||
ulimit -n $OPEN_FILE_LIMIT
|
||||
if [ $? -ne 0 ]; then
|
||||
log_failure_msg "set open file limit to $OPEN_FILE_LIMIT"
|
||||
fi
|
||||
|
||||
log_success_msg "Starting the process" "$name"
|
||||
if which start-stop-daemon > /dev/null 2>&1; then
|
||||
start-stop-daemon --chuid $USER:$GROUP --start --quiet --pidfile $pidfile --exec $daemon -- -pidfile $pidfile -config $config -config-directory $confdir $TELEGRAF_OPTS >>$STDOUT 2>>$STDERR &
|
||||
else
|
||||
su -s /bin/sh -c "nohup $daemon -pidfile $pidfile -config $config -config-directory $confdir $TELEGRAF_OPTS >>$STDOUT 2>>$STDERR &" $USER
|
||||
fi
|
||||
log_success_msg "$name process was started"
|
||||
;;
|
||||
|
||||
stop)
|
||||
# Stop the daemon.
|
||||
if [ -e $pidfile ]; then
|
||||
pidofproc -p $pidfile $daemon > /dev/null 2>&1 && status="0" || status="$?"
|
||||
if [ "$status" = 0 ]; then
|
||||
if killproc -p $pidfile SIGTERM && /bin/rm -rf $pidfile; then
|
||||
log_success_msg "$name process was stopped"
|
||||
else
|
||||
log_failure_msg "$name failed to stop service"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_failure_msg "$name process is not running"
|
||||
fi
|
||||
;;
|
||||
|
||||
reload)
|
||||
# Reload the daemon.
|
||||
if [ -e $pidfile ]; then
|
||||
pidofproc -p $pidfile $daemon > /dev/null 2>&1 && status="0" || status="$?"
|
||||
if [ "$status" = 0 ]; then
|
||||
if killproc -p $pidfile SIGHUP; then
|
||||
log_success_msg "$name process was reloaded"
|
||||
else
|
||||
log_failure_msg "$name failed to reload service"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_failure_msg "$name process is not running"
|
||||
fi
|
||||
;;
|
||||
|
||||
restart)
|
||||
# Restart the daemon.
|
||||
$0 stop && sleep 2 && $0 start
|
||||
;;
|
||||
|
||||
status)
|
||||
# Check the status of the process.
|
||||
if [ -e $pidfile ]; then
|
||||
if pidofproc -p $pidfile $daemon > /dev/null; then
|
||||
log_success_msg "$name Process is running"
|
||||
exit 0
|
||||
else
|
||||
log_failure_msg "$name Process is not running"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log_failure_msg "$name Process is not running"
|
||||
exit 3
|
||||
fi
|
||||
;;
|
||||
|
||||
version)
|
||||
$daemon version
|
||||
;;
|
||||
|
||||
*)
|
||||
# For invalid arguments, print the usage message.
|
||||
echo "Usage: $0 {start|stop|restart|status|version}"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
@ -1,17 +0,0 @@
|
||||
[Unit]
|
||||
Description=The plugin-driven server agent for reporting metrics into InfluxDB
|
||||
Documentation=https://github.com/influxdata/telegraf
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=-/etc/default/telegraf
|
||||
User=telegraf
|
||||
Environment='STDOUT=/var/log/telegraf/telegraf.log'
|
||||
Environment='STDERR=/var/log/telegraf/telegraf.log'
|
||||
ExecStart=/bin/sh -c "exec /usr/bin/telegraf -config /etc/telegraf/telegraf.conf -config-directory /etc/telegraf/telegraf.d ${TELEGRAF_OPTS} >>${STDOUT} 2>>${STDERR}"
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=on-failure
|
||||
KillMode=control-group
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -41,6 +41,7 @@ constater l'existence de notre éditeur favori :
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
docker container run -it my_editor /bin/bash
|
||||
(in_cntr)# nano
|
||||
```
|
||||
</div>
|
||||
|
||||
@ -63,9 +64,9 @@ RUN mysql -u root -p toor virli < /db.sql
|
||||
Cet exemple ne fonctionne pas car le serveur MySQL est bien lancé dans le
|
||||
premier `RUN`{.dockerfile}, mais il se trouve brûtalement arrêté dès lors que
|
||||
la commande `service` se termine. En fait, à chaque instruction, Docker réalise
|
||||
automatiquement un `run` suivi d'un `commit`. Et vous pouvez constater par
|
||||
vous-même que, en créant l'image `tinysql` à partir d'un simple `apt install
|
||||
mysql` :
|
||||
automatiquement l'équivalent un `docker run` suivi d'un `commit`. Et vous
|
||||
pouvez constater par vous-même que, en créant l'image `tinysql` à partir d'un
|
||||
simple `apt install mysql` :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
@ -108,9 +109,9 @@ EXPOSE 80
|
||||
```
|
||||
</div>
|
||||
|
||||
L'instruction `EXPOSE`{.dockerfile} sera traitée plus tard par le client Docker (équivalent
|
||||
à l'argument `--expose`). Il s'agit d'une métadonnée qui sera attachée à
|
||||
l'image (et à toutes ses images filles).
|
||||
L'instruction `EXPOSE`{.dockerfile} sera traitée plus tard par le client Docker
|
||||
(équivalent à l'argument `--expose`). Il s'agit d'une métadonnée qui sera
|
||||
attachée à l'image (et à toutes ses images filles).
|
||||
|
||||
En précisant tous les ports qu'exposent une image dans ses métadonnées, ces
|
||||
ports seront automatiquement exposés en utilisant l'option `-P` du `run` : cela
|
||||
@ -317,9 +318,9 @@ Pour compiler le projet, vous pouvez utiliser dans votre `Dockerfile`
|
||||
|
||||
<div lang="en-US">
|
||||
```dockerfile
|
||||
FROM golang:1.11
|
||||
FROM golang:1.13
|
||||
COPY . /go/src/git.nemunai.re/youp0m
|
||||
WORKDIR /go/src/git.nemunai.re/youp0m
|
||||
RUN go build -v
|
||||
RUN go build -tags dev -v
|
||||
```
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@ Personnalisation du point d'entrée du conteneur
|
||||
## Point d'entrée basique
|
||||
|
||||
Afin de faire bénéficier à nos utilisateurs d'une immersion parfaite, nous
|
||||
allons faire en sorte que notre image permette d'être utilisée ainsi :
|
||||
allons faire en sorte que notre image puisse être utilisée ainsi :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
|
@ -156,7 +156,7 @@ L'entrypoint peut être utilisé de deux manières différentes :
|
||||
<div lang="en-US">
|
||||
```dockerfile
|
||||
ENTRYPOINT ["nginx"]
|
||||
CMD ["-g daemon off;"]
|
||||
CMD ["-g", "daemon", "off;"]
|
||||
```
|
||||
</div>
|
||||
|
||||
@ -190,7 +190,7 @@ exec "$@"
|
||||
Les instructions `ENTRYPOINT`{.dockerfile} et `CMD`{.dockerfile} peuvent
|
||||
prendre deux formes :
|
||||
|
||||
- `["cmd", "arg1", "arg2"]` : ici, un simple `exexve` sera effectué avec ces
|
||||
- `["cmd", "arg1", "arg2"]` : ici, un simple `execve` sera effectué avec ces
|
||||
arguments. Si d'éventuels variables se trouve dans les arguments, elles ne
|
||||
seront pas remplacées.
|
||||
- `cmd arg1 arg2` : ici l'exécution se fera au sein d'un `sh -c`, donc les
|
||||
|
@ -25,7 +25,7 @@ apt-get update
|
||||
</div>
|
||||
|
||||
Il peut arriver que des paquets présents dans l'image ne soient pas à
|
||||
jour. Afin de garder un environnement cohérent, il est recommandé de ne pas
|
||||
jour. Afin de garder un environnement cohérent, il est recommandé de **ne pas**
|
||||
utiliser le gestionnaire de paquets pour mettre à jour les paquets présents de
|
||||
base, mais plutôt de contacter le mainteneur de l'image pour qu'il la mette à
|
||||
jour.
|
||||
@ -54,7 +54,14 @@ en remplaçant `CONTAINER` par le nom ou l'identifiant du container qui
|
||||
doit servir de modèle. `my_nano` est le nom que vous voudrez utiliser
|
||||
à la place d'`ubuntu`.
|
||||
|
||||
Testons sans plus attendre notre nouvelle image :
|
||||
|
||||
Cette action va figer la couche la plus haute de systèmes de fichiers, qui
|
||||
était jusqu'alors en lecture-écriture pour le conteneur ; afin d'en faire la
|
||||
dernière couche de notre nouvelle image.
|
||||
|
||||
![`docker commit`](commit.png)
|
||||
|
||||
Testons alors sans plus attendre notre nouvelle image :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
|
@ -46,8 +46,8 @@ une attention particulière au suivi des bonnes pratiques d'écriture des
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
42sh$ docker build -t countdown countdown
|
||||
42sh$ docker run -d -P countdown
|
||||
42sh$ docker image build -t countdown countdown
|
||||
42sh$ docker container run -d -P countdown
|
||||
42sh$ firefox http://localhost:32198/42:23
|
||||
```
|
||||
</div>
|
||||
@ -69,7 +69,7 @@ envoyé à une autre adresse et/ou non signé et/ou reçu après la correction n
|
||||
sera pas pris en compte.
|
||||
|
||||
Par ailleurs, n'oubliez pas de répondre à
|
||||
[l'évaluation du cours](https://www.epitaf.fr/moodle/mod/quiz/view.php?id=215).
|
||||
[l'évaluation du cours](https://www.epitaf.fr/moodle/mod/quiz/view.php?id=307).
|
||||
|
||||
|
||||
Tarball
|
||||
|
@ -3,7 +3,7 @@ title: Virtualisation légère -- TP n^o^ 2.1
|
||||
subtitle: Construire des images Docker
|
||||
author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
|
||||
institute: EPITA
|
||||
date: Jeudi 18 octobre 2018
|
||||
date: Mercredi 16 octobre 2019
|
||||
abstract: |
|
||||
Durant ce deuxième TP, nous allons voir comment créer nos propres
|
||||
images !
|
||||
@ -11,7 +11,7 @@ abstract: |
|
||||
\vspace{1em}
|
||||
|
||||
Tous les éléments de ce TP (exercices et projet) sont à rendre à
|
||||
<virli@nemunai.re> au plus tard le mercredi 24 octobre 2018 à 0
|
||||
<virli@nemunai.re> au plus tard le mercredi 23 octobre 2019 à 13
|
||||
h 42. Consultez la dernière section de chaque partie pour plus
|
||||
d'information sur les éléments à rendre.
|
||||
|
||||
|
@ -25,6 +25,9 @@
|
||||
|
||||
\usepackage{etoolbox}
|
||||
|
||||
% Declare coloredbox
|
||||
\newcommand{\coloredbox}[2]{#2}
|
||||
|
||||
\makeatletter
|
||||
\pretocmd{\subsection}{\addtocontents{toc}{\protect\addvspace{-5\p@}}}{}{}
|
||||
\pretocmd{\subsubsection}{\addtocontents{toc}{\protect\addvspace{-6\p@}}}{}{}
|
||||
|
@ -32,7 +32,7 @@ Obtenir l'application
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
git clone git://git.nemunai.re/chocominer.git
|
||||
git clone https://git.nemunai.re/chocominer.git
|
||||
```
|
||||
</div>
|
||||
|
||||
|
@ -81,8 +81,8 @@ Lançons les images standards
|
||||
#### `influxdb` et `chronograf`
|
||||
|
||||
```bash
|
||||
kubectl create deployment influxdb --image=influxdb
|
||||
kubectl create deployment chronograf --image=chronograf
|
||||
kubectl apply -f https://virli.nemunai.re/influxdb.yaml
|
||||
```
|
||||
|
||||
#### Notre application
|
||||
@ -100,7 +100,7 @@ Pour trois des applications, des ClusterIP font l'affaire, car ils n'ont pas
|
||||
besoin d'être exposés en dehors du cluster.
|
||||
|
||||
```bash
|
||||
kubectl expose deployment influxdb --port 8088
|
||||
kubectl expose deployment influxdb --port 8086
|
||||
kubectl expose deployment rng --port 80
|
||||
kubectl expose deployment hasher --port 80
|
||||
```
|
||||
|
@ -1,10 +1,10 @@
|
||||
PANDOCOPTS = --pdf-engine=xelatex \
|
||||
PANDOCOPTS = --pdf-engine=lualatex \
|
||||
--standalone \
|
||||
--number-sections \
|
||||
--toc \
|
||||
-f markdown+smart \
|
||||
-M fontsize=12pt \
|
||||
-M papersize=a4paper \
|
||||
-M papersize=a4 \
|
||||
-M mainfont="Linux Libertine O" \
|
||||
-M monofont="FantasqueSansMono-Regular" \
|
||||
-M sansfont="Linux Biolinum O" \
|
||||
@ -13,4 +13,5 @@ PANDOCOPTS = --pdf-engine=xelatex \
|
||||
-M urlcolor="ForestGreen" \
|
||||
-M indent=true \
|
||||
-V toc-title="Sommaire" \
|
||||
--include-in-header=../header.tex
|
||||
-V pdfa \
|
||||
--include-in-header=../../tutorial/header.tex
|
||||
|
Loading…
Reference in New Issue
Block a user