6 points par GN⁺ 2024-11-24 | 1 commentaires | Partager sur WhatsApp
  • Bocker est un projet qui implémente Docker en environ 100 lignes de Bash et propose un flux proche de Docker avec pull d’images, exécution de conteneurs, consultation des logs, commit et suppression
  • Son exécution nécessite btrfs-progs, curl, iproute2, iptables, libcgroup-tools, util-linux 2.25.2 ou plus, coreutils 7.5 ou plus, ainsi qu’un système de fichiers btrfs sous /var/bocker et une configuration réseau bridge0
  • L’exemple du README montre un flux où l’on pull l’image centos:7, on exécute une commande dans le conteneur, puis on commit le résultat de yum install -y wget pour vérifier ensuite la présence de /usr/bin/wget
  • Bocker s’exécute en root et modifie les interfaces réseau, la table de routage et les règles du pare-feu ; il est donc recommandé de l’exécuter dans une machine virtuelle, sans garantie contre d’éventuels dommages sur le système
  • À ce jour, docker pull, images, ps, run, exec, logs, commit, rm/rmi, la mise en réseau et les quotas basés sur CGroups sont implémentés, mais les volumes de données, les conteneurs de volumes de données et la redirection de ports ne le sont pas encore

Objectif et périmètre de Bocker

  • Bocker est un projet qui implémente Docker en environ 100 lignes de Bash
  • Le README illustre un flux de commandes proche de Docker en Bash, avec gestion d’images, exécution de conteneurs, consultation des logs, commit des modifications et limitation des ressources

Exigences d’exécution

  • Les paquets nécessaires à l’exécution sont les suivants
    • btrfs-progs

      • curl
      • iproute2
      • iptables
      • libcgroup-tools
      • util-linux 2.25.2 ou plus
      • coreutils 7.5 ou plus
      • comme la plupart des distributions n’incluent pas une version suffisamment récente de util-linux, il peut être nécessaire de télécharger et compiler soi-même les sources de util-linux 2.25
      • Le système doit disposer de la configuration suivante
      • un système de fichiers btrfs monté sous /var/bocker
      • un pont réseau nommé bridge0 avec l’adresse IP 10.0.0.1/24
      • l’activation de l’IP forwarding dans /proc/sys/net/ipv4/ip_forward
      • des règles de pare-feu permettant d’acheminer le trafic de bridge0 vers l’interface physique
      • un Vagrantfile est fourni pour faciliter la création de l’environnement nécessaire

Précautions d’exécution

  • Même si les prérequis sont remplis, il est recommandé d’exécuter Bocker dans une machine virtuelle
  • Bocker s’exécute en root et doit modifier les éléments suivants
    • les interfaces réseau
    • la table de routage
    • les règles du pare-feu
  • Le README précise qu’il ne peut garantir que Bocker n’endommagera pas le système

Exemple de flux d’utilisation

  • bocker pull centos 7 permet de récupérer l’image centos:7 et génère un ID d’image comme img_42150
  • bocker images affiche l’ID de l’image et sa source
    • Exemple de sortie : img_42150, centos:7
  • bocker run img_42150 cat /etc/centos-release affiche les informations de version de CentOS depuis le conteneur
    • Exemple de sortie : CentOS Linux release 7.1.1503 (Core)
  • bocker ps affiche les ID des conteneurs lancés et la commande
  • bocker logs ps_42045 affiche les logs de sortie du conteneur concerné
  • bocker rm ps_42045 supprime le conteneur
  • Lors de l’exécution de bocker run img_42150 which wget, le résultat indique d’abord que wget n’est pas présent
  • Après installation de wget avec bocker run img_42150 yum install -y wget, bocker commit ps_42018 img_42150 permet de répercuter les modifications dans l’image
  • Ensuite, bocker run img_42150 which wget affiche /usr/bin/wget

Limitation des ressources et CGroups

  • L’exemple d’exécution de Bocker montre que le conteneur est placé sous CGroups
    • dans /proc/1/cgroup, on voit apparaître des entrées comme memory:/ps_42152, cpuacct,cpu:/ps_42152
  • Les exemples de part CPU par défaut et de limite mémoire sont les suivants
    • /sys/fs/cgroup/cpu/ps_42152/cpu.shares : 512
    • /sys/fs/cgroup/memory/ps_42152/memory.limit_in_bytes : 512000000
  • Il est possible de modifier les limites de ressources via des variables d’environnement
    • BOCKER_CPU_SHARE=1024
    • BOCKER_MEM_LIMIT=1024
  • Après modification, l’exemple montre les valeurs suivantes
    • CPU shares : 1024
    • limite mémoire : 1024000000

Fonctionnalités implémentées et non implémentées

  • Les fonctionnalités actuellement implémentées sont les suivantes
    • docker build
    • docker pull
    • docker images
    • docker ps
    • docker run
    • docker exec
    • docker logs
    • docker commit
    • docker rm / docker rmi
    • Mise en réseau

      • Quota Support / CGroups
      • bocker init fournit une implémentation très limitée de docker build
      • Les fonctionnalités pas encore implémentées sont les suivantes
      • Data Volume Containers
      • Data Volumes
      • Port Forwarding

Licence

  • Bocker est un logiciel libre pouvant être redistribué et modifié selon les termes de la GNU General Public License
  • La version de la licence peut être la GPL v3 publiée par la Free Software Foundation ou toute version ultérieure
  • Le programme est distribué dans l’espoir qu’il soit utile, mais sans aucune garantie implicite de qualité marchande ni d’adéquation à un usage particulier

1 commentaires

 
GN⁺ 2024-11-24
Avis de Hacker News
  • J’avais déjà créé quelque chose de similaire avec proot, qui s’appelait Bag [1], et je ne pense pas l’avoir présenté comme une alternative à Docker.
    Cela n’avait rien à voir avec les cgroups, et l’interface en ligne de commande était différente de celle de Docker. Le contexte, c’est que j’avais créé une chaîne de proxy qui ressemblait à du trafic HTML ordinaire pour contourner la censure sur Internet et l’inspection approfondie des paquets ; il fallait qu’elle puisse continuer à tourner partout, mais je ne voulais pas la porter en application native Android.
    Je voulais la faire tourner dans Termux, mais à l’époque Termux n’avait pas de JDK/JRE, tandis qu’en lançant un environnement Arch Linux avec proot, on pouvait utiliser le JDK. L’environnement Arch dans Termux était globalement plus utile, et il était aussi facile d’automatiser par script la création puis la suppression d’environnements jetables avec des configurations différentes, puis d’y entrer avec proot pour n’exécuter qu’une seule commande. Je l’ai donc nommé bag.sh, au sens d’une forme bien plus petite qu’un conteneur maritime.
    Fait amusant, bag.sh contient encore une roadmap/TODO que je n’ai pas touchée depuis cinq ans. Je l’avais rédigée sur un écran mobile, donc la plupart des lignes sont alignées sur 40 colonnes pour pouvoir les voir sans faire défiler.
    [1]: https://github.com/hkoosha/bag

    • Je pense qu’il y a eu pas mal d’histoires de ce genre. Dans une situation où une VM ne convenait pas et où il fallait empaqueter plusieurs composants dans un seul environnement, j’ai utilisé chroot et deb-bootstrap, puis créé un installateur avec makeself.
      J’avais créé dans /opt un petit Debian contenant les logiciels nécessaires et des dépendances comme MySQL ; cela fonctionnait plutôt bien et a été utilisé jusqu’à l’acquisition, vers 2016, de l’entreprise pour laquelle je l’avais fait. Plus généralement, je pense qu’implémenter soi-même une version rudimentaire d’une grosse application est l’une des meilleures façons d’en apprendre le fonctionnement interne.
    • On dirait qu’il manque quelques guillemets importants dans le script. Ce serait bien de passer shellcheck dessus.
      mkdir -p $(dirname "$2")
    • En mettant une tablette 8 pouces en mode paysage, on arrivait tout juste à obtenir quelque chose comme 80x22 à une taille réellement lisible.
      Avec un clavier Bluetooth d’environ 10 pouces qui rentre facilement dans la poche intérieure d’une veste en cuir, on peut sortir de chez soi sans sac, s’asseoir dans un coin d’un beer garden à proximité et écrire du code. C’est étonnamment productif aussi : peut-être parce qu’il y a un peu plus de friction que sur un ordinateur portable pour basculer vers les distractions habituelles, on finit par continuer à fixer le code en sirotant sa bière.
  • J’aime ce genre de choses. J’ai toujours aimé les réalisations en Bash minimal.
    Voici aussi une preuve de concept de répartiteur de charge interne à un cluster, en 40 lignes de Bash, réalisée lors d’un hackathon que nous avions organisé il y a environ 10 ans pour faire connaître des infrastructures distribuées comme Docker et Mesos : https://github.com/cell-os/metal-cell/blob/master/discovery/...
    Il est probablement perdu, mais il y avait aussi un outil de transfert colo-to-cloud basé sur des tunnels SSH inversés, avec redondance et distribution. Shell Fu et d’autres sites recensent bien ce genre de choses : https://www.shell-fu.org/

    • shell-fu.org est excellent, mais j’aimerais aussi voir les commentaires d’autres utilisateurs.
  • Le fait qu’on puisse réimplémenter aussi simplement une grande partie de Docker est le plus gros problème auquel Docker, l’entreprise, a été confrontée et continue de l’être. Fondamentalement, c’est surtout du code de liaison qui assemble des fonctionnalités du noyau.
    Là où Docker apporte vraiment de la valeur, ce n’est pas seulement Docker Hub, mais Docker for Windows et Mac. L’expérience intégrée est nettement meilleure que de devoir manipuler soi-même VirtualBox et Vagrant pour faire tourner Docker sur une machine de développement.

    • Rancher Desktop est aussi une option pratique, et gratuite. Après l’entrée en vigueur de la nouvelle licence de Docker, beaucoup d’endroits, y compris mon lieu de travail, sont passés dessus.
      Personnellement, je pense que la vraie magie de Docker était le format d’image Docker/OCI. C’est une excellente façon de gérer le cache et la distribution d’images de conteneurs, et cela reste l’élément clé qui distingue encore ce workflow d’une VM « complète ».
    • Docker Desktop sur Mac est un bazar plein de contraintes et dépourvu de permissions suffisantes. Utiliser le CLI Docker avec Colima sur Mac a aussi des contraintes de permissions, mais au moins on évite la licence absurde et l’interface graphique de Docker.
      Sous Windows, on peut utiliser Docker dans WSL et cela fonctionne très bien. J’ai du mal à comprendre pourquoi on utiliserait Docker Desktop.
    • Sur macOS, j’utilise simplement Colima : l’expérience est bien meilleure et c’est beaucoup plus léger.
    • Non, Docker aurait dû créer en priorité un PaaS comme CloudRun, Render ou Fly, et le vendre cher aux entreprises.
      À la place, ils ont créé ce Docker Swarm bancal qui ne fonctionnait pas correctement de manière fiable, et Kubernetes les a rapidement dépassés.
    • Parmi les systèmes populaires et rentables, beaucoup peuvent être réimplémentés « facilement ». Je pensais que la valeur de Docker résidait dans les images Docker, et j’ai l’impression que c’est ainsi que Docker est utilisé.
      Pour ma part, je ne m’en suis servi que pour récupérer l’environnement de build virtuel de quelqu’un afin de compiler un logiciel, il y a quelques années.
  • Il y a dans le dépôt des mentions comme « pas encore implémenté », « TODO », « en cours », et voir que le dernier commit date d’il y a plusieurs années, ça fait du bien.
    Ça me rassure un peu sur le fait de ne pas retourner voir les TODO que j’ai disséminés dans mon code. Ce n’est pas pour rabaisser l’auteur, c’est juste réconfortant.

    • Bon point. Ce n’est pas du tout du dénigrement ; au contraire, c’est bien parce que ça normalise ce genre d’état.
      Dans du code non rémunéré, bénévole ou de hobby, si l’on ressent l’obligation de faire simplement parce qu’il est public, le codage devient moins agréable, et on peut finir par ne plus publier du code qu’on aurait autrement rendu public.
    • J’ai l’impression que la plupart des projets, peut-être même tous, ne se terminent jamais. Savoir quand s’arrêter est important.
    • Je trouve ça bien. Quelque chose peut simplement être terminé ; on n’a pas toujours besoin d’avoir plein d’idées suivantes, même si en général il y en a toujours.
      S’il y a toujours une idée suivante, alors par définition il restera toujours des TODO inachevés. En fait, cela devrait être l’état normal de tous les projets.
    • Quand on démarre un projet, il est utile de passer du temps à réfléchir aux « non-objectifs », c’est-à-dire aux fonctionnalités qui viennent à l’esprit mais qu’on choisit délibérément de ne pas implémenter.
      Définir clairement les limites du périmètre est tout à fait acceptable et souvent utile. Cela évite de poursuivre des pistes secondaires et d’avoir éternellement l’impression que le projet n’est jamais « terminé ».
    • C’est tout à fait normal. Le programme fait ce que je veux, et quand mon travail est fini, j’arrête le développement. Le logiciel n’est pas mon hobby.
  • Je suis surpris que lazydocker n’ait pas encore été mentionné comme excellente alternative à Docker Desktop. Il fonctionne sous Linux/macOS/Windows [1].
    C’est une interface terminal assez riche en fonctionnalités, avec aussi l’avantage de pouvoir être exécutée via SSH.
    [1] https://github.com/jesseduffield/lazydocker

    • Il a été posté littéralement il y a quelques jours : https://news.ycombinator.com/item?id=42214873
    • Lazydocker a clairement l’air intéressant, mais mettre dans le README.md d’un projet open source une publicité d’autopromotion pour un produit d’un domaine complètement différent, c’est un peu abusé.
      En tout cas, c’est la première fois que je vois ça. Je me demande aussi si ce genre de publicité est autorisé par les conditions d’utilisation ou la politique d’usage acceptable de GitHub.
  • Je me demande pourquoi Bocker revient si souvent en une. En 2024, Docker est-il encore à ce point controversé ?
    Je ne comprends pas pourquoi on ne reconnaît pas que Docker a apporté quelque chose de réellement utile, principalement pour la distribution de logiciels et le « ça tourne facilement partout ».

    • Ce n’est qu’un outil pédagogique pour voir comment Docker fonctionne.
      Docker est une combinaison de technologies du noyau qui existaient déjà : namespaces, cgroups, systèmes de fichiers union, et probablement quelques autres.
    • S’il revient souvent en une, c’est parce que beaucoup de gens pensent que Docker est quelque chose d’extrêmement complexe, alors qu’au niveau le plus fondamental il est en réalité assez élégant et compréhensible.
      C’est donc intéressant, et c’est pratiquement l’histoire HN parfaite.
    • Ce n’est peut-être pas en une pour dénigrer Docker, mais parce que des gens voient que Docker est utile et veulent savoir comment il fonctionne. Bocker peut servir de porte d’entrée vers ces technologies.
    • Au travail, pour réduire un long pipeline CI, j’ai présenté overlayfs, et tout le monde a été surpris par le gain de vitesse.
      Ce n’est qu’après l’avoir montré à quelques personnes que j’ai réalisé qu’elles auraient pu simplement utiliser /, ou bien que j’aurais pu leur apporter Docker.
  • Dans le genre frère d’une autre mère, il y a https://bastillebsd.org/.
    Bastille utilise en shell beaucoup de structures qu’on s’attendrait à voir dans Docker pour gérer les jails FreeBSD. Il a très peu de dépendances, ce qui me le fait préférer à d’autres logiciels de gestion de jails sous BSD.

    • cbsd est aussi assez impressionnant : shttps://www.bsdstore.ru/en/about.html
      Cela dit, même si c’est un outil CLI/TUI, c’est une solution proche du « maximum d’excès ». Ces temps-ci, je passe par les étapes de création et de gestion des jails uniquement avec la configuration de base de FreeBSD, mais ce n’est qu’une phase temporaire.
      Je continuerai seulement jusqu’à avoir suffisamment gravé dans ma tête la façon dont tout s’imbrique pour être à l’aise en debug ; ensuite, comme une personne raisonnable, j’arrêterai de taper des cailloux les uns contre les autres et je reviendrai à des outils de plus haut niveau.
    • Oui. Pour un script shell d’environ 100 lignes, il apporte beaucoup de valeur.
      En revanche, il m’a fallu un moment pour comprendre pourquoi il s’appelait Bastille. La Bastille était une forteresse construite pendant la guerre de Cent Ans pour défendre Paris contre les attaques anglaises, puis elle a été transformée en prison.
  • Il faut faire attention à la partie disant que « la plupart des distributions ne fournissent pas une version suffisamment récente de util-linux, donc il faudra récupérer les sources ici et compiler soi-même ».
    Le préfixe d’installation par défaut étant /usr/bin, l’installation peut écraser la commande mount existante par une version qui exige des bibliothèques inexistantes. Au démarrage suivant, le noyau montera alors le système de fichiers en lecture seule.

    • Ça devrait être /usr/local/bin.
  • Ce n’est pas idéal pour un usage quotidien, mais ça donne une idée de ce qu’est Docker et de son fonctionnement.
    Sous Linux, Docker est fondamentalement un chroot sophistiqué.

    • Sous macOS/Windows, Docker est fondamentalement un chroot sophistiqué dans une VM Linux.
  • Fait amusant : Docker a commencé en Bash, puis a été porté en Python avant de finalement se fixer sur Go.
    Et lors d’un meetup Docker en 2013, quelqu’un avait écrit un clone de Docker en Bash. Les gens veulent apprendre, et j’espère que ce genre de choses les aide.