Containers as a Service : un Pod par conteneur, isolé dans sa microVM Kata, avec son port Neutron comme seul réseau.
Go Pods Kataopenkeel-zun
Le module
OpenKeel implementation in Go of OpenStack Zun (containers service), generated from the reverse-specification of branch stable/2026.2 (reverse-spec-zun/) by the generate-go-from-spec skill. The Zun v1 API (microversions 1.1 to 1.40) is kept byte-compatible, so python-zunclient, openstack appcontainer, Skyline, Heat and gophercloud keep working unchanged. The node side is replaced: containers run as Kubernetes Pods, isolated in Kata Containers VMs by default, on the node that Placement chose, as openkeel-nova runs VMs on KubeVirt.
What is reproduced and what differs is in docs/CONFORMANCE.md and in § Compatibility gaps below; the security checklist is docs/SECURITY.md.
runs the queued operations: Neutron ports, Cinder attachments, Pods; state sync
the container work of zun-compute
zun-compute-agent
DaemonSet
zun-compute service heartbeat, compute_node row, Placement inventory of its node
the inventory and service parts of zun-compute
zun-wsproxy
Deployment (port 6784)
attach and interactive exec WebSockets
zun-wsproxy
zun-cni, zun-cni-daemon, Docker, containerd CRI and kuryr-libnetwork are gone. There is no RabbitMQ: the API queues each asynchronous operation in the openkeel_task table, which zun-compute claims by compare-and-set.
Configuration: YAML, see config/config.example.yaml (dropped oslo options and why: config/dropped-options.md)
Development environment, database and tests: docs/GETTING-STARTED.md
Database schema, migrations and upgrades: docs/DATABASE.md
Integration with openkeel-nova (one change to its agent): docs/NOVA-INTEGRATION.md
Extrait de openkeel-zun/README.md (en anglais).
API REST
73 opérations de l'API REST d'origine (routes et actions de corps), et leur état dans OpenKeel.
Les échanges enregistrés depuis les tests d'API de Zun Python et les sondes de la vraie application Pecan sont rejoués contre le service Go, avec des vecteurs d'algorithme et un test du contrôleur sur un faux cluster.
Rejeu des échanges enregistrés
Rejeu E2E des tests d'API enregistrés
Les 256 échanges de 221 tests d'API Python donnent le même statut et le même corps, chacun sur une base de données alimentée comme le test enregistré l'impliquait.
Exécution
make e2e (test/e2e), rapport dans report.json ; make e2e-strict échoue sur toute différence non listée dans known-differences.txt.
Dernier résultat 223 / 256 identiques ; le mode strict réussit, les 35 différences sont listées avec leur raison.
Source : openkeel-zun/docs/CONFORMANCE.md
Rejeu des échanges enregistrés
Sondes de la vraie application Pecan
Les requêtes envoyées à la vraie application Python, hors de ses tests unitaires, obtiennent les mêmes réponses du service Go.
Exécution
Rejeu de test/e2e/testdata/zun.probes.json dans la suite e2e.
Dernier résultat 30 / 32 ; les 2 autres sont des défauts Python corrigés volontairement (pièges T7, T13).
Source : openkeel-zun/docs/CONFORMANCE.md
Tests unitaires et golden tests
Vecteurs d'algorithme issus de Python
L'analyse des noms d'image, les décisions de pull, la correspondance des états Docker, les requêtes Placement, la politique de redémarrage et les règles de ports correspondent aux fonctions Python.
Exécution
internal/zun/vectors_test.go sur _rewrite/vectors_stable-2026.2.json.
Dernier résultat 8 / 8 familles, 307 cas.
Source : openkeel-zun/docs/CONFORMANCE.md
Tests unitaires et golden tests
Cycle de vie des conteneurs sur un faux cluster
Création, ordonnancement, réservation, ports Neutron, Pod Kata, arrêt et suppression laissent les mêmes enregistrements qu'en Python, ports et allocations compris.
Exécution
internal/compute/manager_test.go avec des simulacres Kubernetes.
Dernier résultat Réussi.
Source : openkeel-zun/docs/CONFORMANCE.md
Écarté de la réécriture
Zun conserve son API v1 mais exécute les conteneurs comme des Pods Kubernetes dans des VM Kata : les opérations propres à Docker et la pile de nœud Docker, CNI et Kuryr disparaissent.
Assuré par la plateforme Cloud Native
Démon Docker, zun-cni et kuryr-libnetwork
Repris par Pods Kubernetes, Kata Containers
Pourquoi c'est écarté
Les conteneurs sont des Pods placés par Placement et isolés dans des VM Kata ; les ports Neutron se rattachent via le CNI OVN, et le kubelet tire les images et monte les PVC Cinder.
Pourquoi la solution n'est pas affectée
python-zunclient, openstack appcontainer, Skyline et Heat continuent de fonctionner avec la même API ; la pile de nœud est celle du cluster.
Source : openkeel-zun/README.md
Assuré par la plateforme Cloud Native
Pause, unpause et commit
Repris par Kubernetes
Pourquoi c'est écarté
Kubernetes n'a pas d'API de gel ni de commit ; les ajouter exigerait un agent de nœud avec un accès root à containerd ou aux cgroups, ce qu'OpenKeel refuse (décision du 2026-11-02).
Pourquoi la solution n'est pas affectée
Ces actions répondent 409 container.operation-not-supported. Les images se construisent dans un registre ; les conteneurs en cours d'exécution ne sont pas concernés.
Source : openkeel-zun/docs/CONFORMANCE.md
Assuré par la plateforme Cloud Native
Couche inscriptible conservée à l'arrêt
Repris par Kubernetes
Pourquoi c'est écarté
Kubernetes n'a pas de Pod arrêté qui puisse redémarrer : stop supprime le Pod et start en crée un nouveau.
Pourquoi la solution n'est pas affectée
Le système de fichiers et les logs du conteneur sont perdus à l'arrêt. Les données conservées dans des volumes Cinder survivent à stop, start, reboot et rebuild, ce qui est la pratique documentée.
Il n'y a pas de démon pour rechercher, charger des archives ou créer des réseaux ; les kubelets tirent depuis des registres et les Pods se rattachent directement aux ports Neutron.
Pourquoi la solution n'est pas affectée
La recherche d'images ne renvoie que les références exactes, les images Glance nécessitent une référence OCI, et la création de réseau ne fait qu'enregistrer une ligne. Le réseau des conteneurs relève de Neutron.
Source : openkeel-zun/README.md
Assuré par la plateforme Cloud Native
Réservation DISK_GB dans Placement
Repris par Kubernetes (ephemeral-storage)
Pourquoi c'est écarté
Aucun provider OpenKeel ne publie DISK_GB, les disques racine étant des PVC ; la réservation mettrait en Error tout conteneur doté d'un disque.
Pourquoi la solution n'est pas affectée
Le disque devient la request et la limit d'ephemeral-storage du Pod : le kubelet le place et le plafonne, comme le faisait le storage-opt de Docker. CPU et mémoire restent réservés dans Placement.
Source : openkeel-zun/docs/CONFORMANCE.md
Mécanique interne simplifiée
RPC RabbitMQ vers zun-compute
Pourquoi c'est écarté
L'API met chaque opération asynchrone en file dans une table que zun-compute réserve par compare-and-set ; un seul zun-compute actif détient un Lease.
Pourquoi la solution n'est pas affectée
Aucun RabbitMQ n'est nécessaire pour Zun et l'API est inchangée ; la tâche d'un worker tombé est reprise.
Source : openkeel-zun/README.md
Seul ce qui a été écarté par choix de conception figure ici ; le travail pas encore fait se trouve dans les Known gaps du docs/CONFORMANCE.md du module. Tous les modules
Interactions de Zun
Vue « service » générée par la skill diagramme depuis le modèle d'OpenKeel.