Sommaire
Update : RKT c’est fini
Le runtime abordé dans cet article RKT est abandonné depuis le mai 2020, nous vous déconseillons donc son utilisation.
Si vous souhaitez trouver une alternative à RKT, nous avons abordé ce sujet au Paris Container Day 2021 ! Donc n’hésitez pas à aller voir la conférence “Pour quelques runtimes de plus” de Thomas Gerardin, qui présente les principaux runtimes disponible actuellement. Elle est disponible en replay par ici :
Dans un précédent article, nous vous avions présenté les caractéristiques du container runtime RKT. Il est désormais temps de passer à la pratique.
Installation
Avant de pouvoir utiliser RKT, sur la plupart des systèmes d’exploitation, il est nécessaire de l’installer.
Plusieurs méthodes s’offrent à vous :
- l’utilisation du gestionnaire de paquets pour la plupart des distributions Linux
- l’utilisation de Container Linux OS pour lequel RKT est fourni à l’installation (et tout simplement parce que Container Linux OS c’est bien)
La version qui sera alors installée ne sera pas forcément la plus récente (la dernière version est la 1.25). Afin d’installer celle-ci, le plus simple est le téléchargement de l’archive disponible ici.
Les équipes de CoreOS fournissent un script permettant cette installation de manière sécurisée via une unité Systemd. Une version plus récente permettra d’utiliser de nouvelles fonctionnalités disponibles avec un support expérimental.
Une fois l’installation réalisée, partons à la découverte de cet outil.
Premiers pas
Téléchargement d’une image
Un container a besoin d’une image du système à lancer afin de s’exécuter. Comme nous l’avons vu dans notre précédent article, la signature ainsi que l’intégrité d’une image sont vérifiées lors du téléchargement. Nous pouvons prendre en exemple un service Redis :
# rkt fetch quay.io/quay/redis
pubkey: prefix: "quay.io/quay/redis"
key: "https://quay.io/aci-signing-key"
gpg key fingerprint is: BFF3 13CD AA56 0B16 A898 7B8F 72AB F5F6 799D 33BC
Quay.io ACI Converter (ACI conversion signing key) <support@quay.io>
Are you sure you want to trust this key (yes/no)?
yes
Trusting "https://quay.io/aci-signing-key" for prefix "quay.io/quay/redis" after fingerprint review.
Added key for prefix "quay.io/quay/redis" at "/etc/rkt/trustedkeys/prefix.d/quay.io/quay/redis/bff313cdaa560b16a8987b8f72abf5f6799d33bc"
Downloading signature: [=======================================] 473 B/473 B
Downloading ACI: [=============================================] 115 MB/115 MB
image: signature verified:
Quay.io ACI Converter (ACI conversion signing key) <support@quay.io>
sha512-5b31024cd779a03bb85de8fe4b470fec
Le hash sha512 affiché à la fin du téléchargement correspond à l’ID de l’image.
Il est possible de lancer aussi des images Docker. Pour ce faire, nous allons nous baser sur une image de Luke Bond, qui nous sera utile dans les prochaines étapes. Ces images, qui ne proposent pas ce mécanisme de signatures, il faut dès lors passer une option afin d’ignorer ces vérifications :
# rkt fetch --insecure-options=image docker://lukebond/demo-api-redis
Downloading sha256:11b0f785601 [=============================] 547 B / 547 B
Downloading sha256:de4b2408330 [=============================] 2.38 MB / 2.38 MB
Downloading sha256:15559fbe3f4 [=============================] 125 B / 125 B
Downloading sha256:675734e2e0d [=============================] 486 B / 486 B
Downloading sha256:14547e35356 [=============================] 77.8 MB / 77.8 MB
Downloading sha256:427713f7fc5 [=============================] 3.16 MB / 3.16 MB
sha512-caeacc57d886370ccc98727bb7313f56
Le téléchargement ainsi que les différentes vérifications peuvent aussi être effectués lors du lancement du container. Ce téléchargement, réalisé séparément, peut être utile si nous voulons inspecter le contenu de l’image avant de l’utiliser, modifier son contenu avant de construire une image qui correspond plus aux besoins par exemple.
Lancement d’un container
Nous avons donc désormais à notre disposition des images de container. C’est pas mal, mais un peu inutile pour le moment. Nous allons donc démarrer notre premier container de la façon suivante :
# rkt run quay.io/quay/redis
stage1: warning: no volume specified for mount point "volume-var-lib-redis", implicitly creating an "empty" volume. This volume will be removed when the pod is garbage-collected.
stage1: warning: no volume specified for mount point "volume-var-lib-redis", implicitly creating an "empty" volume. This volume will be removed when the pod is garbage-collected.
Les warnings sont ici pour nous indiquer qu’il est possible de fournir un volume pour stocker de manière persistante les données du serveur Redis ici lancé.
Afin de terminer un container, il faut utiliser la séquence CTRL+] (CTRL+$ sur un clavier azerty OSX) 3 fois de suite, ce qui donne en reprenant le container précédent :
stage1: warning: no volume specified for mount point "volume-var-lib-redis", implicitly creating an "empty" volume. This volume will be removed when the pod is garbage-collected.
^]^]Container rkt-f655ee2e-7c24-4745-9aac-88b9f668cb2d terminated by signal KILL.
Et les logs ?
La question que doit se poser tout DevOps est l’accessibilité des logs, et ce afin d’être capable de débugger son application ou son image de container.
Avec RKT, une forte utilisation des mécanismes de systemd est réalisée.
Nous pouvons utiliser machinectl afin d’obtenir les UUID des containers lancés.
# machinectl
MACHINE CLASS SERVICE
rkt-f655ee2e-7c24-4745-9aac-88b9f668cb2d container rkt
Il est aussi possible d’utiliser journalctl afin d’obtenir les logs des applicatifs en cours d’exécution.
journalctl -M rkt-f655ee2e-7c24-4745-9aac-88b9f668cb2d -t redis
-- No entries --
Gestion des ressources
Nous sommes donc désormais capables d’effectuer un certain nombre d’actions avec RKT. Nous pouvons donc déployer des containers, mais comment le terminer, éliminer les ressources superflues, savoir ce qui tourne sur notre serveur ?
Pour toutes ces opérations, quelques commandes sont utiles.
Lister ses containers
Rien de plus simple pour ceci :
# rkt list
UUID APP IMAGE NAME STATE CREATED STARTED NETWORKS
f655ee2e redis quay.io/quay/redis:latest exited 1 minute ago 1 minute ago
L’ensemble des informations utiles y sont et il n’y a aucun besoin d’expliciter plus cela. Les informations réseaux ne sont plus disponibles, le container étant terminé.
Statut d’un container
Une commande permet de connaître rapidement le statut d’un container avec quelques informations supplémentaires.
# rkt status f655ee2e
state=exited
created=2017-02-27 21:46:17 +0000 UTC
started=2017-02-27 21:46:17 +0000 UTC
pid=1899
exited=true
Faire un peu de ménage
Il est de temps en temps nécessaire de faire un peu de rangement parmi ces containers qui ne tournent plus. Pour cela, un garbage collector est disponible. Il est censé tourner de façon périodique et marche en 2 temps : dans un premier temps, le contenu du container sur le système de fichiers est déplacé et le container marqué comme étant dans le garbage collector. Ensuite, une période de grâce, de 30 minutes par défaut, permettant de récupérer des éléments qui aurait pu être oubliés, est active. Un second appel au garbage collector durant cette période n’aura aucun effet. A la fin de cette période, cet appel supprimera définitivement le container.
Cela peut donner (en changeant la période à 10s) :
# rkt gc --grace-period=10s
gc: moving pod "f655ee2e-7c24-4745-9aac-88b9f668cb2d" to garbage
gc: pod "f655ee2e-7c24-4745-9aac-88b9f668cb2d" not removed: still within grace period (10s)
# rkt gc --grace-period=10s
Garbage collecting pod "f655ee2e-7c24-4745-9aac-88b9f668cb2d"
Bien évidemment, les mêmes commandes s’appliquent aux images, tel que rkt image list.
Utiliser le shell d’un container
Maintenant que notre container est lancé, il est possible que nous ayons besoin de rentrer dans celui-ci, afin de vérifier les processus qui tournent, modifier les fichiers de configuration des services du container. Afin de réaliser cette opération, il nous suffit d’utiliser l’UUID du container (nouvellement créé, le précédent ayant été supprimé) via la commande suivante :
# rkt enter 5d1e2e76
enter: no command specified, assuming "/bin/bash"
groups: cannot find name for group ID 11
root@rkt-5d1e2e76-b28e-4aa3-9a09-fe52e9ea4c3a:/# ps auxw
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.5 49692 6076 ? Ss 20:57 0:00 /usr/lib/systemd/systemd --default-standard-output=tty --log-target=null --show-status=0
root 3 0.0 0.5 49572 6092 ? Ss 20:57 0:00 /usr/lib/systemd/systemd-journald
root 5 0.0 0.8 37004 8964 ? Ssl 20:57 0:00 /usr/bin/redis-server *:6379
root 31 0.0 0.3 18176 3304 ? S 21:06 0:00 /bin/bash
root 41 0.0 0.2 15576 2204 ? R+ 21:06 0:00 ps auxw
root@rkt-7039ad45-a0db-4499-ad48-1eca6373ad2d:/#
Opérations sur les images
Vous allez me dire : “Oui c’est bien gentil, on peut télécharger, vérifier et utiliser des images, mais c’est un peu léger tout ça”. Et vous n’avez pas tort. Il est en effet possible de réaliser quelques actions supplémentaires.
Obtenir des informations
Nous pouvons obtenir un certain nombre d’informations sur une image téléchargée. Cela se fait de la façon suivante :
# rkt image cat-manifest quay.io/quay/redis
{
"acKind": "ImageManifest",
"acVersion": "0.6.1",
"name": "quay.io/quay/redis",
"labels": [
{
"name": "version",
"value": "latest"
},
{
"name": "arch",
"value": "amd64"
},
{
"name": "os",
"value": "linux"
}
],
"app": {
"exec": [
"/usr/bin/redis-server",
"conf/redis.conf"
],
"user": "root",
"group": "root",
"workingDirectory": "/",
"environment": [
{
"name": "HOME",
"value": "/root"
},
{
"name": "PATH",
"value": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
},
{
"name": "DEBIAN_FRONTEND",
"value": "noninteractive"
}
],
"mountPoints": [
{
"name": "volume-var-lib-redis",
"path": "/var/lib/redis"
}
]
}
}
Nous pouvons alors savoir quelle est l’application lancée par le container, sur les utilisateurs, ainsi que d’autres informations sur la construction de l’image ou définissant des options qui peuvent être ajoutées lors du lancement du container, tel que des points de montage.
Contenu d'une image
Nous avons téléchargé une image, obtenu quelques informations sur celle-ci mais que contient-elle réellement ? Encore une fois, tout est prévu. Il suffit de lancer la commande suivante et la magie opère (le répertoire de destination est créé à l’exécution) :
# rkt image extract quay.io/quay/redis /opt/redis-image
# ls /opt/redis-image/*
/opt/redis-image/manifest
/opt/redis-image/rootfs:
bin boot conf dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
Nous retrouvons donc le système de fichiers du container ainsi que le manifest de l’image contenant les informations vues précédemment.
Construction d’images
Afin de construire des images, il faut utiliser acbuild. La définition d’une image peut être considérée comme l’équivalent d’un Dockerfile, c’est un fichier qui contient une suite d’appel à acbuild pour définir à la fois le contenu et les métadonnées de l’image. Un exemple est disponible ici
Et c’est comment le stockage et le réseau ?
Nous avons pour le moment découvert les quelques commandes qui nous permettent déjà de faire pas mal de choses avec RKT. On souhaiterait tout de même avoir du stockage persistant pour mettre les données de nos services ou bien encore exposer ceux-ci au monde.
Stockage
Comme nous l’avons vu lors du lancement de l’image Redis ainsi que dans le listing des attributs de l’image, des points de montage peuvent être associés à un container. Il existe 2 types de points de montage :
- empty, qui est le cas par défaut et qui a été appliqué lors de nos précédents lancements de Redis. Le volume est créé localement dans le container et supprimé lorsque celui-ci passe à la poubelle.
- host, qui utilise un dossier existant sur le système afin de stocker les données utilisables ou écrites par l’application. Lorsque le container est détruit, ces données sont toujours disponibles
Réseau
Par défaut, chaque container à une ip dans le range x.x.X.x/X. Les applicatifs qui tournent dans nos containers sont accessibles depuis l’hôte avec l’adresse ip privée du container. C’est assez sympa mais pouvoir rendre le service accessible à l’extérieur de notre hôte, c’est quand même mieux. Toujours dans les attributs de l’image, nous pouvons trouver ce genre d’informations :
"ports": [
{
"name": "http",
"port": 80,
"protocol": "tcp"
}
]
Dès lors, en ajoutant --port=http:
au lancement du container avec un port disponible sur l’hôte, que ce soit le 80 ou un autre, les connexions sur le port défini côté hôte seront transférées au port 80 du container.
Nous allons illustrer ces 2 points en utilisant l’image pour le système de blog Ghost. En effet, dans le manifest de l’image, nous pouvons constater l’utilisation d’un point de montage ainsi que l’exposition d’un port :
"mountPoints": [
{
"name": "volume-var-lib-ghost",
"path": "/var/lib/ghost"
}
],
"ports": [
{
"name": "2368-tcp",
"protocol": "tcp",
"port": 2368,
"count": 1,
"socketActivated": false
}
]
De ce fait, une fois le dossier créé, le container peut être lancé de la façon suivante :
# mkdir /opt/ghost
# rkt --insecure-options=image --port=2368-tcp:2368 --volume volume-var-lib-ghost,kind=host,source=/opt/ghost run docker://ghost
Et nous obtenons alors un blog prêt à être configuré et accessible via l’ip publique de l’hôte sur le port 2368. Il aurait aussi été possible que le blog réponde sur le port 80 (via --port=2368-tcp:80) :
Lorsque nous quittons le container, les données du blog sont toujours présentes dans le dossier adéquat :
[ 7179.637791] ghost[5]: GET /favicon.ico 200 0.828 ms - -
[ 7225.932754] ghost[5]: GET / 200 115.729 ms - 4546
^]^]Container rkt-08cb2a23-6093-4b2c-99ff-dee301738e6c terminated by signal KILL.
# ls /opt/ghost/
apps config.js data images themes
Aller plus loin
Nous avons ici découvert une utilisation basique de RKT. Il est bien évidemment possible de faire plus de choses avec.
API
Une api gRPC est disponible en version expérimentale afin de communiquer avec RKT. Elle se lance de la façon suivante :
# rkt api-service
api-service: API service starting...
api-service: Listening on localhost:15441
api-service: API service running
Pour l’utiliser, un exemple en Go est fourni.
Activation de fonctionnalités expérimentales
Certaines fonctionnalités de RKT ne sont disponibles qu’en version expérimentale, le temps que celles-ci soient testées en conditions réelles et leur code corrigé des quelques bugs pouvant exister.
Pour utiliser, il suffit d’exporter la variable d’environnement RKT_EXPERIMENT_APP, soit globalement, soit à l’utilisation du binaire RKT :
# export RKT_EXPERIMENT_APP=1
# RKT_EXPERIMENT_APP=1 rkt ...
Parmi les fonctionnalités expérimentales au moment de la rédaction de ce billet, on trouve :
la commande app qui permet d’attacher, supprimer, démarrer ou encore arrêter une application dans un container, ainsi que de démarrer un container en mode sandbox, de façon à construire/tester le container applicatif.
les commandes attach/detach avec lesquelles vous pouvez récupérer stdin/stdout/stderr de votre container. Cela n’est fonctionnel que sous certaines conditions
Ressources additionnelles
Je ne peux que vous conseiller de suivre le blog ainsi que le twitter de CoreOS, où de nombreuses informations sont disponibles. Bien évidemment, la documentation est hautement fournie. De nombreux webinaires sont donnés par les équipes de CoreOS sur BrightTalk.
Conclusion
J’espère que cette introduction vous a donné envie d’utiliser RKT. Maintenant lancez-vous, fouillez la documentation (de nombreuses options sont disponibles), mixez cela dans du Kubernetes et faites vous votre avis sur RKT.