2020 done

This commit is contained in:
nemunaire 2020-09-14 15:46:13 +02:00
parent fafac06b23
commit a75f4b43b7
25 changed files with 113 additions and 2498 deletions

View file

@ -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`, ...

View file

@ -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.

View file

@ -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.

View file

@ -1,11 +0,0 @@
/var/log/telegraf/telegraf.log
{
rotate 6
daily
missingok
dateext
copytruncate
notifempty
compress
}

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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@}}}{}{}

View file

@ -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>

View file

@ -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
```

View file

@ -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