Rkt

# INTRODUCTION

 

rkt (se dit rock-it) est un container runtime crée par les équipes de CoreOS. rkt a fait sa première apparition fin Novembre 2014 et celui-ci est en constante évolution depuis (au rythme d’une release toutes les deux semaines en moyenne).

 

 

Un containeur Linux est un ensemble de processus qui sont isolés du reste du système. Un containeur s’exécute à partir d’une image distincte qui fournit tous les fichiers nécessaires à la prise en charge des processus qu’il contient. En fournissant une image qui contient toutes les dépendances d’une application, le containeur assure la portabilité et la cohérence de l’application entre les divers environnements (développement, test puis production).

Pour mieux comprendre ce qu’est un container, imaginons que vous êtes en train de développer une application. Vous travaillez sur un ordinateur portable dont l’environnement présente une configuration spécifique. D’autres développeurs peuvent travailler sur des machines qui présentent des configurations légèrement différentes. L’application que vous développez repose sur cette configuration et dépend de fichiers spécifiques. En parallèle, votre entreprise exploite des environnements de test et de production qui sont standardisés sur la base de configurations qui leur sont propres et de l’ensemble des fichiers associés. Vous souhaitez émuler ces environnements autant que possible localement, mais sans avoir à payer les coûts liés à la recréation des environnements de serveur. Comment faire pour que votre application en développement puisse fonctionner dans ces environnements, passer l’assurance qualité et être déployée sans prise de tête, sans réécriture et sans correctifs ? La réponse est simple : il vous suffit d’utiliser des containeurs. Le containeur qui accueille votre application contient toutes les configurations nécessaires. Vous pouvez ainsi le déplacer entre les environnements de développement, de test et de production, sans aucun effet secondaire. Les containeurs peuvent aussi être utilisés pour résoudre des problèmes liés à des situations qui nécessitent un haut niveau de portabilité, de configurabilité et d’isolation. Quelle que soit l’infrastructure (sur site, dans le cloud ou hybride), les containeurs répondent à la demande.

 

# CONTEXTE

 

La définition d’un standard autour de ce que doit être un container ayant été mise en place aux débuts de Docker, il est possible de retrouver le manifeste sur le GitHub de moby, les équipes de Container Linux ont fortement participé à son développement. Toutefois, l’évolution de Docker ne correspondait pas à ce que les développeurs de CoreOS envisageaient à la base :

  • Docker tourne avec un daemon (désigne un type de programme informatique, un processus ou un ensemble de processus qui s’exécute en arrière-plan plutôt que sous le contrôle direct d’un utilisateur) qui gère un ensemble de composants. Si ce processus disparait, les containers ont disparu même si ce dernier a changé en Juin 2016 suite à la sortie de la version 1.11 de Docker, avec le Docker Engine séparé du daemon gérant les containers
  • De « simple » container, Docker est devenu tout un écosystème packagé dans un seul binaire (là encore, la situation a changé) : création d’images, orchestrateur de containeurs.

De ce constat est né le projet RKT, le développement de ce dernier se concentre sur les points suivants :

  • La sécurité : La signature ainsi que l’intégrité des images est vérifiée par défaut au téléchargement ou au lancement du containeur. De plus, l’architecture a elle aussi gagné en sécurité. En effet, aucun daemon nécessitant des privilèges élevés n’est nécessaire au bon fonctionnement de RKT et en fonction de l’opérateur à réaliser, il n’est pas forcément nécessaire d’avoir des privilèges administrateurs. La récupération d’une image en est un exemple. Afin d'assurer l'isolation entre l'host et les containers, RKT n'a pas réinventé la roue et utilise les mécanismes existants tels que les Cgroups v1 et v2 ou encore Selinux. L'isolation matérielle est, elle, assurée par le support des hyperviseurs. Cerise sur le gâteau, le support de Trusted Platform Module va permettre l'audit des containers ainsi que de leur configuration.
  • Composabilité : elle est à la fois externe et interne. En externe, RKT est compatible avec les systèmes d'init existants que sont OpenRC et Systemd. La compatibilité avec les orchestrateurs tels que Kubernetes et Nomad est aussi assurée.

    En interne, celle-ci est assurée par un fonctionement en couches et le support de plusieurs moteurs d'exécution pour les containers. Les différentes couches sont les suivantes :

  • En stage0, RKT lui-même, le binaire n'étant qu'une UX/API pour le moteur d'exécution du container
  • En stage1 se trouve le moteur d'exécution du container. Comme évoqué précédemment, plusieurs sont disponibles. Par défaut, un container est lancé via systemd-nspawn. Le container peut aussi démarrer via un simple chroot, nommé fly par les développeurs de RKT. Enfin, l'isolation matérielle peut aussi être réalisée sur cette couche par l'intermédiaire de LKVM (une version allégée de KVM) ou en core Qemu
  • Le stage2 comprend la ou les applications qui doivent fonctionner dans le container lancé. La notion de Pod par RKT regroupe à la fois le moteur d'exécution et les applications containerisées, ce qui est au final démarré par le binaire rkt. Illustrée,  cette composabilité interne peut être vue de la façon suivante :

 

  • Une intégration aux standards : RKT a été la première implémentation du standard APPC, qui définit ce que doit être un container runtime, le format d'image, le protocole de découverte d'images. Ce standard a eu son petit succès mais est désormais en perte de vitesse. L'Open Container Initiative, promue par la Linux Foundation, et avec la participation des grands acteurs du secteur, propose un nouveau standard qui définit lui aussi ce que doit être un container ainsi que le format de l'image, pour le moment seulement considéré comme un "filesystem bundle" décompressable sur disque. À terme, les fonctionnalités d'APPC seront disponibles avec OCI. Enfin, le projet Container Runtime Interface (CRI) développé principalement par Google et Redhat, qui permet la définition d'une API permettant de lancer tout container runtime avec les mêmes instructions, a été pris en compte récemment dans RKT.
  • La compatibilité : les images Docker sont supportées nativement
  • Une API gRPC est disponible afin de réaliser de l'introspection sur les containers et les images.

 

# COMPARAISON RKT-DOCKER

 

Le moteur Docker est une exécution de conteneur d'application implémentée en tant que démon API central. Docker peut résoudre un nom "Docker Image", tel que   quay.io/coreos/etcd, et télécharger, exécuter et surveiller le conteneur d'application. Fonctionnellement, tout cela est similaire à rkt, cependant, avec « Docker Images », rkt peut également télécharger et exécuter des « Images de conteneur d'applications » (ACI) spécifiées par la spécification de conteneur d'applications (appc).

En plus de supporter les ACI, rkt a une architecture sensiblement différente qui est conçue pour la composabilité et la sécurité.

 

Modèle de processus

Avant la version 1.11 de Docker, le démon Docker Engine téléchargeait des images de conteneur, lançait des processus de conteneur, exposait une API distante et agissait comme un démon de collecte de journaux, le tout dans un processus centralisé s'exécutant en tant que root.

Bien qu'une telle architecture centralisée soit pratique pour le déploiement, elle ne suit pas les meilleures pratiques pour la séparation des processus et des privilèges Unix; de plus, cela complique l'intégration de Docker aux systèmes d'initialisation Linux tels que upstart et systemd.

Depuis la version 1.11, le démon Docker ne gère plus l'exécution des conteneurs. Au lieu de cela, ceci est maintenant géré par containerd. Plus précisément, le démon Docker prépare l'image en tant qu'ensemble OCI (Open Container Image) et lance un appel API vers containerd pour démarrer le bundle OCI. containerd démarre ensuite le conteneur en utilisant runC.

 

 

Depuis l'exécution d'un conteneur Docker à partir de la ligne de commande (par exemple en utilisant docker run) parle simplement à l'API du démon Docker, qui est directement ou indirectement - via containerd - responsable de la création du conteneur, les systèmes init sont incapables de suivre directement la vie de le processus de conteneur réel.

 

rkt n'a pas de démon "init" centralisé, mais lance des conteneurs directement à partir des commandes client, ce qui le rend compatible avec les systèmes init tels que systemd, upstart et autres.

 

Privilège Séparation

rkt utilise les autorisations de groupe Unix standard pour permettre la séparation des privilèges entre différentes opérations. Une fois que le répertoire de données rkt est correctement configuré, les téléchargements d'images de conteneur et la vérification de signature peuvent s'exécuter en tant qu'utilisateur non privilégié.

 

 

 

# COMPARAISON RKT-DOCKER

 

rkt est écrit en Go et peut être compilé pour plusieurs CPU. Le projet rkt distribue des binaires pour amd64. Ces binaires rkt fonctionneront sur n'importe quel noyau Linux amd64 moderne.

 

Exécution du dernier binaire rkt

Pour commencer à exécuter la dernière version de rkt sur amd64, récupérez la version directement à partir du projet rkt GitHub :

  1. wget https://github.com/rkt/rkt/releases/download/v1.29.0/rkt-v1.29.0.tar.gz
  2. tar xzvf rkt-v1.29.0.tar.gz
  3. cd rkt-v1.29.0
  4. ./rkt help

 

Installation de rkt à partir d'un paquet de distribution Linux

Un autre moyen d'exécuter rkt est de l'installer avec le gestionnaire de paquets de votre système, comme apt sur Debian ou dnf sur Fedora. Vérifiez votre distribution Linux dans la liste des distributions pour voir si un paquet rkt est disponible : https://rocket.readthedocs.io/en/latest/Documentation/distributions/

 

Exécution de rkt dans une machine virtuelle Vagrant

Si votre système d'exploitation n'est pas Linux, il est facile d'exécuter rkt dans une machine virtuelle Linux avec Vagrant. Les instructions ci-dessous démarrent une machine virtuelle avec rkt installé et prêt à fonctionner.

 

Vagabond sur Mac et Windows

Pour les utilisateurs Mac (et autres Vagrant), nous avons mis en place un fichier Vagrantfile. Assurez-vous que Vagrant 1.5.x ou supérieur est installé : https://www.vagrantup.com/

Tout d'abord, téléchargez le fichier Vagrantfile et démarrez une machine Linux avec rkt installé en exécutant errant vers le haut.

  1. git clone https://github.com/rkt/rkt
  2. cd rkt
  3. vagrant up

 

Vagrant sur Linux

Pour utiliser Vagrant sur une machine Linux, vous pouvez utiliser libvirt en tant que VMM au lieu de VirtualBox. Pour ce faire, installez les plugins nécessaires, convertissez la boîte et démarrez la machine en utilisant le fournisseur libvirt:

  1. vagrant plugin install vagrant-libvirt
  2. vagrant plugin install vagrant-mutate
  3. vagrant mutate ubuntu/xenial64 libvirt
  4. vagrant up --provider=libvirt

 

Accéder à la machine virtuelle Vagrant et exécuter rkt. Avec un ssh, vous aurez accès à run rkt. Si vous utilisez une version obsolète de VirtualBox, il se peut que SSH demande un mot de passe. Vous pouvez trouver le mot de passe de l'utilisateur ubuntu dans config.sss.password : ~/.vagrant.d/boxes/ubuntu-VAGRANTSLASH-xenial64/[DATE]/virtualbox/Vagrantfile

  1. vagrant ssh
  2. rkt --help

 

Mise en réseau de conteneurs sur une machine virtuelle Vagrant 

Pour atteindre les pods de votre hôte, déterminez l'adresse IP de la machine vagabonde :

  1. vagrant ssh -c 'ip address'
  2. ...
  3. 3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group defaultqlen 1000
  4. link/ether 08:00:27:04:e4:5d brd ff:ff:ff:ff:ff:ff
  5. inet 172.28.128.3/24 brd 172.28.128.255 scope global enp0s8
  6. valid_lft forever preferred_lft forever
  7. ...

 

Dans cet exemple, la machine vagabonde a l'adresse IP 172.28.128.3.

 

La commande suivante démarre un conteneur nginx, pour simplifier l'utilisation de la mise en réseau hôte pour rendre le module directement accessible sur l'adresse réseau et les ports de l'hôte. La validation des signatures n'est pas prise en charge pour les registres et les images Docker, de sorte que --insecure-options = image désactive la vérification des signatures :

  1. sudo rkt run --net=host --insecure-options=image docker://nginx

 

Le conteneur nginx est maintenant accessible sur l'hôte sous http://172.28.128.3.

 

Pour utiliser des conteneurs avec le réseau par défaut contenu, une route vers le réseau de conteneur 172.16.28.0/24 doit être configurée à partir de l'hôte via la machine virtuelle.

Sous Linux, exécutez :

  1. sudo ip route add 172.16.28.0/24 via 172.28.128.3

 

Sur Mac OSX, exécutez:

  1. sudo route -n add 172.16.28.0/24 172.28.128.3

 

Maintenant, nginx peut être démarré en utilisant le réseau contenu par défaut :

  1. sudo rkt run --insecure-options=image docker://nginx
  2. $ rkt list
  3. UUID        APP IMAGE NAME                  STATE   CREATED     STARTED     NETWORKS
  4. 0c3ab969    nginx   registry-1.docker.io/library/nginx:latest   running 2 minutes ago   2 minutes ago   default:ip4=172.16.28.2

 

Dans cet exemple, le conteneur nginx a reçu l'adresse IP 172.16.28.2 (l'adresse attribuée sur votre système peut varier). Puisque nous avons établi une route entre l'hôte et le réseau de pods 172.16.28.0/24, le conteneur nginx est maintenant accessible sur l'hôte sous http://172.16.28.2. Le reste du guide peut maintenant être suivi normalement.

 

Configuration d'un hôte rkt 

Une fois que rkt est présent sur une machine, certaines étapes de configuration facultatives peuvent faciliter son utilisation.

 

SELinux

rkt prend en charge l'exécution des contrôles d'accès obligatoires SELinux, mais une stratégie SELinux doit être adaptée à votre distribution. Les nouveaux utilisateurs de rkt sur des distributions autres que Container Linux devraient temporairement désactiver SELinux pour le rendre plus facile à démarrer. Si vous pouvez aider à rkt package pour votre distribution, y compris le support de la politique SELinux, s'il vous plaît donner un coup de main !

Facultatif : Configurer la séparation des privilèges

 

Pour permettre à différentes sous-commandes d'utiliser le privilège le moins nécessaire, rkt reconnaît un groupe rkt ayant un accès en lecture-écriture au répertoire de données rkt. Cela permet à rkt fetch, qui télécharge et vérifie les images, de s'exécuter en tant qu'utilisateur non privilégié, membre du groupe rkt.

 

Si vous ignorez cette section, vous pouvez toujours exécuter sudo rkt fetch à la place, mais la configuration d'un groupe rkt est une bonne pratique de sécurité de base pour l'utilisation en production. Le repo rkt inclut un script setup-data-dir.sh qui peut aider à configurer les autorisations appropriées pour l'exécution non-privilégiée de sous-commandes qui manipulent le magasin local, mais pas l'environnement d'exécution :

  1. sudo groupadd rkt
  2. export WHOAMI=$(whoami); sudo gpasswd -a $WHOAMI rkt
  3. sudo ./dist/scripts/setup-data-dir.sh

 

La clé de signature pour valider les extractions non privilégiées

La clé de signature donne la permission pour les images etcd. Cette étape doit être exécutée en tant que root car l'accès au fichier de clés est restreint à partir du même groupe rkt :

  1. sudo ./rkt trust --prefix coreos.com/etcd

 

Récupérer une image en tant que membre non privilégié du groupe rkt

Testez ceci en récupérant une image etcd en utilisant un utilisateur non-root dans le groupe rkt. Assurez-vous que votre shell est redémarré pour activer le groupe rkt pour votre utilisateur, ou exécutez simplement newgrp rkt pour l'activer et continuer dans la même session.

 

Récupérez maintenant l'image etcd en tant qu'utilisateur non privilégié :

  1. ./rkt fetch coreos.com/etcd:v3.1.7

 

# UTILISATION

 

Construire une image de conteneur d'applications

 

Le format d'image native de rkt est l'image du conteneur d'applications (ACI), définie dans la spécification du conteneur d'applications (https://rocket.readthedocs.io/en/latest/Documentation/app-container/). L'outil de compilation est un moyen simple de démarrer la construction d'ACI. Le référentiel de construction appc (https://github.com/appc/build-repository) a des ressources pour construire des ACI à partir d'un certain nombre d'applications populaires.

 

L'outil docker2aci (https://github.com/appc/docker2aci) convertit les images Docker en ACI, ou rkt peut convertir les images directement à partir des registres Docker à la volée (https://rocket.readthedocs.io/en/latest/Documentation/running-docker-images/).

 

Téléchargement d'un ACI 

rkt utilise le stockage adressable de contenu (CAS) pour stocker un ACI sur le disque. Dans cet exemple, une image est téléchargée et ajoutée au CAS. Le téléchargement d'une image avant de l'exécuter n'est pas strictement nécessaire - si une image n'est pas présente en local, rkt tentera de la récupérer - mais cela illustre comment fonctionne rkt.

 

Comme rkt vérifie les signatures par défaut, la première étape consiste à faire confiance à la clé publique CoreOS utilisée pour signer l'image, en utilisant la sous-commande rkt trust :

  1. $ sudo rkt trust --prefix=coreos.com/etcd
  2. Prefix: "coreos.com/etcd"
  3. Key: "https://coreos.com/dist/pubkeys/aci-pubkeys.gpg"
  4. GPG key fingerprint is: 8B86 DE38 890D DB72 9186  7B02 5210 BD88 8818 2190
  5. CoreOS ACI Builder <release@coreos.com>
  6. Are you sure you want to trust thiskey (yes/no)? yes
  7. Trusting "https://coreos.com/dist/pubkeys/aci-pubkeys.gpg"for prefix "coreos.com/etcd".
  8. Added key forprefix "coreos.com/etcd" at "/etc/rkt/trustedkeys/prefix.d/coreos.com/etcd/8b86de38890ddb7291867b025210bd8888182190"

 

Récupérer l'ACI

Maintenant que la clé publique CoreOS est approuvée, récupérez l'ACI en utilisant rkt fetch. Cette étape n'a pas besoin de privilèges root si l'hôte rkt a été configuré pour la séparation de privilèges (https://rocket.readthedocs.io/en/latest/Documentation/trying-out-rkt/#optional-set-up-privilege-separation) :

  1. $ rkt fetch coreos.com/etcd:v3.1.7
  2. rkt: searching forapp image coreos.com/etcd:v3.1.7
  3. rkt: fetching image from https://github.com/coreos/etcd/releases/download/v3.1.7/etcd-v3.1.7-linux-amd64.aci
  4. Downloading aci: [==========================================   ] 3.47 MB/3.7 MB
  5. Downloading signature from https://github.com/coreos/etcd/releases/download/v3.1.7/etcd-v3.1.7-linux-amd64.asc
  6. rkt: signature verified:
  7. CoreOS ACI Builder <release@coreos.com>
  8. sha512-7d28419b27d5ae56cca97f4c6ccdd309c...

 

 

Téléchargement d'images à partir de registres privés 

Le téléchargement d'images de conteneur à partir d'un registre privé implique généralement de transmettre des noms d'utilisateur et des mots de passe ou d'autres types d'informations d'identification au serveur. rkt prend en charge différents régimes d'authentification avec des fichiers de configuration. La documentation de configuration décrit le format de fichier et donne des exemples de configuration de l'authentification avec l'authentification de base HTTP, les bearer token OAuth et d'autres méthodes.

 

L'image dans le local

Il est possible de lister les fichiers hash identifiés sur disque dans le CAS de rkt :

  1. $ find /var/lib/rkt/cas/blob/
  2. /var/lib/rkt/cas/blob/
  3. /var/lib/rkt/cas/blob/sha512
  4. /var/lib/rkt/cas/blob/sha512/1e
  5. /var/lib/rkt/cas/blob/sha512/1e/sha512-7d28419b27d5ae56cca97f4c6ccdd309c95b967ca0119f6962b187d1287ec9967f49e367c36b0e44ecd73675bc06d112dec86386d0e9b84c2265cddd45d15020

 

Selon la spécification App Container, le hachage SHA-512 est celui du fichier tar compressé dans l'ACI, et peut être examiné avec des outils standard :

  1. $ wget https://github.com/coreos/etcd/releases/download/v3.1.7/etcd-v3.1.7-linux-amd64.aci
  2. ...
  3. $ gzip -dc etcd-v3.1.7-linux-amd64.aci >  etcd-v3.1.7-linux-amd64.tar
  4. $ sha512sum etcd-v3.1.7-linux-amd64.tar
  5. 7d28419b27d5ae56cca97f4c6ccdd309c95b967ca0119f6962b187d1287ec9967f49e367c36b0e44ecd73675bc06d112dec86386d0e9b84c2265cddd45d15020  etcd-v3.1.7-linux-amd64.tar
  6. Running an ACI with rkt

 

Exécution d'un ACI avec rkt 

Après avoir été récupéré et stocké localement, un ACI peut être lancé en pointant rkt sur la référence de l'image originale (dans ce cas, coreos.com/etcd:v3.1.7), le hachage ACI, ou l'URL complète du ACI. Les trois exemples suivants sont donc équivalents:

 

Exécution du conteneur par nom et version ACI

  1. $ sudo rkt run coreos.com/etcd:v3.1.7
  2. ...
  3. Press ^] three times to kill container

 

Exécution du conteneur par hachage ACI

  1. $ sudo rkt run sha512-1eba37d9b344b33d272181e176da111e
  2. ...
  3. ^]]]

 

Exécution du conteneur par l'URL ACI

  1. $ sudo rkt run https://github.com/coreos/etcd/releases/download/v3.1.7/etcd-v3.1.7-linux-amd64.aci
  2. ...
  3. ^]]]

 

Lorsqu'une URL ACI est donnée, rkt effectue la vérification ETag appropriée pour récupérer la dernière version de l'image du conteneur.

 

Quitter les pods rkt

Comme indiqué ci-dessus, répéter le caractère d'échappement ^] à trois reprises tue le pod et se détache de sa console pour revenir au shell de l'utilisateur.

 

Le caractère d'échappement ^] est généré par Ctrl-] sur un clavier américain. La combinaison de touches requise sera différente sur les autres dispositions de clavier. Par exemple, la disposition du clavier suédois utilise Ctrl-å sur OS X ou Ctrl- ^ sur Windows pour générer le caractère d'échappement ^].

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *