Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for OpenStack By James Joyner IV · · 10 min read

Running Containers Directly on OpenStack with Zun

Zun runs containers as first-class OpenStack resources without a Kubernetes layer. Here's how to deploy, network, and debug Zun capsules with AI assistance.

  • #openstack
  • #zun
  • #containers
  • #kuryr
  • #deployment

Most people reach for Magnum and Kubernetes when they want containers on OpenStack, but sometimes that is a lot of machinery for a handful of workloads. Zun is the quieter option: it runs containers as native OpenStack resources, scheduled by Nova-style placement and networked through Neutron via Kuryr. I started using it for internal tooling that needed Neutron networking and Cinder volumes but did not justify a full cluster. It is genuinely useful, and genuinely under-documented, so here is the working guide I wish I had.

What Zun actually gives you

A Zun container is an OpenStack object with a UUID, a Neutron port, optional Cinder volumes, and quota accounting — the same primitives as a VM, but starting in seconds. You manage it with the same openstack CLI you already know.

openstack appcontainer service list
openstack appcontainer host list

If appcontainer service list shows zun-compute as up on your compute hosts, the plumbing is in place. The service list is the first thing I check, because a down zun-compute agent produces the same “nothing schedules” symptom as a Nova scheduler problem, and the two get confused constantly.

Launch your first container

Creating a container looks a lot like booting a server, which is the whole point. You pick an image, a network, and resource limits.

openstack appcontainer run \
  --name web1 \
  --net network=private \
  --cpu 1 --memory 512 \
  nginx:stable
openstack appcontainer show web1 -f value -c status -c addresses

The container pulls from a registry on the compute host and comes up with a real Neutron port. If it sticks in Creating, the cause is almost always the image pull or Kuryr failing to wire the port — both of which show up in the compute agent log rather than the API.

Pro Tip: Use openstack appcontainer logs <name> before you SSH anywhere. Half of “my container won’t start” tickets are an application crashing on a bad env var, and the container logs say so immediately.

Networking through Kuryr is where it gets interesting

Zun does not bridge containers the way Docker does on a laptop. Kuryr-libnetwork maps each container onto a Neutron port, so security groups, floating IPs, and subnets all behave like they do for instances.

openstack port list --device-owner kuryr | head
openstack appcontainer show web1 -f value -c addresses
openstack floating ip create public
openstack appcontainer add floating ip ... # via the associated port

When connectivity breaks, debug it as a Neutron problem, not a container problem. Check the security group on the Kuryr port, confirm the subnet has a route, and verify the port is ACTIVE. I have wasted time restarting containers when the real issue was a missing egress rule on the port’s security group.

Persistent data with Cinder

Stateless containers are easy; the value of Zun-on-OpenStack is attaching real block storage. You can mount a Cinder volume straight into a container.

openstack volume create --size 10 zun-data
openstack appcontainer run --name db1 \
  --mount source=zun-data,destination=/var/lib/data \
  --net network=private \
  postgres:16

This is where Zun beats running Docker by hand: the volume lifecycle, quotas, and multi-tenancy are all handled by Cinder and Keystone. If the mount fails, check that the volume is available and that zun-compute can reach the storage backend — the same iSCSI or RBD path Nova uses.

Let AI draft the boilerplate, not the decisions

Zun’s CLI is verbose and its docs are thin, which is exactly the situation where an AI assistant shines as a fast junior engineer. I describe what I want — “an nginx container on the private net with a 5 GB Cinder volume and a floating IP” — and have the model draft the openstack appcontainer run flags and the volume commands. It saves me flipping between three doc pages.

But I read every flag before running it, because the assistant will confidently invent options that do not exist in your release. I keep it on a strict diet: sanitized network names, no project tokens, never the clouds.yaml with real credentials. The model writes the candidate command; I diff it against openstack appcontainer run --help and execute it myself against a non-prod project first.

openstack appcontainer run --help | grep -E 'mount|net|security-group'

Cursor is handy when I am scripting Zun lifecycle automation in Python with the SDK, and the prompt workspace is where I keep the Zun command-builder prompt so I am not rewriting it each time. For ready-made versions, the prompt library has CLI-scaffolding prompts.

Capsules for multi-container workloads

A single container is fine for a service, but real workloads often need a sidecar — an app plus a log shipper, or a web server plus a cache. Zun’s answer is the capsule, a pod-like group of containers that share a network namespace and are scheduled together. It is the closest Zun gets to a Kubernetes pod, without the cluster.

openstack capsule create --template capsule.yaml
openstack capsule list
openstack capsule show <capsule-uuid> -f value -c status -c containers

The template is a small YAML spec listing the containers and their shared resources. Because the containers in a capsule share a network namespace, they reach each other over localhost, which makes the sidecar pattern trivial. When a capsule sticks in Creating, the failure is almost always one container in the group — capsule show lists each container’s individual status so you can see which one is dragging the rest down rather than guessing.

Quotas keep Zun from eating the cloud

Because Zun containers are first-class OpenStack resources, they consume real quota — vCPUs, memory, and Neutron ports — from the project. On a shared cloud, an unbounded container workload can quietly exhaust a tenant’s allocation and block VM launches, so I set and watch container quotas the same way I do for instances.

openstack quota show <project> -f value -c instances -c cores -c ram
openstack appcontainer list --all-projects -f value -c uuid -c project_id | wc -l

The gotcha is that container and instance quotas draw from overlapping pools on most deployments — a project that fills its core quota with containers cannot then boot a VM, and the error message points at Nova even though Zun is the culprit. Knowing the two share a budget saves a confusing round of “but I have no instances running.”

Debug a wedged container

When a container is Error or Dead, work from the agent outward. The container engine state, the Zun compute log, and the Neutron port together tell the whole story.

openstack appcontainer show web1 -f value -c status_reason
journalctl -u zun-compute -n 100 --no-pager
openstack port show <kuryr-port-uuid> -f value -c status

The status_reason field usually names the failure outright — image pull error, scheduling failure, or port binding failure — which routes you to the right subsystem without guessing.

Conclusion

Zun is the right tool when you want containers with native OpenStack networking, storage, and tenancy but not a Kubernetes control plane to babysit. Treat its failures as OpenStack failures — read the service list, the agent log, and the Neutron port — and you will diagnose them with skills you already have. An AI assistant is excellent at drafting Zun’s verbose commands and clustering its errors, a fast junior that accelerates the boring parts. Keep production credentials out of the prompt, verify generated flags against --help, and run destructive commands yourself. More on this stack under OpenStack.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.