Containers

Cet article est une comparaison entre différents registres (registry) docker que vous pouvez héberger vous-même.

Public visé: Administrateurs systèmes, DevOps familiers avec l’écosystème docker, et généralement ceux qui souhaitent en savoir plus sur les registres docker.

Par Quentin Anglade, chargé d’études sécurité @ Objectif Libre

Tests : registres Docker à héberger

Le hub docker est parfait si vous avez du temps pour récupérer vos images, si vous n’avez pas besoin d’héberger des images privées ou si les offres payantes du docker hub vous conviennent.

Vous avez peut-être besoin d’un registre privé, rapide, capable de détecter des vulnérabilités ou d’un registre sur votre réseau isolé. Ou bien vous avez peut-être votre propre infrastructure et vous ne voulez pas payer des SaaS puisque vous pouvez l’héberger vous-même.

Quelle que soit votre situation, si vous utilisez docker, vous avez probablement besoin d’un registre. Cet article compare 3 registres docker open source que vous pouvez héberger vous-même.

Harbor

Fonctionnalités

Développé par VMware, ce « enterprise-class registry server » est bien plus qu’un simple registre. Voici ses principales fonctionnalités:

  • Role based access control : les utilisateurs et dépôts sont organisés par projet et chaque utilisateur peut avoir des permissions différentes pour les images d’un projet
  • Policy based image replication : les images peuvent être répliquées / synchronisées entre plusieurs instances Harbor. C’est utile pour des situations de load-balancing, haute disponibilité, multi-datacentres ou multi-clouds
  • Vulnerability Scanning : Harbor peut scanner vos images et avertir les utilisateurs et/ou empêcher l’image d’être téléchargée (docker pull)
  • LDAP/AD support : vous pouvez utiliser votre serveur LDAP ou Active Directory pour l’authentification de vos utilisateurs
  • Image deletion & garbage collection : Habor supprime automatiquement les données inutiles pour récupérer de l’espace disque
  • Notary : vous pouvez signer vos images pour assurer leur authenticité / intégrité
  • Graphical user portal : les utilisateurs peuvent naviguer, chercher et gérer les projets via l’interface web
  • Auditing : toutes les opérations des utilisateurs sont enregistrées
  • RESTful API : APIs pour la plupart des opérations administratives, facilement intégrables avec des services externes
  • Easy deployment : installation disponible en ligne ou hors-ligne via des installateurs

Installation

L’installation d’Harbor n’est pas si facile. L’installateur hors-ligne est très pratique pour les environnements avec un accès réseau restreint, mais vous aurez probablement à modifier cet installateur pour répondre à vos besoins – sauf si vous utilisez des outils VMware pour votre cloud, auquel cas vous pouvez utiliser le fichier OVA fourni.

Vous pouvez télécharger l’installateur sur github.

Le fichier Harbor.cfg , accompagné d’un script d’installation, doit être exécuté chaque fois que vous voulez changer la configuration de Harbor. Ce script s’occupe de générer les fichiers de configuration et les certificats. Seul bémol, ce script n’est pas conteneurisé. Si vous n’avez pas python2 comme interpréteur par défaut, il vous faudra changer le shebang à la première ligne du script prepare. Et si vous n’avez pas python2 dans votre environnement de déploiement (une distribution moderne qui déprécie python2 ou une distribution orientée conteneurs telle que Container Linux par exemple), vous devrez soit l’installer, soit pré-configurer harbor sur une autre machine, soit conteneuriser vous-même le script.

Le script prepare a dû être modifié pour fonctionner sur ma machine : il ne pouvait pas générer les certificats, et donnait un message d’erreur un peu vague. Après quelques minutes de débug bas niveau à base de print, je suis tombé sur cette issue github avec les instructions pour patcher le script. C’est dommage, car c’est exactement le type de problèmes que résout docker. Notez que ceci n’est nécessaire que si vous n’utilisez pas vos propres certificats HTTPS (un déploiement de test sur votre machine par exemple).

Par défaut, Harbor stocke toutes ses données dans le dossier /data. Il n’est pas possible de changer ce chemin dans le fichier de configuration Harbor.cfg. Si vous avez besoin d’utiliser un autre chemin, vous devrez éditer tous les fichiers docker-compose. Également, tous les logs des conteneurs sont stockés via un conteneur syslog qui stocke lui-même ses logs dans le /var/logde l’hôte.

Après toutes ces modifications, j’ai lancé le script install.sh et Harbor était lancé, avec une erreur 502 au niveau du reverse proxy. J’ai essayé de changer le chemin de la secretkey dans le fichier de configuration, mais cela n’a pas changé le chemin dans les fichier docker-compose. J’ai dû supprimer le dossier /data/secretkey créé par les volumes docker et je l’ai remplacé par la clé qui avait été générée au chemin original que j’avais spécifié dans le fichier de configuration.

Si vous comptez déployer Harbor derrière un reverse proxy, vous devrez probablement enlever la ligne proxy_set_header X-Forwarded-Proto $$scheme; dans le fichier common/templates/nginx/.

J’ai ensuite réussi à me connecter sur l’interface web et à changer le mot de passe par défaut. Ce déploiement est au final assez poussif. Harbor est pensé pour fonctionner sur une machine virtuelle, ce qui semble logique pour un produit VMware.

Utilisation

Tout comme n’importe quel registre docker, un simple docker login domain.tld et vous pouvez utiliser le registre:

docker build -t myawesomeimage .
docker tag myawesomeimage domain.tld/project/image:tag
docker push domain.tld/project/image:tag

L’interface graphique est simple et efficace, vous pouvez faire ce dont vous avez besoin en quelques clics.

Clair, le scanner de vulnérabilités fait par CoreOS, est très bien intégré. Il y a une bonne visibilité des vulnérabilités par conteneur, avec la possibilité de scanner les images lorsqu’elles sont poussées, et empêcher qu’elles soient téléchargées si elles dépassent un seuil paramétrable de vulnérabilité.

Vous pouvez utiliser votre LDAP/AD pour vos utilisateurs, chaque action est enregistrée:

Vous pouvez rendre un dépôt public pour que quiconque puisse télécharger l’image et avoir accès aux détails du dépôt dans un navigateur avec la même URL.

L’API REST a l’air correcte et vous avez même droit à swagger pour vous simplifier la vie.

Le serveur notary intégré est une belle addition si vous voulez signer vos images, mais il est assez difficile de le faire fonctionner avec vos propres certificats.

Portus

Fonctionnalités

Portus est une interface utilisateur et serveur d’authentification pour un registre docker. Il est développé par SUSE et a des fonctionnalités intéressantes:

  • Permissions par utilisateur et par groupe
  • Interface web « user friendly »
  • Synchronisation avec un registre privé
  • LDAP, OAuth et OpenID-Connect pour l’authentification des utilisaeurs
  • Monitoring de l’activité sur le registre et sur Portus lui-même
  • Recherche de repos et de tags
  • Possibilité de mettre en favoris vos dépôts préférés
  • Désactivation temporaire d’utilisateurs
  • Tokens d’applications utilisables pour plus de sécurité

Installation

L’installation est simple comparée à celle d’Harbor. La documentation comporte plusieurs exemples de déploiements, le plus simple étant via docker-compose. Il est également possible de le déployer avec kubernetes et helm.

Si vous voulez déployer Portus de manière sécurisée (HTTPS + scanner de vulnérabilités), vous trouverez un article dédié ici.

Tout comme Habor, si vous déployez Portus derrière un reverse proxy tel que Nginx, vous pourrez rencontrer des conflits au niveau des headers http, car Portus intègre lui-même un serveur Nginx.

Utilisation

Portus est comme votre propre hub docker, mais en mieux. Son interface est simple et fonctionne bien:

Tout comme Harbor, un simple docker login domain.tld:5000 suffit pour utiliser le registre avec docker. Harbor présente cependant l’avantage d’utiliser les mêmes URLs pour l’interface et le registre.

Portus fonctionne par utilisateurs, teams et namespaces. Un utilisateur peut avoir des namespaces, une team peut avoir des namespaces, et une team a bien sûr des utilisateurs. En d’autres termes, si vous créez un namespace « azerty », vous pousserez des images vers domain.tld:5000/azerty/image:tag. Vous pouvez consulter la documentation pour plus de détails.

Clair n’est pas aussi bien intégré à Portus qu’à Harbor. Vous ne pouvez pas scanner à la demande, empêcher des images vulnérables d’être téléchargées, voir si les bases de données des vulnérabilités sont à jour, etc. Portus peut vous indiquer des images comme étant non vulnérables alors que le serveur clair n’a simplement pas eu le temps de télécharger les bases de données de vulnérabilités. Si vous ne voulez pas que les images vulnérables soient utilisées via Portus, vous pouvez utiliser son API REST dans votre intégration continue ou via un autre service.

L’interface des vulnérabilités est minimale:

Conclusion

Si tout fonctionne bien avec Portus et que son déploiement est facile, il n’est pas aussi personnalisable que Harbor. Il y a peu d’options configurables comparé à Harbor. Cependant, Portus reste efficace et son API peut vous permettre de combler son manque de personnalisation. Gardez en tête que Portus est un frontend d’un registre et non pas un registre en soi.

GitLab

Fonctionnalités

Gitlab propose un registre docker depuis la version 8.8. Il est directement intégré avec les projets Gitlab et propose les avantages suivants:

  • Authentification identique à Gitlab, les utilisateurs, groupes et projets sont respectés
  • Pas besoin de créer des dépôt sur le registre, chaque projet possède déjà son propre repository
  • Les projets ont un nouvel onglet, Container Registry, qui liste toutes les images relatives au projet
  • Possibilité d’activer / désactiver le registre par projet
  • Il est facile pour les développeurs de pousser et de récupérer des images depuis l’intégration continue
  • Pas besoin de télécharger / déployer un nouveau logiciel

Le but est bien sûr de l’utiliser avec l’intégration continue et le déploiement continu de Gitlab. Vous pouvez trouver quelques exemples d’utilisation ici.

Installation

On ne peut pas vraiment parler d’installation puisque le registre est intégré à Gitlab : il suffit de l’activer. Si vous avez une installation Gitlab omnibus, il y a une seule ligne à changer dans gitlab.rb:

registry_external_url 'https://gitlab.example.com:4443'

Vous aurez peut-être besoin de changer quelques lignes si vous voulez utiliser un domaine spécifique pour votre registre.

Si vous avez installé Gitlab depuis les sources, il vous faudra changer quelques lignes dans gitlab.yml comme décrit dans la documentation Gitlab.

Utilisation

Ici encore, un simple docker login suffit pour utiliser votre registre. Vous n’avez pas à gérer les utilisateurs, teams ou namespaces puisque tout est lié aux utilisateurs existants et à leurs permissions. Vous pouvez cependant supprimer les images depuis l’interface web de Gitlab :

Voici un « hello world » de l’utilisation du registre Gitlab dans une chaîne d’intégration continue, le fichier .gitlab-ci.yml tel que dans la documentation Gitlab :

build:
  image: docker:stable
  services:
  - docker:dind
  stage: build
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.example.com
    - docker build -t registry.example.com/group/project/image:latest .
    - docker push registry.example.com/group/project/image:latest

Il est facile d’automagiquement construire et pousser vos images docker vers le registre Gitlab avec quelques lignes.

Il n’y a pas de scanner de vulnérabilités intégré à Gitlab, sauf si vous souscrivez la version payante Gitlab Ultimate. Si vous voulez quand même scanner vos images pour vous assurer qu’elles ne sont pas vulnérables, vous pouvez le faire vous-même en suivant le guide.

Gitlab étant très personnalisable, vous pouvez aussi utiliser votre intégration continue avec d’autres registres tels que Harbor ou Portus.

Bonus: Openshift

Openshift est une plateforme de conteneurs open source développée par Red Hat, basée sur Docker et Kubernetes.

Si vous utilisez Openshift, vous avez probablement par défaut le registre docker d’Openshift : OCR (Openshift Container Registry). Pas besoin d’utiliser un registre différent, même si vous pouvez, puisque le registre OCR est particulièrement bien intégré à Openshift.

Lors d’une utilisation normale d’Openshift, vous n’avez pas à vous soucier du registre. Vous pouvez cependant y accéder, mais il n’y a en général pas de raison particulière de le faire.

Vous pouvez aussi déployer OCR en tant que registre indépendant, ce qui peut être utile principalement dans un scénario multi-clusters ou pour des raisons de sécurité.

Si vous n’utilisez pas Openshift, vous n’aurez probablement pas l’utilité d’OCR.

Conclusion

Si vous avez besoin d’un registre qui:

  • S’intègre avec votre LDAP/AD
  • Est sécurisé, avec un scanner de vulnérabilités
  • Permet de facilement signer des images avec notary

Harbor saura répondre à vos besoins, une fois mis en place.

Si vous voulez votre propre hub docker facile à déployer, supportant LDAP, permettant de vérifier la vulnérabilité des images, permettant l’interaction entre utilisateurs: Portus est fait pour vous.

Si vous utilisez Gitlab et voulez un registre qui marche, utilisez celui de Gitlab.

Si vous utilisez Openshift, vous êtes déjà équipé.

Pour tout autre besoin, un mélange de Gitlab/intégration continue et registre externe peut être une bonne solution.