Skip to main content
Choose OVHcloud when you want Kubernetes on Public Cloud instances in a project you own, including OVHcloud’s 3-AZ regions where a cluster can be spread across three availability zones. Ankra creates the private network, managed network gateway, bastion and instances in your project, installs Kubernetes and the OpenStack cloud integration, and then operates the cluster for you - this is an Ankra Managed cluster. OVHcloud bills you directly for the instances.

Before you start

  • OVHcloud API credentials - application key, application secret, consumer key and Public Cloud project ID - stored as an OVH credential.
  • An SSH key credential - your own public key, or one Ankra generates. See SSH Key Credentials.
  • Room in your project’s quotas for the instances, a network and the SSH keys, and the target region enabled on the project. Check them in the OVHcloud Control Panel; OVHcloud support raises quotas.

Create the cluster

1

Open the create dialog

Go to Clusters, click Create cluster and pick OVHcloud under Ankra Managed.
2

Credential & Region

Pick the OVH credential and the SSH key (or add either inline), and the region, for example Gravelines, Strasbourg, Beauharnois, Warsaw, London or Frankfurt.
3

Network & Compute

Keep or change the subnet CIDR, then pick the bastion flavor, the control plane count and flavor, and the worker flavor and count, with optional autoscaling bounds and a cloud-init document for the workers. The wizard shows each flavor’s vCPUs, RAM, disk and hourly price. Add more node groups once the cluster is running.
4

Kubernetes

Keep kubeadm (the default, with Cilium) or pick k3s, and optionally the version. See Choices fixed at create time for the CNI and etcd options.
5

GitOps

Optionally connect a Git repository; Ankra commits the cluster’s stacks to it. Two checkboxes are on by default:
  • Include Networking Stack - Traefik, cert-manager and a Let’s Encrypt ClusterIssuer, with Traefik behind an OVHcloud load balancer.
  • Include Public DNS - a delegated subdomain on ankra.cc with external-dns wired, so an ingress hostname under it gets its DNS record and TLS certificate automatically.
6

Details

Name the cluster, set its environment, and click Create cluster. A progress view follows the network, bastion, control plane and worker instances, Kubernetes installation and Ankra Agent.

Verify

  1. The cluster moves from Provisioning to Online in the clusters list once the Ankra Agent has connected.
  2. Point kubectl at it through Ankra (this needs a Cluster Access grant) and check the nodes:
    Every control plane and worker should be Ready. See Accessing Clusters with kubectl.

What Ankra created in your project

  • A private network - a vRack VLAN with a DHCP subnet. Nodes have private addresses only.
  • A managed network gateway (<cluster>-network-gw) attached to the subnet. It is the nodes’ default route and NAT: all node egress leaves through it.
  • A bastion (<cluster>-bastion) - the only instance with a public IP. It is an SSH jump host, not a router: Ankra reaches the nodes through it to provision, upgrade and reconcile, and you can use it for ssh -J. Clusters created before the bastion rename carry the instance name <cluster>-gateway for the same component.
  • Control plane and worker instances, and your SSH key on every instance.
  • The OpenStack cloud controller manager and Cinder CSI driver, for LoadBalancer Services and persistent volumes.
Because no workload traffic depends on the bastion, workloads keep running while it is unavailable, but Ankra cannot provision, scale, upgrade or reconcile the cluster until it is back, and the dashboard can show the cluster as degraded meanwhile. The OVH Reference has the diagram.

OVHcloud specifics

  • Flavor changes go one way. A node group moves to a larger flavor only; each node is powered off, resized and powered on, with brief downtime for its workloads. For smaller nodes, create a new group and delete the old one.
  • Labels and taints at add time. ankra cluster ovh node-group add also takes --labels and --taints, so a group can be created with them in one step.
  • First-boot scripts. A node group can carry a cloud-init document, applied at first boot on every instance the group ever creates, including replacements - see Node Group Cloud-init User Data.
  • Restart is a soft reboot through the OVHcloud API, falling back to a hard reboot when the guest OS does not respond. An instance that is SHUTOFF is started instead. ankra cluster ovh nodes list shows each node’s live provider_status and provider_power_state, which helps spot a crashed or powered-off instance first.
  • Access. ankra cluster ovh access-info <cluster> prints the bastion and control plane IPs with ready-to-paste ssh -J and Kubernetes API port-forward commands.
  • Stop. A stop releases the node instances, the bastion and the managed network gateway. The private network is kept and reused on the next start, and the Cinder volumes are kept and billed while the cluster is stopped.
  • Terminate deletes the instances, networks and SSH keys; the dialog and ankra cluster deprovision list the Cinder volumes the teardown deletes.

Availability Zones

Some OVH regions are 3-AZ: one region spanning three availability zones with independent power, cooling, and networking. EU-WEST-PAR holds eu-west-par-a, eu-west-par-b and eu-west-par-c, and EU-SOUTH-MIL holds the equivalent three. Every other region is a single failure domain, so check before you plan around zones. Two rules come from OVH and shape everything below. An instance’s zone is chosen at creation, and a request that names no zone gets whichever zone OVH picks - in practice the same one for every node of a cluster. And an instance’s zone is fixed for its lifetime, so re-placing a node means replacing it.

Find the zones a region has

Zone names are region-scoped, so check the spelling before you use one. Only a region whose type is region-3-az accepts zone placement.

Spread a new cluster across zones

Pass the zone pool at create. Ankra distributes instances across it deterministically: control planes and etcd spread per role, workers spread per node group, so a three-node database group gets one node in each zone rather than being balanced against unrelated workers.
Spreading across more than one zone requires at least 3 control planes. Fewer cannot keep etcd quorum through the loss of a zone, which is the only reason to spread a control plane, so the create is refused rather than quietly producing a cluster that fails on the first zone outage.
Omitting the zones leaves placement to OVH and changes nothing about how clusters behaved before. Clusters in single-zone regions are unaffected by everything in this section.

Pin a node group to one zone

A node group can be pinned to a single zone instead of spreading. Pin the group that runs zonal storage, because an OVH volume cannot attach from another zone.
Day-2 growth follows the cluster’s stored zone pool: node group add, node group scale, worker scale, and control plane growth all balance new instances around where the existing ones already are. A group whose nodes all share one zone is treated as pinned and grows in that zone; a group that is already spread keeps spreading. Spreading is per group, so a group with fewer nodes than the pool has zones cannot cover every zone. A new group added without a pin takes the zone with the fewest instances cluster-wide for each of its nodes, and a one-node group therefore lands wherever the cluster is thinnest, which is not necessarily the zone its name suggests: two groups called general-par-a and general-par-b, added without --availability-zone to a cluster whose eu-west-par-c held only one control plane, both went to eu-west-par-c. A group whose name promises a zone needs the pin. ankra cluster node-group list ends each line with az= and the zones the group’s nodes were placed into (availability_zones on the node-group listing API), so a group that has collapsed into one zone is visible in a single call.

Node topology labels

Every OVH node carries topology.kubernetes.io/zone (the zone OVH reports for the instance) and topology.kubernetes.io/region (the cluster’s region), so zone-aware scheduling works without extra configuration. The zone comes from what OVH reports for the live instance rather than what was requested, so it is correct even on clusters created before zone placement existed. On those older clusters Ankra records the zone the next time it reads the instance, but the labels are written by a server sync; trigger one rather than waiting:

Fixing a cluster that is already in one zone

  • Workers - in place. Add a node group pinned to the target zone, drain the old group, then delete it. No cluster rebuild.
  • Control planes - not in place. The zone is immutable and Ankra never re-places an existing control plane, so a zone-spread control plane on an existing cluster means recreating the cluster.
A cluster created before zone placement existed has no stored zone pool, so a node group added to it without a zone still lands wherever OVH picks. Pin each group explicitly: three zones means three pinned node groups.

Zone tolerance needs more than node spread

OVH High Speed block storage is zonal. It is triple-replicated within a single zone and cannot attach from another. A single database pod with a single PersistentVolume is therefore not zone-fault-tolerant however the nodes are spread: the volume is the single-zone dependency, and if its zone goes down the pod cannot start anywhere else. A zone-fault-tolerant stateful workload needs all of:
  • Replication at the application layer - CloudNativePG or Patroni with one replica per zone, each with its own volume. Node spread gives the replicas somewhere to live; it does not create them.
  • A WaitForFirstConsumer StorageClass so the volume is not bound before its pod is scheduled. Ankra ships csi-cinder-sc-topology for exactly this reason, and marks it the default on new OVH clusters. On a cluster created earlier, k3s’s local-path class is still present and also marked default, so name the class explicitly on anything that matters rather than relying on which default wins:
  • A node group pinned to one zone per replica, so a rescheduled pod cannot land where its volume is not. allowedTopologies on the StorageClass does not do this on its own - it narrows which zones the provisioner may choose from, it does not tie a volume to one of them.
  • topologySpreadConstraints keyed on topology.kubernetes.io/zone for the stateless tiers.
Node spread is necessary but never sufficient.
Zone placement is pending on OVH. The Cinder CSI provisioner runs with its Topology feature gate off on every Ankra OVH cluster, because OVH Block Storage rejects the compute zone names the gate forwards - with the gate on, every volume creation in a 3-AZ region fails with Availability zone 'eu-west-par-a' is invalid. While it is off the provisioner sends no zone at all: Cinder creates the volume in its own default zone, and the PersistentVolume carries no zone affinity. That applies to every class, csi-cinder-sc-topology included, so delayed binding still holds the volume back until a pod is scheduled, but the volume is not placed in that pod’s zone.Until the gate can be re-enabled per region, pin each stateful replica to a node group in one zone, so its pod can only ever be scheduled where its volume already is.

Operate it

Day-2 tasks work the same way on every Ankra Managed provider, with the CLI name ovh:

Troubleshooting