Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
3d19dc71be | |||
da48300a6c | |||
c2fb8e9799 | |||
394091338f | |||
4e58219ba8 | |||
a4bf192c12 | |||
01882ae09e |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "demo"]
|
||||||
|
path = demo
|
||||||
|
url = git@git.nemunai.re:teach/virli-demo.git
|
1
demo
Submodule
1
demo
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit fff9e75e0a2cfdb5f1d6ad0b2c17110750bcc62b
|
@ -1,23 +1,38 @@
|
|||||||
Utiliser l'API de Docker
|
Utiliser l'API de Docker
|
||||||
========================
|
========================
|
||||||
|
|
||||||
Le Docker Engine expose une API REST sur le protocole HTTP. Comme première
|
Le Docker Engine expose une API REST sur le protocole HTTP. Le client `docker`
|
||||||
tentative, vous pouvez essayer de récupérer des informations générales avec un
|
utilise cette API pour communiquer avec le daemon. C'est aussi cette même API
|
||||||
simple `curl` :
|
que `docker-compose` emploie. En fait n'importe quel programme peut en faire
|
||||||
|
usage, c'est d'ailleurs très simple d'utilisation.
|
||||||
|
|
||||||
|
Si vous n'avez jamais communiqué avec une API REST, voici un premier exemple
|
||||||
|
pour récupérer des informations générales sur le daemon Docker avec un simple
|
||||||
|
`curl` :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
curl -s --unix-socket /var/run/docker.sock http://localhost/v1.38/info | jq .
|
curl -s --unix-socket /var/run/docker.sock http://localhost/v1.38/info | jq .
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
On retrouve un objet JSON contenant des informations similaires à ce que l'on
|
On utilise l'option `--unix-socket` de `curl` car on ne se connecte pas
|
||||||
obtient avec un `docker info`.
|
directement à un port, comme c'est le cas habituellement avec le protocole
|
||||||
|
HTTP. Bien évidemment lorsque le daemon Docker se trouve sur une machine
|
||||||
|
distante (dans le cas de Docker Desktop sur Windows et Mac), on utilise l'IP et
|
||||||
|
le port de la machine distance.
|
||||||
|
|
||||||
|
Le premier élément dans le chemin de l'URL (`/v1.38/`) correspond à la version
|
||||||
|
de l'API que l'on souhaite utiliser. Celle-ci change dès que des
|
||||||
|
fonctionnalités sont ajoutées, à l'occasion d'une nouvelle version. Il n'est
|
||||||
|
généralement pas nécessaire de mettre à jour cette version dans les programmes
|
||||||
|
que vous développez car l'API est rétro-compatible : les anciennes versions de
|
||||||
|
l'API restent accessibles.
|
||||||
|
|
||||||
|
La commande que l'on a lancé nous retourne un objet JSON contenant des
|
||||||
|
informations similaires à ce que l'on obtient avec un `docker info`. L'avantage
|
||||||
|
est ici de pouvoir effectuer un traitement programmatique de ces informations.
|
||||||
|
|
||||||
Le premier élément dans le chemin de l'URL correspond à la version de l'API que
|
|
||||||
l'on souhaite utiliser. Celle-ci change dès que des fonctionnalités sont
|
|
||||||
ajoutées, à l'occasion d'une nouvelle version. Il n'est généralement pas
|
|
||||||
nécessaire de mettre à jour cette version dans les programmes que vous
|
|
||||||
développez car l'API est rétro-compatible : les anciennes versions de l'API
|
|
||||||
restent accessibles.
|
|
||||||
|
|
||||||
Pour réaliser cet exercice, vous pouvez utiliser le langage de votre choix, en
|
Pour réaliser cet exercice, vous pouvez utiliser le langage de votre choix, en
|
||||||
utilisant des outils ou des bibliothèques cohérents avec l'objectif recherché :
|
utilisant des outils ou des bibliothèques cohérents avec l'objectif recherché :
|
||||||
|
@ -5,8 +5,10 @@ Docker) qui pour un conteneur donné :
|
|||||||
|
|
||||||
1. détecte si le conteneur exécute une image disposant d'une mise à jour ;
|
1. détecte si le conteneur exécute une image disposant d'une mise à jour ;
|
||||||
1. cherche à récupérer la dernière image disponible ;
|
1. cherche à récupérer la dernière image disponible ;
|
||||||
1. mette à jour le contneur ;
|
1. met à jour le conteneur.
|
||||||
1. dans un conteneur, automatiquement pour toutes les images.
|
|
||||||
|
Enfin, pour simplifier son utilisation régulière, vous conceverez une image de
|
||||||
|
conteneur minimaliste.
|
||||||
|
|
||||||
## Étape 1 : Lister les conteneurs
|
## Étape 1 : Lister les conteneurs
|
||||||
|
|
||||||
@ -33,7 +35,7 @@ optimistic_meninsky
|
|||||||
|
|
||||||
Écrivez un `Dockerfile` pour conteneuriser ce programme : gérer tant la
|
Écrivez un `Dockerfile` pour conteneuriser ce programme : gérer tant la
|
||||||
construction (s'il y a des étapes de construction) que l'exécution. En
|
construction (s'il y a des étapes de construction) que l'exécution. En
|
||||||
utilisant les bonnes pratiques vues en cours.
|
utilisant les bonnes pratiques que nous avons pu voir.
|
||||||
|
|
||||||
### Exemple d'exécution {-}
|
### Exemple d'exécution {-}
|
||||||
|
|
||||||
@ -104,7 +106,7 @@ suivant si (0) aucune mise à jour de l'image n'est disponible, respectivement
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
N'hésitez pas à utiliser la sortie d'erreur et la sortie standard pour afficher
|
N'hésitez pas à utiliser la sortie d'erreur et la sortie standard pour afficher
|
||||||
des informations pour vous. Celles-ci ne seront pas vérifiées.
|
des informations de débogage pour vous.
|
||||||
|
|
||||||
::::: {.warning}
|
::::: {.warning}
|
||||||
|
|
||||||
@ -112,10 +114,11 @@ des informations pour vous. Celles-ci ne seront pas vérifiées.
|
|||||||
|
|
||||||
Par *image à jour*, on entend : « aligné par rapport à l'image du
|
Par *image à jour*, on entend : « aligné par rapport à l'image du
|
||||||
registre ». On ne s'intéresse pas à la date de construction ou de récupération
|
registre ». On ne s'intéresse pas à la date de construction ou de récupération
|
||||||
de l'image, mais uniquement à son identifiant. Si l'image sur laquelle se base
|
de l'image, mais uniquement à son identifiant. En bref : si l'image sur
|
||||||
un conteneur en cours d'exécution n'a pas le même identifiant que l'image du
|
laquelle se base un conteneur en cours d'exécution n'a pas le même identifiant
|
||||||
même tag dans le cache d'images, alors on considère que le conteneur doit être
|
que l'image du même tag dans le cache d'images, alors on considère que le
|
||||||
redémarré (même si la construction ou la récupération est antérieure).\
|
conteneur doit être redémarré (même si la construction ou la récupération est
|
||||||
|
antérieure).\
|
||||||
|
|
||||||
Attention, on souhaite rester sur **le même tag** que celui avec lequel on a
|
Attention, on souhaite rester sur **le même tag** que celui avec lequel on a
|
||||||
démarré le conteneur. Il ne s'agit pas de trouver un tag plus récent.
|
démarré le conteneur. Il ne s'agit pas de trouver un tag plus récent.
|
||||||
@ -135,7 +138,7 @@ plus souvent que les autres tags.
|
|||||||
|
|
||||||
## Étape 3 : Chercher une mise à jour l'image
|
## Étape 3 : Chercher une mise à jour l'image
|
||||||
|
|
||||||
En ajoutant l'option `--pull`, votre programme va lancer un pull de l'image
|
En ajoutant l'option `--pull`, votre programme va lancer un *pull* de l'image
|
||||||
avant de faire la vérification.
|
avant de faire la vérification.
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
@ -154,16 +157,24 @@ avant de faire la vérification.
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
::::: {.question}
|
||||||
|
|
||||||
L'image `youp0m` est mise à jour régulièrement. Il y a de forte chance pour
|
L'image `youp0m` est mise à jour régulièrement. Il y a de forte chance pour
|
||||||
qu'elle ne soit plus à jour si celle dont vous disposez date de plus d'une
|
qu'elle ne soit plus à jour si celle dont vous disposez date de plus d'une
|
||||||
semaine. Si vous possédez déjà la dernière version de vos conteneurs,
|
semaine. Si vous possédez déjà la dernière version de vos conteneurs,
|
||||||
recherchez une image sur le Docker Hub régulièrement mise à jour pour faire vos
|
recherchez une image sur le Docker Hub régulièrement mise à jour pour faire vos
|
||||||
tests.
|
tests.
|
||||||
|
|
||||||
Attention une fois l'image *pull* par `ctr-updater`, un appel à nouveau à
|
:::::
|
||||||
`ctr-updater` sans `--pull` retourne la mise à jour, car le `pull` précédent
|
|
||||||
|
::::: {.warning}
|
||||||
|
|
||||||
|
Une fois l'image *pull* par `ctr-updater`, un nouvel appel à `ctr-updater` sans
|
||||||
|
`--pull` indiquera qu'une mise à jour est disponible, car le `pull` précédent
|
||||||
aura téléchargé localement l'image.
|
aura téléchargé localement l'image.
|
||||||
|
|
||||||
|
:::::
|
||||||
|
|
||||||
::::: {.question}
|
::::: {.question}
|
||||||
|
|
||||||
#### Comment tester lorsqu'on a `pull` toutes ses images ? {-}
|
#### Comment tester lorsqu'on a `pull` toutes ses images ? {-}
|
||||||
|
209
template.tex
209
template.tex
@ -1,209 +0,0 @@
|
|||||||
\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$lang$,$endif$$if(papersize)$$papersize$,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$}
|
|
||||||
\usepackage[T1]{fontenc} % font encoding
|
|
||||||
\usepackage{euler} % math font (must be loaded before fontspec)
|
|
||||||
\usepackage{tabularx} % arrays with paragraph-like cells
|
|
||||||
\usepackage[table]{xcolor} % colors
|
|
||||||
\usepackage{tikz} % graphics
|
|
||||||
\usepackage{float} % improve floating figures and tables
|
|
||||||
\usepackage{titlesec} % must be loaded BEFORE hyperref!
|
|
||||||
\usepackage{graphicx} % pictures inclusion
|
|
||||||
\usepackage{listings} % source code environments and inclusion
|
|
||||||
\usepackage{fancybox} % boxes
|
|
||||||
\usepackage{textcomp} % more symbols
|
|
||||||
\usepackage{pifont} % even more symbols (with \ding)
|
|
||||||
\usepackage{amsmath,amsfonts} % math symbols and environments
|
|
||||||
\usepackage{calc} % operations on lengths
|
|
||||||
\usepackage{booktabs} % better tables
|
|
||||||
\usepackage{multirow} % tabular cells spanning multiple rows
|
|
||||||
\usepackage{ifthen} % if-then-else construct
|
|
||||||
\usepackage{enumitem} % list customization
|
|
||||||
\usepackage{sectsty} % section-title customization
|
|
||||||
\usepackage{ifxetex,ifluatex}
|
|
||||||
\usepackage{setspace} % set space amount between lines
|
|
||||||
\usepackage[cm]{fullpage} % don't waste space around pages
|
|
||||||
\usepackage{longtable}
|
|
||||||
\usepackage{fixltx2e} % provides \textsubscript
|
|
||||||
% use upquote if available, for straight quotes in verbatim environments
|
|
||||||
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
|
|
||||||
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
|
|
||||||
\usepackage[utf8]{inputenc}
|
|
||||||
$if(euro)$
|
|
||||||
\usepackage{eurosym}
|
|
||||||
$endif$
|
|
||||||
\else % if luatex or xelatex
|
|
||||||
\ifxetex
|
|
||||||
\usepackage{mathspec}
|
|
||||||
\usepackage{xltxtra,xunicode}
|
|
||||||
\else
|
|
||||||
\usepackage{fontspec}
|
|
||||||
\fi
|
|
||||||
\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
|
|
||||||
\newcommand{\euro}{€}
|
|
||||||
$if(mainfont)$
|
|
||||||
\setmainfont{$mainfont$}
|
|
||||||
$endif$
|
|
||||||
$if(sansfont)$
|
|
||||||
\setsansfont{$sansfont$}
|
|
||||||
$endif$
|
|
||||||
$if(monofont)$
|
|
||||||
\setmonofont[Mapping=tex-ansi]{$monofont$}
|
|
||||||
$endif$
|
|
||||||
$if(mathfont)$
|
|
||||||
\setmathfont(Digits,Latin,Greek){$mathfont$}
|
|
||||||
$endif$
|
|
||||||
\fi
|
|
||||||
\setmainfont[Ligatures={Common,Rare}]{LinLibertine}
|
|
||||||
\setsansfont[Ligatures=Common]{LinBiolinum}
|
|
||||||
\setmonofont{Inconsolata}
|
|
||||||
\linepenalty=100
|
|
||||||
\allsectionsfont{\color{black}}
|
|
||||||
\setlist{itemsep=1pt,topsep=2pt,partopsep=0pt,parsep=0pt,leftmargin=20pt}
|
|
||||||
|
|
||||||
\titlespacing{\section}{0pt}{2.5em}{0.66em}
|
|
||||||
\titlespacing{\subsection}{0pt}{1.5em}{0.5em}
|
|
||||||
\titlespacing{\subsubsection}{0pt}{1em}{0.4em}
|
|
||||||
\titlespacing{\paragraph}{0pt}{2ex}{1.2ex}
|
|
||||||
|
|
||||||
% use microtype if available
|
|
||||||
\IfFileExists{microtype.sty}{\usepackage{microtype}}{}
|
|
||||||
$if(geometry)$
|
|
||||||
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
|
|
||||||
$endif$
|
|
||||||
$if(natbib)$
|
|
||||||
\usepackage{natbib}
|
|
||||||
\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}
|
|
||||||
$endif$
|
|
||||||
$if(biblatex)$
|
|
||||||
\usepackage{biblatex}
|
|
||||||
$if(biblio-files)$
|
|
||||||
\bibliography{$biblio-files$}
|
|
||||||
$endif$
|
|
||||||
$endif$
|
|
||||||
$if(listings)$
|
|
||||||
\usepackage{listings}
|
|
||||||
$endif$
|
|
||||||
$if(lhs)$
|
|
||||||
\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
|
|
||||||
$endif$
|
|
||||||
$if(highlighting-macros)$
|
|
||||||
$highlighting-macros$
|
|
||||||
$endif$
|
|
||||||
$if(verbatim-in-note)$
|
|
||||||
\usepackage{fancyvrb}
|
|
||||||
$endif$
|
|
||||||
$if(tables)$
|
|
||||||
\usepackage{longtable}
|
|
||||||
$endif$
|
|
||||||
$if(graphics)$
|
|
||||||
\usepackage{graphicx}
|
|
||||||
% Redefine \includegraphics so that, unless explicit options are
|
|
||||||
% given, the image width will not exceed the width of the page.
|
|
||||||
% Images get their normal width if they fit onto the page, but
|
|
||||||
% are scaled down if they would overflow the margins.
|
|
||||||
\makeatletter
|
|
||||||
\def\ScaleIfNeeded{%
|
|
||||||
\ifdim\Gin@nat@width>\linewidth
|
|
||||||
\linewidth
|
|
||||||
\else
|
|
||||||
\Gin@nat@width
|
|
||||||
\fi
|
|
||||||
}
|
|
||||||
\makeatother
|
|
||||||
\let\Oldincludegraphics\includegraphics
|
|
||||||
{%
|
|
||||||
\catcode`\@=11\relax%
|
|
||||||
\gdef\includegraphics{\@ifnextchar[{\Oldincludegraphics}{\Oldincludegraphics[width=\ScaleIfNeeded]}}%
|
|
||||||
}%
|
|
||||||
$endif$
|
|
||||||
\ifxetex
|
|
||||||
\usepackage[setpagesize=false, % page size defined by xetex
|
|
||||||
unicode=false, % unicode breaks when used with xetex
|
|
||||||
xetex]{hyperref}
|
|
||||||
\else
|
|
||||||
\usepackage[unicode=true]{hyperref}
|
|
||||||
\fi
|
|
||||||
\hypersetup{breaklinks=true,
|
|
||||||
bookmarks=true,
|
|
||||||
pdfauthor={$author-meta$},
|
|
||||||
pdftitle={$title-meta$},
|
|
||||||
colorlinks=true,
|
|
||||||
citecolor=$if(citecolor)$$citecolor$$else$blue$endif$,
|
|
||||||
urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,
|
|
||||||
linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$,
|
|
||||||
pdfborder={0 0 0}}
|
|
||||||
\urlstyle{same} % don't use monospace font for urls
|
|
||||||
$if(links-as-notes)$
|
|
||||||
% Make links footnotes instead of hotlinks:
|
|
||||||
\renewcommand{\href}[2]{#2\footnote{\url{#1}}}
|
|
||||||
$endif$
|
|
||||||
$if(strikeout)$
|
|
||||||
\usepackage[normalem]{ulem}
|
|
||||||
% avoid problems with \sout in headers with hyperref:
|
|
||||||
\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
|
|
||||||
$endif$
|
|
||||||
\setlength{\parskip}{6pt plus 2pt minus 1pt}
|
|
||||||
\setlength{\emergencystretch}{3em} % prevent overfull lines
|
|
||||||
$if(numbersections)$
|
|
||||||
\setcounter{secnumdepth}{5}
|
|
||||||
$else$
|
|
||||||
\setcounter{secnumdepth}{0}
|
|
||||||
$endif$
|
|
||||||
$if(verbatim-in-note)$
|
|
||||||
\VerbatimFootnotes % allows verbatim text in footnotes
|
|
||||||
$endif$
|
|
||||||
$if(lang)$
|
|
||||||
\usepackage[$lang$]{babel}
|
|
||||||
$endif$
|
|
||||||
$for(header-includes)$
|
|
||||||
$header-includes$
|
|
||||||
$endfor$
|
|
||||||
|
|
||||||
$if(title)$
|
|
||||||
\title{$title$}
|
|
||||||
$endif$
|
|
||||||
$if(subtitle)$
|
|
||||||
\subtitle{$subtitle$}
|
|
||||||
$endif$
|
|
||||||
\author{$for(author)$$author$$sep$ \and $endfor$}
|
|
||||||
\date{$date$}
|
|
||||||
|
|
||||||
\begin{document}
|
|
||||||
$if(title)$
|
|
||||||
\maketitle
|
|
||||||
$endif$
|
|
||||||
|
|
||||||
$for(include-before)$
|
|
||||||
$include-before$
|
|
||||||
|
|
||||||
$endfor$
|
|
||||||
$if(toc)$
|
|
||||||
{
|
|
||||||
\hypersetup{linkcolor=black}
|
|
||||||
\setcounter{tocdepth}{$toc-depth$}
|
|
||||||
\tableofcontents
|
|
||||||
}
|
|
||||||
$endif$
|
|
||||||
$body$
|
|
||||||
|
|
||||||
$if(natbib)$
|
|
||||||
$if(biblio-files)$
|
|
||||||
$if(biblio-title)$
|
|
||||||
$if(book-class)$
|
|
||||||
\renewcommand\bibname{$biblio-title$}
|
|
||||||
$else$
|
|
||||||
\renewcommand\refname{$biblio-title$}
|
|
||||||
$endif$
|
|
||||||
$endif$
|
|
||||||
\bibliography{$biblio-files$}
|
|
||||||
|
|
||||||
$endif$
|
|
||||||
$endif$
|
|
||||||
$if(biblatex)$
|
|
||||||
\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
|
|
||||||
|
|
||||||
$endif$
|
|
||||||
$for(include-after)$
|
|
||||||
$include-after$
|
|
||||||
|
|
||||||
$endfor$
|
|
||||||
\end{document}
|
|
@ -12,7 +12,7 @@ disponible. La mémoire est ainsi utilisée de manière plus efficace.
|
|||||||
|
|
||||||
[^vm-overcommit]: Cela dépend de la valeur de `/proc/sys/vm/overcommit_memory`,
|
[^vm-overcommit]: Cela dépend de la valeur de `/proc/sys/vm/overcommit_memory`,
|
||||||
généralement 0. Voir
|
généralement 0. Voir
|
||||||
<https://www.kernel.org/doc/html/latest/vm/overcommit-accounting.html>.
|
<https://www.kernel.org/doc/html/latest/mm/overcommit-accounting.html>.
|
||||||
|
|
||||||
Mais évidemment, cela peut donner lieu à des situations où, au moment où un
|
Mais évidemment, cela peut donner lieu à des situations où, au moment où un
|
||||||
processus se met à utiliser un nouveau bloc de mémoire (reçu du noyau d'un
|
processus se met à utiliser un nouveau bloc de mémoire (reçu du noyau d'un
|
||||||
|
@ -86,18 +86,18 @@ on lui attribue de nombreuses vulnérabilités. Vous devriez notamment consulter
|
|||||||
* [Anatomy of a user namespaces vulnerability](https://lwn.net/Articles/543273/) :\
|
* [Anatomy of a user namespaces vulnerability](https://lwn.net/Articles/543273/) :\
|
||||||
<https://lwn.net/Articles/543273/> ;
|
<https://lwn.net/Articles/543273/> ;
|
||||||
* <http://marc.info/?l=linux-kernel&m=135543612731939&w=2> ;
|
* <http://marc.info/?l=linux-kernel&m=135543612731939&w=2> ;
|
||||||
* <http://marc.info/?l=linux-kernel&m=135545831607095&w=2>.
|
* <http://marc.info/?l=linux-kernel&m=135545831607095&w=2> ;
|
||||||
|
* <https://www.openwall.com/lists/oss-security/2024/04/14/1>.
|
||||||
|
|
||||||
De nombreux projets ont choisi de ne pas autoriser l'utilisation de cet espace
|
De nombreux projets ont choisi de ne pas autoriser l'utilisation de cet espace
|
||||||
de noms sans disposer de certaines *capabilities*[^userns-caps].
|
de noms sans disposer de certaines *capabilities*[^userns-caps].
|
||||||
|
|
||||||
[^userns-caps]: Sont nécessaires, conjointement : `CAP_SYS_ADMIN`, `CAP_SETUID` et `CAP_SETGID`.
|
[^userns-caps]: Sont nécessaires, conjointement : `CAP_SYS_ADMIN`, `CAP_SETUID` et `CAP_SETGID`.
|
||||||
|
|
||||||
|
::::: {.question}
|
||||||
De nombreuses distributions ont choisi d'utiliser un paramètre du noyau pour
|
De nombreuses distributions ont choisi d'utiliser un paramètre du noyau pour
|
||||||
adapter le comportement.
|
adapter le comportement.
|
||||||
|
|
||||||
|
|
||||||
::::: {.question}
|
|
||||||
##### Debian et ses dérivées {.unnumbered}
|
##### Debian et ses dérivées {.unnumbered}
|
||||||
|
|
||||||
Si vous utilisez Debian ou l'un de ses dérivés, vous devrez autoriser
|
Si vous utilisez Debian ou l'un de ses dérivés, vous devrez autoriser
|
||||||
|
@ -39,7 +39,7 @@ confiant sur le fait que ce sera toujours le cas (du moins tant que la
|
|||||||
distribution assure le support de sa version).
|
distribution assure le support de sa version).
|
||||||
\
|
\
|
||||||
|
|
||||||
Le but du DevOps est donc de retrouver une certaine fluidité entre le
|
Le but du DevOps[^ABOUTDEVOPS] est donc de retrouver une certaine fluidité entre le
|
||||||
développement et l'exploitation. Il s'agit d'un mouvement qui vise à ce que les
|
développement et l'exploitation. Il s'agit d'un mouvement qui vise à ce que les
|
||||||
développeurs, sans avoir à gérer au quotidien la maintenance des serveurs de
|
développeurs, sans avoir à gérer au quotidien la maintenance des serveurs de
|
||||||
production, soient davantage impliqués dans les opérations de déploiement. Cela
|
production, soient davantage impliqués dans les opérations de déploiement. Cela
|
||||||
@ -48,6 +48,9 @@ phase de conception du projet, puis dès les premiers développements, des tests
|
|||||||
automatisés sont réalisés directement dans un environnement proche de la
|
automatisés sont réalisés directement dans un environnement proche de la
|
||||||
production.
|
production.
|
||||||
|
|
||||||
|
[^ABOUTDEVOPS]: Pour une explication détaillée du mouvement DevOps, je vous recommande :
|
||||||
|
<https://blog.stephane-robert.info/post/introduction-devops/>
|
||||||
|
|
||||||
Il en résulte moins de friction entre les deux équipes. Les développeurs étant
|
Il en résulte moins de friction entre les deux équipes. Les développeurs étant
|
||||||
par ailleurs amenés à écrire des recettes de déploiement, tels que des
|
par ailleurs amenés à écrire des recettes de déploiement, tels que des
|
||||||
playbooks Ansible ou bien encore des conteneurs Docker.
|
playbooks Ansible ou bien encore des conteneurs Docker.
|
||||||
|
20
tutorial/devops/renovate-cmd.md
Normal file
20
tutorial/devops/renovate-cmd.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Exportez dans une variable d'environnement le token d'accès généré qui vous est affiché par Gitea :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```shell
|
||||||
|
export RENOVATE_TOKEN=a0b1c2d3e4f5A6B7C8D9
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
La commande que nous allons utiliser pour lancer Renovatebot est la suivante :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```shell
|
||||||
|
docker container run --name renovate --network my_ci_net \
|
||||||
|
-e RENOVATE_ENDPOINT="http://gitea:3000/api/v1/" RENOVATE_PLATFORM=gitea \
|
||||||
|
-e RENOVATE_TOKEN -e RENOVATE_GIT_AUTHOR="Renovatebot <renovate@sample>" \
|
||||||
|
-e RENOVATE_AUTODISCOVER=true -e RENOVATE_LOG_LEVEL=info -d \
|
||||||
|
renovate/renovate
|
||||||
|
```
|
||||||
|
</div>
|
@ -24,7 +24,7 @@ Lançons enfin Drone avec les deux commandes suivantes :
|
|||||||
```shell
|
```shell
|
||||||
docker volume create drone_data
|
docker volume create drone_data
|
||||||
|
|
||||||
docker container run --name droneci -v drone_data:/data --network my_ci_net
|
docker container run --name droneci -v drone_data:/data --network my_ci_net \
|
||||||
-p 80:80 -e DRONE_GITEA_CLIENT_ID -e DRONE_GITEA_CLIENT_SECRET \
|
-p 80:80 -e DRONE_GITEA_CLIENT_ID -e DRONE_GITEA_CLIENT_SECRET \
|
||||||
-e DRONE_GITEA_SERVER=http://gitea:3000 -e DRONE_SERVER_PROTO=http \
|
-e DRONE_GITEA_SERVER=http://gitea:3000 -e DRONE_SERVER_PROTO=http \
|
||||||
-e DRONE_RPC_SECRET -e DRONE_SERVER_HOST=droneci -d \
|
-e DRONE_RPC_SECRET -e DRONE_SERVER_HOST=droneci -d \
|
||||||
|
@ -33,16 +33,61 @@ rejoindre), quelles *capabilities* resteront disponibles, quels nouveaux points
|
|||||||
de montages, ... Voir [la
|
de montages, ... Voir [la
|
||||||
suite](https://github.com/opencontainers/runtime-spec/blob/master/config.md).
|
suite](https://github.com/opencontainers/runtime-spec/blob/master/config.md).
|
||||||
|
|
||||||
Aujourd'hui, les dernières versions de `docker` utilisent `runc` pour l'étape
|
Aujourd'hui, `docker` utilise `runc` pour l'étape de lancement du conteneur,
|
||||||
de lancement du conteneur, après avoir téléchargé l'image puis mis en place
|
après avoir téléchargé l'image puis mis en place l'empilement de couches dans
|
||||||
l'empilement de couches dans un répertoire prédéterminé. `docker` ne lance donc
|
un répertoire prédéterminé. `docker` ne lance donc plus de conteneur à
|
||||||
plus de conteneur à proprement parler, il fait seulement en sorte d'atteindre
|
proprement parler, il fait seulement en sorte d'atteindre l'état voulu par
|
||||||
l'état voulu par cette spécification, avant de passer la main à `runc`.
|
cette spécification, avant de passer la main à `runc`.
|
||||||
|
|
||||||
|
::::: {.question}
|
||||||
|
|
||||||
|
##### Si `docker` fait appel à un programme externe pour lancer effectivement nos conteneurs, c'est que l'on peut changer cette implémentation ? {-}
|
||||||
|
|
||||||
|
<!-- https://ops.tips/blog/run-docker-with-forked-runc/ -->
|
||||||
|
|
||||||
|
Oui ! Et il n'y a même pas besoin de faire beaucoup d'efforts, car c'est une
|
||||||
|
possibilité qui est offerte au travers d'une option du daemon Docker. Le
|
||||||
|
binaire doit simplement avoir la même interface de ligne de commande que `runc`
|
||||||
|
(les arguments `create` et `start`, nous les verrons plus tard).
|
||||||
|
|
||||||
|
Pour l'ajouter, il convient de passer l'option suivante au daemon Docker lors
|
||||||
|
de son lancement (dans le fichier de service `systemd`, ou d'`init`) :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```sh
|
||||||
|
/usr/bin/dockerd [...] --add-runtime=my-runtime=/usr/local/bin/my-runtime
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Ou bien en passant par le fichier de configuration `/etc/docker/daemon.json` :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"runtimes": {
|
||||||
|
"my-runtime": {
|
||||||
|
"path": "/usr/local/bin/my-runtime",
|
||||||
|
"runtimeArgs": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Pour chaque nouveau conteneur lancé, il sera alors possible de préciser le *runtime* à utiliser grâce à l'option `--runtime` :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```sh
|
||||||
|
docker container run [...] --runtime=my-runtime nginx:alpine
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
:::::
|
||||||
|
|
||||||
|
|
||||||
### `image-spec`
|
### `image-spec`
|
||||||
|
|
||||||
Une image OCI est composée d'un manifest, d'une suite de couches de systèmes de
|
Une image OCI est composée d'un manifest, d'une série de couches de systèmes de
|
||||||
fichiers, d'une configuration ainsi que d'un index d'image optionnel.
|
fichiers, d'une configuration ainsi que d'un index d'image optionnel.
|
||||||
|
|
||||||
Le
|
Le
|
||||||
@ -52,14 +97,13 @@ trouver les différents éléments : configuration et couches. Lorsqu'une même
|
|||||||
image a des variations en fonction de l'architecture du processeur, du système
|
image a des variations en fonction de l'architecture du processeur, du système
|
||||||
d'exploitation, ... dans ce cas [l'index
|
d'exploitation, ... dans ce cas [l'index
|
||||||
d'image](https://github.com/opencontainers/image-spec/blob/master/image-index.md)
|
d'image](https://github.com/opencontainers/image-spec/blob/master/image-index.md)
|
||||||
est utilisé pour sélectionner le bon manifest.
|
est utilisé pour sélectionner le bon manifest correspondant au système.
|
||||||
|
|
||||||
Le format des [couches de système de
|
Le format des [couches de système de
|
||||||
fichiers](https://github.com/opencontainers/image-spec/blob/master/layer.md)
|
fichiers](https://github.com/opencontainers/image-spec/blob/master/layer.md)
|
||||||
sont spécifiées : il est nécessaire de passer par des formats standards (comme
|
sont spécifiées : il est nécessaire de passer par des formats standards (comme
|
||||||
les tarballs), contenant éventuellement des fichiers et dossiers spéciaux
|
les tarballs), contenant éventuellement des fichiers et dossiers spéciaux
|
||||||
contenant les modifications, suppressions, ... éventuelles de la couche
|
représentant les modifications ou les suppressions éventuelles de la couche.
|
||||||
représentée.
|
|
||||||
|
|
||||||
La
|
La
|
||||||
[configuration](https://github.com/opencontainers/image-spec/blob/master/config.md)
|
[configuration](https://github.com/opencontainers/image-spec/blob/master/config.md)
|
||||||
@ -72,14 +116,14 @@ des couches du système de fichiers, ainsi que l'historique de l'image.
|
|||||||
|
|
||||||
### `distribution-spec`
|
### `distribution-spec`
|
||||||
|
|
||||||
Dernière née de l'organisme, cette spécification fédère la notion de
|
Enfin, cette spécification fédère la notion de *registre* et la manière dont
|
||||||
*registre* : une API REST sur HTTP où l'on peut récupérer des images, mais
|
les clients vont interagir avec : il s'agit d'une API REST au dessus du
|
||||||
aussi en envoyer.
|
protocole HTTP.
|
||||||
|
|
||||||
|
Cela permet de récupérer des images, mais aussi d'en envoyer, en gérant
|
||||||
|
éventuellement la manière de s'authentifier.
|
||||||
|
|
||||||
### Pour aller plus loin {-}
|
\
|
||||||
|
|
||||||
Si maintenant `docker` fait appel à un programme externe pour lancer
|
Nous allons voir plus en détails, dans les chapitres suivantes, ce que l'on
|
||||||
effectivement nos conteneurs, c'est que l'on peut changer cette
|
peut tirer de ces spécifications, en décortiquant des usages précis.
|
||||||
implémentation ? la réponse dans l'article :\
|
|
||||||
<https://ops.tips/blog/run-docker-with-forked-runc/>
|
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
\newpage
|
\newpage
|
||||||
|
|
||||||
Registres
|
Registres d'images
|
||||||
=========
|
==================
|
||||||
|
|
||||||
Nous allons appréhender le fonctionnement d'un registre OCI, en essayant de
|
Regardons d'un peu plus près les registres d'images OCI. Ce sont eux qui
|
||||||
récupérer les couches de quelques images (Debian, Ubuntu, hello, ...) : dans un
|
distribuent les images OCI et permettent à Docker de récupérer très facilement
|
||||||
premier temps en nous préoccupant simplement de la couche la plus basse (qui ne
|
de nouveaux services.
|
||||||
contient pas de modification ou de suppression : chaque fichier est normal).
|
|
||||||
|
Dans les sections à venir, nous allons essayer de récupérer la configuration et
|
||||||
|
les couches de quelques images courantes (Debian, Ubuntu, `hello-world`, ...) :
|
||||||
|
dans un premier temps en nous préoccupant simplement de la couche la plus basse
|
||||||
|
(le système de baase). Puis nous verrons dans le chapitre suivant comment gérer
|
||||||
|
les autres couches.
|
||||||
|
|
||||||
|
|
||||||
## Authentification
|
## Authentification
|
||||||
@ -29,7 +34,7 @@ lang="en-US">`repository:hello-world:pull`</span>). Ce qui nous donne :
|
|||||||
dépôt (*repository*).
|
dépôt (*repository*).
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```
|
||||||
42sh$ curl "https://auth.docker.io/token?service=registry.docker.io&" \
|
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 .
|
||||||
```
|
```
|
||||||
@ -79,9 +84,10 @@ curl -s \
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Dans la liste des *manifests* retournés, nous devons récupérer son `digest`. Dans
|
Parmi la liste des *manifests* retournés, nous devons récupérer le `digest`
|
||||||
tout l'écosystème OCI, les `digest` servent à la fois de chemin d'accès et de
|
correspondant au système qui correspond à votre architecture et notre
|
||||||
somme de contrôle.
|
système. Dans tout l'écosystème OCI, les `digest` servent à la fois de chemin
|
||||||
|
d'accès et de somme de contrôle.
|
||||||
|
|
||||||
|
|
||||||
## Lecture du *manifest*
|
## Lecture du *manifest*
|
||||||
@ -100,17 +106,17 @@ curl -s \
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
Nous voici donc maintenant avec le *manifest* de notre image. Nous pouvons
|
Nous voici donc maintenant avec le *manifest* de notre image. Nous pouvons
|
||||||
constater qu'il n'a bien qu'une seule couche, ouf !
|
constater qu'il n'a bien qu'une seule couche. Ouf, ça va simplifier les
|
||||||
|
choses !
|
||||||
|
|
||||||
|
|
||||||
## Récupération de la configuration et de la première couche
|
## 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
|
Les deux éléments que l'on cherche maintenant à récupérer vont se trouver dans
|
||||||
répertoire `blobs`, il ne s'agit en effet plus de *manifest*. Si les *manifests*
|
le répertoire `blobs` de notre dépôt. Il ne s'agira plus de *manifest*, mais
|
||||||
sont toujours stockés par le registre lui-même, les blobs peuvent être délégués
|
bien des fichiers définitifs.
|
||||||
à un autre service, par exemple dans le cloud, chez Amazon S3, un CDN, etc.
|
|
||||||
|
|
||||||
Pour récupérer la configuration de l'image :
|
Récupérons la configuration de l'image comme ceci :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
@ -120,8 +126,16 @@ curl -s --location \
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Remarquez l'usage de l'option `--location` de `curl` : 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. Sans
|
||||||
|
l'option `--location`, notre `curl` va retourner une redirection vers une autre
|
||||||
|
adresse, celle qui contient effectivement la configuration. Il en sera de même
|
||||||
|
pour les fichiers stockant les couches.\
|
||||||
|
|
||||||
Enfin, armé du `digest` de notre couche, il ne nous reste plus qu'à la demander gentiment :
|
|
||||||
|
Enfin d'autre part, armé du `digest` de notre couche, il ne nous reste plus
|
||||||
|
qu'à la demander gentiment :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
4
tutorial/docker-internals/runtimes.md
Normal file
4
tutorial/docker-internals/runtimes.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
\newpage
|
||||||
|
|
||||||
|
Programmes d'exécution de conteneurs
|
||||||
|
====================================
|
Loading…
Reference in New Issue
Block a user