OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent

Components · Compute and capacity

Zun

Containers as a Service: one Pod per container, isolated in its own Kata microVM, with its Neutron port as its only network.

Go Kata Podsopenkeel-zun

The 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.

  • Go module: github.com/openkeel/openkeel-zun
  • One image, four executables:
ExecutableKubernetes objectRolePython process it replaces
zun-apiDeployment (port 9517, admin 9090)REST API, scheduling through Placement, synchronous Kubernetes calls (logs, exec, top, stats, archives)zun-api
zun-computeDeployment, one active replica (Lease)runs the queued operations: Neutron ports, Cinder attachments, Pods; state syncthe container work of zun-compute
zun-compute-agentDaemonSetzun-compute service heartbeat, compute_node row, Placement inventory of its nodethe inventory and service parts of zun-compute
zun-wsproxyDeployment (port 6784)attach and interactive exec WebSocketszun-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

Excerpt from openkeel-zun/README.md (in English).

REST API

73 operations of the original REST API (routes and body actions), and their state in OpenKeel.

  • 69Implemented
  • 4Partial

How compatibility is tested

Exchanges recorded from Python Zun's API tests and probes of the real Pecan application are replayed against the Go service, with algorithm vectors and a controller test on a fake cluster.

Replay of recorded exchanges

E2E replay of recorded API tests

The 256 exchanges of 221 Python API tests give the same status and body, each on a database seeded as the recorded test implied.

How it runs

make e2e (test/e2e), report in report.json; make e2e-strict fails on any difference not listed in known-differences.txt.

Latest result 223 / 256 identical; strict mode passes, the 35 differences listed with their reason.

Source: openkeel-zun/docs/CONFORMANCE.md

Replay of recorded exchanges

Probes of the real Pecan application

Requests sent to the real Python application, outside its unit tests, get the same answers from the Go service.

How it runs

Replay of test/e2e/testdata/zun.probes.json in the e2e suite.

Latest result 30 / 32; the 2 others are Python defects fixed on purpose (traps T7, T13).

Source: openkeel-zun/docs/CONFORMANCE.md

Unit and golden tests

Algorithm vectors from Python

Image name parsing, pull decisions, Docker state mapping, Placement queries, restart policy and port rules match the Python functions.

How it runs

internal/zun/vectors_test.go on _rewrite/vectors_stable-2026.2.json.

Latest result 8 / 8 families, 307 cases.

Source: openkeel-zun/docs/CONFORMANCE.md

Unit and golden tests

Container lifecycle on a fake cluster

Create, schedule, claim, Neutron ports, Kata Pod, stop and delete leave the same records as Python, ports and allocations included.

How it runs

internal/compute/manager_test.go with Kubernetes fakes.

Latest result Pass.

Source: openkeel-zun/docs/CONFORMANCE.md

Left out of the rewrite

Zun keeps its v1 API but runs containers as Kubernetes Pods in Kata VMs, so Docker-specific operations and the Docker, CNI and Kuryr node stack are gone.

Done by the Cloud Native platform

Docker daemon, zun-cni and kuryr-libnetwork

Taken over by Kubernetes Pods, Kata Containers

Why it was left out

Containers are Pods placed by Placement and isolated in Kata VMs; Neutron ports attach through the OVN CNI, and the kubelet pulls images and mounts Cinder PVCs.

Why the solution is not affected

python-zunclient, openstack appcontainer, Skyline and Heat keep working against the same API; the node stack is the cluster's own.

Source: openkeel-zun/README.md

Done by the Cloud Native platform

Pause, unpause and commit

Taken over by Kubernetes

Why it was left out

Kubernetes has no freezer or commit API; adding them would need a node agent with root access to containerd or cgroups, which OpenKeel refuses (decision 2026-11-02).

Why the solution is not affected

These actions answer 409 container.operation-not-supported. Images are built in a registry; running containers are unaffected.

Source: openkeel-zun/docs/CONFORMANCE.md

Done by the Cloud Native platform

Writable layer kept across stop

Taken over by Kubernetes

Why it was left out

Kubernetes has no stopped Pod that can start again: stop deletes the Pod and start creates a new one.

Why the solution is not affected

The container filesystem and logs are lost on stop. Data kept in Cinder volumes survives stop, start, reboot and rebuild, which is the documented practice.

Source: openkeel-zun/README.md

Done by the Cloud Native platform

Docker image search, docker load, Docker networks

Taken over by Kubernetes (kubelet)

Why it was left out

There is no daemon to search, load archives or create networks; kubelets pull from registries and Pods attach Neutron ports directly.

Why the solution is not affected

Image search returns only exact references, Glance images need an OCI reference, and network create only records a row. Container networking itself is Neutron's.

Source: openkeel-zun/README.md

Done by the Cloud Native platform

DISK_GB claim in Placement

Taken over by Kubernetes (ephemeral-storage)

Why it was left out

No OpenKeel provider publishes DISK_GB, root disks being PVCs; the claim would put every container with a disk in Error.

Why the solution is not affected

The disk becomes the Pod's ephemeral-storage request and limit: the kubelet places and caps it, as Docker's storage-opt did. CPU and memory are still claimed in Placement.

Source: openkeel-zun/docs/CONFORMANCE.md

Internal machinery simplified

RabbitMQ RPC to zun-compute

Why it was left out

The API queues each asynchronous operation in a database table that zun-compute claims by compare-and-set; one active zun-compute holds a Lease.

Why the solution is not affected

No RabbitMQ is needed for Zun and the API is unchanged; a crashed worker's task is taken over.

Source: openkeel-zun/README.md

Only what was left out by design is listed here; the work not done yet is in the Known gaps of the module's docs/CONFORMANCE.md. Every module

Zun interactions

Service view generated by the diagram skill from the OpenKeel model.

Diagram openkeel-zun.svg Full screen
The 8 interactions of the model
FromToProtocolWhat
Zun APIPlacementREST APIallocation candidates, claims
Zun APIKubernetes API serverKubernetes APIlogs, exec, top, resize, metrics
Zun computeNeutron serverREST APIports bound to host (compute:zun)
Zun computeCinder APIREST APIattachments → kubernetes_pvc
Zun computeKubernetes API serverKubernetes APIPods (Kata RuntimeClass), NADs, Secrets
Zun compute agentPlacementREST APIinventory (Node UID provider)
Zun compute agentKubernetes API serverKubernetes APINode allocatable, Pods
Zun wsproxyKubernetes API serverKubernetes APIattach, exec (WebSockets)

Specifications