Kubernetes on OpenStack: what the integration connects and who it serves
A platform team that already runs OpenStack and needs Kubernetes clusters to draw compute, storage, load balancing and identity from it should plan around one supported method: the OpenStack Cloud Controller Manager, shipped as cloud-provider-openstack, paired with CSI drivers for Cinder and Manila, Octavia for ingress, and Keystone for identity. Each piece covers a different part of the cloud, and the combination is assembled from open-source components rather than bought as one product, so the team owns the build, the configuration and the upgrade order. The Cloud Controller Manager connects the Kubernetes control plane to OpenStack. It registers nodes against Nova instances, keeps node metadata current and provisions cloud resources when Kubernetes asks for them. The Cinder CSI driver supplies block volumes for PersistentVolumeClaims, which suits single-writer workloads such as databases. The Manila CSI driver supplies shared file systems for workloads that need several pods to mount the same volume. Whether Manila can offer multi-writer access depends on the share backend you run, so confirm the access modes it supports before you promise shared storage to application teams.
Octavia fulfills Kubernetes Services of type LoadBalancer and typically fronts the ingress controller, so external traffic reaches the cluster through a load balancer you operate inside your OpenStack project. Confirm which Octavia provider and listener protocols your release exposes, and which health monitor types your network team accepts, before you fix the ingress design. Keystone handles identity in two places: the cloud credentials the controllers use to call OpenStack APIs, and the human sign-in path that a platform team may want to connect to Kubernetes. Keystone federation supports SAML 2.0 and OpenID Connect, so an organization can route employee sign-in through its own identity provider with mapping rules that decide group and role membership.
The people this integration serves are not only the platform team. Security engineers need to know which OpenStack credentials the controllers hold and how far those credentials reach. Application teams need predictable storage classes and load balancers that they can request without filing tickets. Compliance leads need evidence that Secrets are protected: Kubernetes stores Secrets unencrypted in etcd by default, so encryption at rest must be configured deliberately, and the Barbican-backed key path is one option to evaluate. Confirm with your release documentation how the key management integration is wired and who can rotate its keys.
Before the build starts, the team should inventory which OpenStack services are deployed, at which versions and endpoints, and which projects, quotas and networks each cluster will use. Decide early whether clusters map to one OpenStack project per environment or per business unit, because that choice sets credential scope, quota boundaries and the blast radius of a misconfigured controller. Write these decisions down with the platform owners so the later sections on build sequence, verification and operations start from a settled picture of what the integration connects.
Prerequisites for Kubernetes on OpenStack before any cluster is built
Most failed Kubernetes on OpenStack builds trace back to decisions made before the first node boots: which releases are paired, which account the cloud provider uses, how the network is laid out and how the API is reached. The cards below cover these checks in the order a platform team should settle them, so the cluster build starts from a documented baseline.
Choose a maintained OpenStack release
Start with an OpenStack release that is still maintained when the cluster will go live. The current references are 2026.1 Gazpacho, a SLURP release released on 2026-04-01, plus the maintained 2025.2 Flamingo and 2025.1 Epoxy releases. Record the release you select, because the cloud-provider-openstack version, the Octavia and Cinder APIs and the upgrade path all depend on it. Plan for a SLURP target so later upgrades stay on supported steps.
Confirm a supported Kubernetes minor version
Select a Kubernetes minor version that the project still maintains. As of September 2026, the maintained minors listed in the release table were 1.37, 1.36 and 1.35, with end-of-life dates running into 2027. Check the release page again on the day you commit, since the window moves. Choose a minor that you can upgrade one step at a time under the version skew policy, and confirm the cluster will not fall out of support before your planned upgrade.
Confirm the compatibility matrix first
Check the cloud-provider-openstack release against both the OpenStack release and the Kubernetes minor version before you pin any version. The project's compatibility matrix is the authority here, and this page does not reproduce it. Confirm the pairing with the project, record the exact release tags you tested together, and keep that record with the change request. Treat an untested pairing as a risk to close before build, not after.
Create a least-privilege service user
Create a dedicated Keystone service user for the cloud provider instead of reusing an administrator account. Grant only the roles and project scope the controller needs to manage load balancers, volumes, routers and instances in the target project. Keep this user out of human workflows, store its credentials in your secret manager and document who can rotate them. Review the role list against the cloud provider documentation for your chosen release, because the required roles change between releases.
Design the network and subnets
Plan the project network, the node subnet, the pod and service address ranges and the routing between them before the first instance is created. Decide whether node addresses come from a fixed subnet, which security groups apply to control plane and worker nodes, and how pod traffic leaves the project. Confirm that the address ranges do not overlap with corporate networks you need to reach. Changing these ranges after the cluster exists usually means a rebuild.
Provide a TCP load balancer path to port 6443
Set up a TCP load balancer in front of the kube-apiserver endpoint on port 6443 before you join additional control plane nodes. The kubeadm high availability guide calls for at least three control plane nodes behind this load balancer. Confirm that the load balancer health checks the API port, that the security groups allow the required traffic, and that your operators can reach the endpoint from their networks. Octavia is the usual OpenStack option, and you should verify its service availability in your target release.
Plan etcd capacity and backups
Decide before the build whether etcd runs stacked on the control plane nodes or as an external cluster, and size the volumes that hold it. Kubernetes documentation recommends an odd number of members, with five members for production. Define where etcdctl snapshot save writes backups, how often they run and how a restore with etcdutl is tested. Backup storage should sit outside the failure domain of the cluster, which often means a separate Cinder or Ceph-backed location.
How the Cloud Controller Manager and CSI drivers divide the work
The first design decision is which component owns which resource. The OpenStack Cloud Controller Manager runs inside the cluster and calls OpenStack APIs to keep Kubernetes objects aligned with cloud resources. It reads server records from Nova so that nodes receive labels and addresses, consults Neutron for network addresses, and asks Octavia to create load balancers when a Service of type LoadBalancer is created. Volumes and shared file systems are a separate concern. The Cinder CSI driver provisions block volumes and the Manila CSI driver provisions shares, and both are reached through StorageClasses that your platform team defines. Keeping these responsibilities apart lets you review the permissions of each component on its own terms.
The controller needs its own OpenStack identity. Configure it with a dedicated Keystone credential rather than a personal user account, so that its actions are attributable and the credential can be rotated without affecting people. Application credentials are commonly used for this purpose, but confirm the current recommendation for your release in the cloud-provider-openstack documentation. Scope the credential to the project that holds the cluster and grant only the roles the controller and CSI drivers need. Store it in a Kubernetes Secret with tightly restricted read access, because Secrets are stored unencrypted in etcd by default unless you configure encryption at rest.
Controller authentication to Keystone is a machine-to-cloud relationship, and it is separate from how people reach the Kubernetes API server. Kubernetes does not represent normal users as API objects. It authenticates them with X.509 client certificates, bearer tokens such as OpenID Connect and JWT, webhook token authentication or an authenticating proxy. Keystone is not the default identity source for engineers running kubectl. Decide how staff authenticate to the API server, typically through your corporate directory using OIDC, and confirm whether Keystone federation will serve only the cloud-side identity or also the cluster front door. Documenting both paths separately makes access reviews easier to run and explain.
The storage backend is a separate decision that affects both drivers. Ceph block devices can back Glance images, Cinder volumes and backups, and Nova guest disks, but whether your cloud uses Ceph, another Cinder backend or a mix is a choice to confirm with your OpenStack design, not a requirement of the CSI drivers. Ask which backend each Cinder volume type maps to, because StorageClass parameters point at those types. Check the Manila share backend too, since it determines whether ReadWriteMany claims can be supported. Agree on capacity and failure domains with the storage team before you define StorageClasses that application teams will depend on.
Configuration sequence for the OpenStack and Kubernetes integration
This sequence builds a Kubernetes control plane on OpenStack and connects it to the cloud for node identity, load balancing, block storage and optional shared file storage. Each step closes with a check that must pass before the next one begins.
Create the Keystone service user and roles
The cloud team creates a dedicated service user and project for the cluster, separate from personal accounts. They assign only the roles that the cloud provider and CSI drivers need for the Kubernetes release you plan to run, and they confirm that exact role set against the documentation for that release. Store the credentials in your secrets tooling, not in configuration files. Check: authenticate as the new user with the OpenStack CLI, request a token scoped to the project, and list servers, volumes and load balancers without authorization errors. Do not continue until this works.
Confirm Octavia and Cinder endpoints
Confirm that the service catalog exposes load balancing (Octavia) and block storage (Cinder) endpoints for the target region. Then confirm that the planned control plane and worker subnets can reach those endpoints over the network path you intend to use, including any firewall rules between the cluster network and the OpenStack API network. Check: list the catalog entries for both services and run a read-only request against each endpoint from a host in the cluster subnet. If either fails, fix the catalog or routing before building any nodes.
Build the kubeadm control plane
Provision at least three control plane nodes and place a TCP load balancer in front of kube-apiserver on port 6443. Choose the stacked etcd topology, where etcd runs on the control plane nodes, or the external etcd topology, which uses separate etcd hosts and more machines to operate. Keep the etcd member count odd, and plan five members for production, as the Kubernetes documentation recommends. Before the first node joins, decide how the kubelet and API server will be told to use an external cloud provider, because that setting is easier to put in place at initialization. Check: the etcd member list shows an odd number of healthy members, and kubectl reaches the API server through the load balancer address and returns the server version.
Deploy cloud-provider-openstack and confirm node registration
Create the cloud configuration secret using the service user credentials from the first step, then deploy the OpenStack Cloud Controller Manager at the version that matches your Kubernetes minor release. Join the worker nodes after the controller is running. The controller sets provider IDs and addresses on each node and clears the uninitialized taint that OpenStack-backed nodes carry until it has processed them. Check: each node shows a provider ID and addresses that match its OpenStack instance, no node retains the uninitialized taint, and the node names match the instance names in your project.
Add the Cinder CSI driver and a test PVC
Install the Cinder CSI driver with the same credentials and configuration pattern used for the cloud controller. Create a StorageClass that points to a Cinder volume type the cloud team has confirmed for this project. Then create a test PersistentVolumeClaim, attach it to a test pod on a worker node, write a file, and delete the pod and claim to confirm reclaim behavior. Check: the claim reaches Bound, the matching volume appears in the Cinder project, the pod reads back the file it wrote, and the volume is removed from Cinder after the claim is deleted under your chosen reclaim policy.
Add the Manila CSI driver if shared file storage is needed
Skip this step if workloads only need block volumes that attach to one pod at a time. When multiple pods across nodes must read and write the same files, deploy the Manila CSI driver. Confirm that Manila is available in the cloud, that the share types and share networks your team needs exist, and that the cluster nodes can reach the share export path. Check: create a test claim with the read-write-many access mode, mount it in two pods scheduled on different worker nodes, and confirm that a file written from one pod is visible from the other.
Deploy an Octavia-backed Service and Ingress
Create a test Service of type LoadBalancer and confirm that the cloud controller asks Octavia to provision a load balancer with a listener and a pool for the nodes. Then deploy your ingress controller behind that Service and route a test hostname to a simple backend. Confirm with the cloud team how TLS certificates, health monitors and any fixed addresses will be handled for production traffic. Check: the Octavia listener and pool report healthy members, and an HTTP request through the external address returns the response from the test backend.
Configure encryption at rest for Secrets
Kubernetes stores Secrets unencrypted in etcd by default, so configure an encryption provider in an EncryptionConfiguration file that the API server loads. Confirm with the cloud team whether a Barbican-backed key provider is available and supported for your Kubernetes release, or whether a key managed elsewhere will be used. Pair this with least-privilege RBAC that restricts list and watch access to Secrets. Check: create a test Secret, read its raw value directly from etcd with etcdctl, and confirm the stored data is not readable as plaintext. Also confirm that a documented key rotation procedure and an etcd backup and restore test with etcdutl are complete before the cluster takes workloads.
Mapping OpenStack resources and Keystone roles to Kubernetes objects
This table pairs each OpenStack resource that cloud-provider-openstack consumes with the Kubernetes object that represents it in a cluster. Read each row left to right to see which Kubernetes object carries the mapping and which team should own and approve it. Exact LoadBalancer annotation names and CSI parameters must come from the release that matches your deployed cloud-provider-openstack version, so confirm them before writing manifests.
| OpenStack resource | Kubernetes counterpart | Who owns the mapping |
|---|---|---|
| Keystone project | Namespace per team or environment, agreed in the mapping convention and paired with resource quotas | Cloud platform team with application owners |
| Keystone role (for example member or reader) | RoleBinding or ClusterRoleBinding granting Kubernetes roles to the group that authentication presents | Identity team with cluster administrators |
| Cinder volume type | StorageClass whose parameters name the Cinder volume type for the Cinder CSI driver | Storage team defines types; platform team creates StorageClasses |
| Manila share type | StorageClass for the Manila CSI driver naming the share type, used for shared file workloads | Storage team with platform team; confirm driver support for your release |
| Octavia flavor or provider | LoadBalancer Service annotations selecting a flavor or provider, with names taken from the matching release | Network team publishes approved options; application teams choose per Service |
| Nova instance metadata | Node labels and taints on worker nodes, used by scheduling selectors and node affinity rules | Platform team defines node pools; cloud team sets server metadata |
How Kubernetes Secrets encryption and Barbican fit together
Kubernetes stores Secrets unencrypted in etcd by default, so the first decision is whether your cluster will encrypt them and where the key will live. The Kubernetes good practices guidance asks administrators to do three things: configure encryption at rest, restrict list and watch access with least-privilege RBAC, or keep sensitive values in an external store reached through the Secrets Store CSI Driver. These controls cover different risks. Encryption at rest protects etcd data and its backups, RBAC limits who can read Secrets through the API, and an external store keeps some values out of etcd entirely. Most clusters on OpenStack need more than one of these. Decide which ones your team will run before any workload that uses Secrets is migrated.
Encryption at rest is configured on kube-apiserver through an encryption configuration file that lists providers for each resource type. The first provider in the list encrypts new writes, and the others allow existing data to be read during a change. Local key providers keep the key material on control plane nodes, so anyone who can read that file and the etcd data can decrypt Secrets. A KMS provider moves the key out of the API server and calls an external key service. The Barbican-backed option for cloud-provider-openstack is a design choice, not a default. Confirm it against your exact Kubernetes and cloud-provider-openstack releases, including which provider is supported, what Keystone credentials the API server needs, and how the key lifecycle is handled. Get that version matrix in writing before you commit to the design.
Key rotation and key ownership are where this design usually breaks down. Rotating a local key means adding a new key entry, restarting the API servers, and then rewriting existing Secrets so they are encrypted with the new key before the old one is removed. Skipping the rewrite leaves data protected by a key you have retired, and removing the old key too early makes that data unreadable. Name an owner for each key: the platform team that runs the control plane, a security team that controls the key service, or the OpenStack operators who administer Barbican. Document the owner alongside the rotation procedure, the interval your policy requires, and the approval path for emergency rotation. Ask the project whether Barbican rotation can be automated and how it audits key use.
The most serious risk is a backup that cannot be restored. An etcd snapshot taken with etcdctl snapshot save contains encrypted Secret values, and restoring it with etcdutl into a cluster whose encryption key is missing or different leaves those Secrets unreadable. The snapshot can be intact while the cluster is unusable for every workload that depends on those values. Store encryption keys as a separate backup with separate access control, outside the failure domain of the etcd backups. Record which key version each snapshot requires so a restore after a rotation does not depend on memory. Then test a restore into a non-production cluster that uses the same key, and include that check in the restore runbook before go-live.
Security settings to harden the OpenStack integration
These six cards cover the security decisions between OpenStack and the Kubernetes cluster that consumes it. Credentials, access and network controls define what each component can reach, while etcd protection and benchmark checks show whether those settings hold after the build and through upgrades.
Service credentials and Secret access
The cloud provider and the Cinder and Manila CSI drivers each need OpenStack credentials. Create a dedicated application credential per component, scoped to one project and only the roles it needs, and set a rotation schedule. Bind each controller and CSI service account to a Kubernetes RBAC role that grants get, list and watch on Secrets only in the namespaces it serves, since list and watch return Secret contents. Confirm the role set with your OpenStack team, then test that a pod in one namespace cannot read Secrets in another.
Pod Security Standards by namespace
Kubernetes Pod Security Standards define three profiles: privileged, baseline and restricted. Assign a profile per namespace with the built-in Pod Security admission labels, starting with restricted for tenant workloads. Reserve privileged for components that need host access, such as some CSI node plugins, and confirm each requirement in the driver documentation. Expect friction where images run as root or mount host paths, and record every exception with its owner and reason before enforcement.
Human access through OIDC or certificates
Kubernetes does not store user accounts. It accepts X.509 client certificates, OpenID Connect tokens and other bearer-token methods, so the API server must be configured for one of them. Keystone federation documentation covers SAML 2.0 and OpenID Connect, but whether a Keystone-issued token can serve as an OIDC source for the Kubernetes API server needs confirmation against your OpenStack and Kubernetes versions. If it cannot, use your corporate identity provider as the issuer, map groups to RBAC bindings, and keep client certificates for break-glass access with short lifetimes.
Network policies between tenant networks
Tenant networks in OpenStack isolate projects at the network layer, but pod traffic inside a cluster is controlled only if the CNI plugin enforces Kubernetes NetworkPolicy. Confirm that your CNI supports it, then apply default-deny ingress and egress per namespace and allow only the paths you need, such as the API server, the Octavia load balancer and storage backends. Decide how security groups on the OpenStack side map to in-cluster policies, and test both layers with cross-tenant connection attempts from a test pod.
etcd access control and backup protection
etcd holds every Kubernetes object, and Secrets are stored unencrypted there by default. Enable encryption at rest for Secrets, and if your design uses Barbican as the key source, confirm that integration for your versions. Limit etcd client access to control plane nodes with TLS client certificates, and run an odd number of members, with five recommended in production. Take snapshots with etcdctl snapshot save, store them encrypted outside the cluster with restricted access, and test restores with etcdutl.
CIS benchmark checks and owners
The CIS Kubernetes Benchmark provides a set of configuration checks for the control plane, worker nodes and policies. Scan the built cluster and log every failed or not-applicable check in a register with a named owner: the platform team for API server and kubelet settings, the OpenStack team for cloud provider and Octavia configuration, and the security team for approved exceptions. Confirm which benchmark version matches your Kubernetes release, since check sets change between versions, and rerun the scan after each upgrade.
How to test the integration before production traffic arrives
The integration is not ready for production until a written verification plan exists and every test in it has an acceptance criterion agreed before the build starts. Write the pass and fail conditions first, then ask the build team to show evidence against them. Otherwise, the team tends to define success as whatever the cluster happens to do during the demo. The plan should cover the OpenStack Cloud Controller Manager, each CSI driver in use, the load balancer path, Keystone authentication, the kubeadm control plane and etcd. Assign an owner to each test, name the environment it runs in, and keep the results with the change record so an auditor or a later operator can see what was proven and when.
Start with the node and storage path, because failures there surface everywhere else. After the controller starts, confirm that every node registers with the expected name, provider ID, and zone and region labels, and that each node maps to a Nova instance in the right project. Then provision a PersistentVolumeClaim through the Cinder CSI driver and another through the Manila CSI driver, attach or mount each to a pod, and write a marker file. Delete the pod so the scheduler places it on a different node. The acceptance criterion is that the same data reads back after the reschedule and that the volume detaches cleanly from the old node. Repeat the test with the storage class parameters your platform team plans to use in production.
Test ingress from outside the cluster with a LoadBalancer Service and an Ingress backed by Octavia. Record the external address, the listener and the health monitor status in OpenStack. A successful HTTP response from a host on the corporate network is the minimum, and the test should also confirm that security group rules permit only the ports you planned. Next, rotate the Keystone credential that the controller and CSI drivers use, following your organization's rotation procedure. Confirm that workloads keep running, that the old credential is rejected, and that the rotation is recorded. Ask your identity team beforehand which credential type the integration uses, because the rotation steps depend on it.
Fail a kubeadm control plane node and verify that the TCP load balancer on port 6443 keeps serving the API, that the etcd members elect a leader if you use the stacked topology, and that kubectl, the controller manager and the scheduler recover. The kubeadm high availability guide calls for at least three control plane nodes, so run the failover test at that count. Finally, rehearse an etcd snapshot save with etcdctl snapshot save, then restore it into a scratch environment with etcdutl. Time the procedure and record every manual step, because the restore runbook is the document operators will reach for during an incident. Store the rehearsal results with the acceptance criteria.
Common failures when Kubernetes runs on OpenStack
This table lists five common failures when Kubernetes runs on OpenStack with cloud-provider-openstack, with the likely cause, the fix and the check that confirms the cause. Read each row from the symptom across, and run the check before changing configuration, since several symptoms look alike. The main takeaway is that most of these failures trace back to the connection between the cluster and OpenStack services, so confirm credentials, endpoints, volume types, quotas and version order first.
| Failure | Likely cause | Fix | Check that confirms the cause |
|---|---|---|---|
| Nodes stay tainted as uninitialized | The cloud controller cannot reach Nova or Keystone, so it never sets node addresses and metadata. | Correct the cloud configuration credentials and endpoints, then confirm the controller can authenticate to Keystone and list Nova servers. | Read the cloud controller manager logs for Keystone or Nova errors, and confirm the uninitialized taint clears after the controller runs again. |
| PVCs stay Pending | The StorageClass names a Cinder volume type that does not exist in the target project or region. | Set the StorageClass to a Cinder volume type available to that project, and recreate the StorageClass because its parameters cannot be edited in place. | Run openstack volume type list and compare the output with the StorageClass parameters, then describe the PVC for provisioner events. |
| LoadBalancer Services never receive an address | Octavia quota is exhausted, or the Octavia provider the controller expects is not enabled in the cloud. | Raise the load balancer quota for the project or correct the provider setting, then recreate the Service so the controller retries. | Run openstack quota show and openstack loadbalancer provider list, then inspect Service events for quota or provider errors. |
| Control plane upgrade breaks kubelets | The control plane was upgraded by more than one minor version at a time, or kubelets are older than the version skew policy allows. | Upgrade one minor version at a time, control plane first, then upgrade kubelets within the allowed skew before the next step. | Compare the API server version with the kubelet versions shown by kubectl get nodes against the Kubernetes version skew policy. |
| API server authentication fails after a Keystone or OIDC change | The OIDC issuer URL, client ID or required claims changed, so the API server rejects tokens that previously worked. | Align the kube-apiserver OIDC settings with the new issuer and client values, restart the API servers, and reissue user tokens. | Decode a failing token to check its issuer and audience claims, then match them against the kube-apiserver logs for authentication errors. |
Questions buyers ask before hiring help for Kubernetes on OpenStack
How much does it cost to set up Kubernetes on OpenStack?
Cost depends on the scope you agree in writing, so DeployOpen does not publish a price list and a quote follows the scope. The one-time work includes discovery, architecture decisions, building the control plane and node pools, configuring the OpenStack Cloud Controller Manager, the Cinder and Manila CSI drivers, Octavia ingress and Keystone authentication, then encryption of secrets, hardening, testing and handover documentation. Recurring costs appear only if you add a support retainer, upgrades or continuous testing. The main cost drivers are the number of clusters, storage backends, HA topology, identity federation and compliance evidence. Ask for a quote that lists each driver as a separate line with the deliverable it buys, the work it assumes from your team, and which items are optional.
How long does a Kubernetes on OpenStack engagement take?
The duration follows the same drivers as cost, and this topic has no researched duration to quote, so ask for a timeline in the written scope rather than relying on a general figure. Two release facts shape the calendar. Kubernetes publishes about three minor releases per year on a cycle of about 14 weeks, and OpenStack upgrades can be planned between SLURP releases as well as adjacent releases. Ask the scope to name milestones: architecture sign-off, a staging cluster that passes your acceptance tests, a production cutover window and handover. Also ask which milestones depend on your team, such as network changes, identity federation approvals or security review, because those waits often set the calendar more than the build does.
What does our team have to provide during the engagement?
Your team provides the decisions and access that no outside party can make for you. That means a named technical owner, a business sponsor who can settle trade-offs, and administrative access to the OpenStack projects, quotas and networks the clusters will use. You also need identity provider administrators for Keystone federation, DNS and network planning, access to the load balancer and storage backends, and change windows for staging and production. Security and compliance staff supply the policies that Pod Security Standards, secrets handling and RBAC design must follow. Plan a regular review slot with decision-makers, because open questions on identity mapping or storage classes stall builds. Confirm in the scope who holds credentials and how they are handed over.
Can our internal platform team deploy Kubernetes on OpenStack alone?
Yes, an experienced internal team can do it alone, provided it covers both platforms. The build needs working knowledge of OpenStack identity, networking, block and file storage and load balancing, plus kubeadm bootstrapping, etcd operations, certificate handling and CSI storage classes. The harder ongoing skill is upgrades. Kubernetes maintains only its three most recent minor releases, the version skew policy requires kube-apiserver to move one minor version at a time before the other components, and OpenStack upgrades must follow its release cadence. Check whether your team can staff on-call coverage for etcd backups and restores, test upgrades before production and track two release trains. If the answer is uncertain, a fixed-scope build with handover, followed by an optional retainer, is one way to split the work.
Should we use stacked or external etcd for Kubernetes on OpenStack?
Stacked topology runs etcd members on the control plane nodes. It uses fewer machines and is simpler to operate, but losing one control plane node removes an API server and an etcd member at the same time. External etcd runs on its own nodes, which separates those failure domains at the cost of more virtual machines, more certificates and another backup target. The kubeadm high availability guide describes both options and requires at least three control plane nodes with a TCP load balancer in front of kube-apiserver on port 6443. On OpenStack, confirm whether Octavia will serve that role and how its health checks behave. etcd needs an odd number of members, and Kubernetes documentation recommends five members for production. Whichever topology you choose, plan etcdctl snapshot save backups and test restores with etcdutl before go-live.
How do we protect Kubernetes Secrets on OpenStack with encryption?
Do not rely on the default. Kubernetes stores Secrets unencrypted in etcd unless you configure encryption at rest. The Kubernetes good practices guidance also asks you to restrict list and watch access with least-privilege RBAC, and it points to external stores through the Secrets Store CSI Driver for secrets that should not live in the cluster at all. The topic scope includes Barbican-backed secret encryption, but the exact key provider path depends on your Kubernetes distribution and your Barbican deployment, so confirm that path during design. Ask the quote to state which keys are created, where they are held, who owns rotation and how a restore from an etcd backup handles encrypted data. These answers belong in the written design, not in an engineer's memory.
What compliance evidence should a Kubernetes on OpenStack quote include?
The quote should name the evidence you will receive, not just the word compliance. DeployOpen prepares systems, controls and evidence for compliance assessments, but it does not issue audit reports, attestations or certifications. Independent auditors and certification bodies do that work. Ask which controls the build targets and how configuration maps to the CIS Kubernetes Benchmark. Evidence typically includes configuration baselines, RBAC and Pod Security Standards settings, encryption and backup records, access logs, change records and test results. Confirm the assessor you work with, the boundary of the cluster and identity systems in scope, and who keeps the evidence current after handover. The quote should also separate what DeployOpen delivers from what your platform owner must maintain.
How DeployOpen scopes and delivers Kubernetes on OpenStack
DeployOpen plans, builds, documents and supports Kubernetes on OpenStack with cloud-provider-openstack inside your own cloud accounts, data centers or air-gapped networks. Each engagement starts from a written scope that ties the OpenStack services your clusters consume to the Kubernetes version, identity model and recovery targets your teams need.
How we scope
- Inventory the OpenStack services your clusters will consume, including Nova, Cinder, Manila, Octavia, Keystone and Barbican.
- Agree the Kubernetes distribution, minor version and upgrade approach in writing before build work starts.
- Define which Cinder and Manila storage classes, Octavia ingress paths and Keystone authentication flows are in scope.
How we build
- Configure the OpenStack Cloud Controller Manager with credentials scoped to the projects your clusters use.
- Deploy Cinder and Manila CSI drivers and test volume provisioning, snapshots and resizing against your storage backends.
- Set up control plane nodes behind a TCP load balancer on port 6443 and test failover of kube-apiserver.
How we hand over
- Document cluster topology, OpenStack resource ownership, credential rotation steps and the version skew rules you must follow.
- Run and record an etcd snapshot backup and a restore rehearsal before handover, using etcdctl and etcdutl.
- Provide runbooks for Barbican-backed secret encryption and Octavia ingress changes that your platform team can run alone.
How we support
- Ongoing support, upgrades and continuous testing are available as a retainer that follows the agreed scope.
- Plan Kubernetes minor version upgrades around the three-release support window and the kubelet skew policy.
- Review OpenStack release changes, including SLURP upgrades, that could affect the cloud provider, CSI or Octavia components.

