Kubernetes itself is portable, so lock-in comes from the services around it: cloud-specific networking, load balancers, storage, identity, secrets, observability, managed databases, and management consoles. Keep each layer portable with Git and infrastructure as code, the same open-source components on every cloud, Gateway API, external secrets, OpenTelemetry, and databases you can run anywhere, and manage the fleet with tools that work on every cloud. Control Plane runs the same workload definition across AWS, GCP, Azure, and clusters you already run, with networking, identity, and observability built in.
Disclosure: Control Plane publishes this guide.
TL;DR
- Where lock-in hides: cloud-specific CNIs, load balancer controllers, IAM bindings, secret managers, monitoring agents, managed databases, and cloud consoles.
- The portable stack: Terraform or OpenTofu for provisioning, Argo CD or Flux for GitOps, Cilium where you can run it, Gateway API for ingress, Rook-Ceph, Longhorn, or application-layer replication for data, External Secrets Operator or HashiCorp Vault for secrets, workload identity federation for cloud access, OpenTelemetry and Prometheus for observability, and PostgreSQL or MySQL you can run anywhere.
- The cost of portability: more clusters and components to operate, cross-cloud egress, and sometimes lowest-common-denominator features. A managed service is worth its lock-in when you document an exit plan.
- How Control Plane fits: Control Plane’s Global Virtual Cloud (GVC), a named set of locations across one or more clouds where each workload runs, deploys one workload definition active-active across AWS, GCP, Azure, your own Kubernetes clusters, and on-premises servers, with networking, identity, and observability built in.
Which parts of Kubernetes cause cloud lock-in?
Each layer has a cloud-specific default, a portable alternative, and a trade-off.
| Layer | Cloud-specific default | Portable option | Trade-off |
|---|---|---|---|
| Provisioning | Cloud console, CloudFormation, ARM or Bicep templates | Terraform, OpenTofu, Pulumi, or Crossplane | Extra tooling to maintain; new cloud features can arrive later |
| Deployment | AWS CodePipeline, Azure Pipelines, Cloud Build | Argo CD or Flux (GitOps) | You operate the GitOps controller |
| Networking (CNI) | AWS VPC CNI, Azure CNI, GKE Dataplane V2 | Cilium where supported, with rules written as standard NetworkPolicy | GKE Dataplane V2 and Azure CNI Powered by Cilium are already Cilium-based; on EKS, replacing the VPC CNI changes pod IP addressing and some AWS integrations |
| Ingress and load balancing | AWS Load Balancer Controller, GKE Ingress, Application Gateway Ingress Controller | Gateway API implementations such as Envoy Gateway, Cilium, Istio, or NGINX Gateway Fabric | The Gateway still provisions a cloud load balancer, and Gateway classes and annotations differ per provider |
| Service-to-service security | Cloud-specific options or none | Istio, Linkerd, or Cilium Cluster Mesh | Operational overhead of a mesh, plus proxy latency and resource use |
| Storage and data | Provider block storage classes (EBS, Persistent Disk, Azure Disk) | Rook-Ceph or Longhorn, or application-layer replication, with StorageClass names set per overlay | Different performance and durability; self-managed storage to operate |
| Identity | IAM roles for service accounts, Workload Identity Federation for GKE, Microsoft Entra Workload ID | One pattern on every cloud: Kubernetes service account tokens federated to each provider, with bindings kept in per-cloud overlays | A separate binding per provider |
| Secrets | AWS Secrets Manager, Google Secret Manager, Azure Key Vault | External Secrets Operator or HashiCorp Vault | You run and secure the secrets layer |
| Observability | CloudWatch, Cloud Monitoring, Azure Monitor | Prometheus, Grafana, and OpenTelemetry | Self-managed collection and storage |
| Databases | Amazon Aurora, Spanner, Azure Cosmos DB | PostgreSQL or MySQL run portably, or a managed service with a documented migration path | You handle backups, replication, and upgrades |
| Cluster management | EKS, GKE, and AKS consoles | Rancher, Karmada, or Red Hat Advanced Cluster Management | Another management plane to operate and secure |
Each cloud-specific default lowers setup effort and raises switching cost. Decide and document where you accept lock-in, and keep an exit plan for each case.
How do I manage Kubernetes across multiple clouds without vendor lock-in?
Manage every cluster from Git and infrastructure as code, run the same open-source component at each layer on every cloud, route traffic globally, and test moves to a second cloud on a schedule. The ten steps below build that setup.
- Git and a GitOps controller for every cluster. Keep manifests, Helm charts, and Kustomize overlays in Git, with one base per application and an overlay per cloud for StorageClass names, load balancer annotations, and identity bindings. Run Argo CD or Flux so each cluster reconciles from Git. See Argo CD vs Flux.
- Infrastructure as code for clusters and cloud resources. Define clusters, networks, IAM roles, and DNS zones in Terraform, OpenTofu, or Pulumi, with shared modules and provider-specific parameters. Crossplane manages cloud resources as Kubernetes custom resources.
- The same networking on every cluster where you can. Run Cilium where the provider allows it: GKE Dataplane V2 and Azure CNI Powered by Cilium are Cilium-based, and EKS supports Cilium in chaining or replacement mode. Write network rules as standard Kubernetes NetworkPolicy so they apply whichever CNI enforces them. For ingress, adopt Gateway API so routing definitions are the same on every cloud; the community ingress-nginx project was retired in March 2026.
- Secrets from one source. Run External Secrets Operator on every cluster against one backend, such as HashiCorp Vault, so every workload fetches secrets the same way.
- Workload identity per cloud. Configure workload identity federation so pods get cloud credentials without long-lived keys. Each cloud wires it differently: IRSA uses a service account annotation, EKS Pod Identity uses an association in the EKS API, Workload Identity Federation for GKE can grant IAM roles directly to the Kubernetes service account as a principal, with no annotation, and Microsoft Entra Workload ID on AKS uses a service account annotation plus a pod label, backed by a federated identity credential in Entra ID. Keep these bindings in per-cloud overlays; application code that uses the default cloud SDK credential chain does not change.
- One observability backend. Instrument workloads with OpenTelemetry and run Collectors on each cluster that ship metrics, logs, and traces to one backend, with Prometheus and Grafana for metrics and dashboards. Telemetry from every cloud lands in one place, with no dependency on CloudWatch, Cloud Monitoring, or Azure Monitor.
- A global traffic layer. Use external-dns with DNS-based global load balancing, or another global traffic manager, to route users to the nearest healthy cluster, with health checks per cluster and an active-active or active-passive policy per application.
- A data strategy per service. Stateless services need no cross-cloud data plan beyond the stores they call. For stateful services, run a portable database on Kubernetes with application-layer replication, use a managed database on each cloud with asynchronous replication between them, or keep the service on one cloud and document the lock-in. Weigh cross-cloud transfer cost and latency.
- Policy as code across clusters. Run OPA Gatekeeper or Kyverno on every cluster with a shared policy library in Git, enforcing Pod Security Standards, resource limits, image provenance, and network policy.
- Regular portability drills. Deploy a service to the second cloud on a schedule and verify it works, starting with non-critical workloads. Drills expose hidden dependencies on cloud-specific features.
What tools help with cloud portability and avoiding vendor lock-in?
The main open-source tools are Terraform or OpenTofu, Argo CD or Flux, Cilium, Gateway API, External Secrets Operator or Vault, OpenTelemetry and Prometheus, Velero, and a fleet manager such as Rancher.
| Category | Tools | What it makes portable |
|---|---|---|
| Infrastructure as code | Terraform, OpenTofu, Pulumi, Crossplane | Cluster provisioning and cloud resource definitions |
| GitOps | Argo CD, Flux | Application deployment, configuration, and drift correction |
| Networking and mesh | Cilium (including Cluster Mesh), Calico, Istio, Linkerd | Network policy, service-to-service encryption, cross-cluster connectivity |
| Ingress | Gateway API implementations (Envoy Gateway, Cilium, Istio, NGINX Gateway Fabric) | Routing definitions |
| Global traffic | external-dns with DNS-based global load balancing | Routing users between clusters on different clouds |
| Secrets | External Secrets Operator, HashiCorp Vault | Secret storage and delivery |
| Backup and migration | Velero | Moving workloads and volumes between clusters |
| Observability and cost | OpenTelemetry, Prometheus, Grafana, OpenCost | Metrics, logs, traces, and Kubernetes cost allocation |
| Fleet and multi-cluster management | Rancher, Karmada, Red Hat Advanced Cluster Management | Cluster access, inventory, policy, and multi-cluster scheduling |
| Platforms that run workloads across clouds | Control Plane | Workload deployment, global routing, identity, and observability across AWS, GCP, Azure, Kubernetes clusters you already run, and on-premises servers from one definition |
GKE fleet management can also manage clusters on other clouds, but it is tied to Google Cloud. For a broader comparison, see the best Kubernetes management platforms.
Is multi-cloud a real solution to vendor lock-in?
Partly. Running on two or more clouds reduces dependence on one provider’s availability and pricing, but it removes lock-in only when each layer uses portable components. Workloads that depend on Aurora on AWS and Spanner on GCP are locked in to both providers.
Multi-cloud also adds operational cost: more credentials, networking models, billing systems, and provider quirks. Teams that adopt it without the portable stack often carry the operating complexity of two clouds and the lock-in of each.
The practical approach is selective portability. Run each workload where it fits best, keep its layers portable so it can move, and accept managed-service lock-in only with a documented exit plan. See managed services vs portability and how to avoid cloud vendor lock-in.
What does portability cost?
Budget for these costs when you commit to a portable stack on every cloud.
More clusters to upgrade. Each Kubernetes upgrade is tested and rolled out to every cluster, and CNI, ingress, mesh, and policy components each have their own upgrade cycle. The work grows with the number of clusters.
More components to operate. Running Cilium, a mesh, Vault, External Secrets Operator, OpenTelemetry Collectors, Prometheus, Grafana, and a policy engine on every cluster means monitoring, capacity planning, and incident response for each.
Cross-cloud egress. Providers bill data leaving their network, so cross-cloud database replication, service calls, and log shipping add recurring transfer charges. Keep chatty services and their data in one cloud and track egress spend per service.
Lowest-common-denominator features. Portable alternatives can lack the integration of managed services. A self-managed PostgreSQL cluster needs engineering effort to match a managed database’s automated backups, point-in-time recovery, and read replicas.
When managed services are worth it. A small team may be better served by a managed database despite the dependency. Document the lock-in and the migration path (most managed PostgreSQL and MySQL services support logical or binlog replication to an external target), and revisit the decision as the team grows.
Operating the clusters. The largest recurring labor cost is operating Kubernetes itself on every cloud: upgrades, node pools, autoscaler tuning, and patching. A platform that handles Day 2 operations across clouds removes much of it, which is the approach Control Plane takes.
How Control Plane fits
Control Plane is the unbreakable platform for running production workloads. It runs serverless, standard, stateful, and cron workloads natively on AWS, GCP, and Azure, VM workloads on locations joined through Control Plane’s Managed Kubernetes, and workloads on Kubernetes clusters you already run or your own machines, including on premises, active-active across regions and clouds.
A workload deployed to a GVC runs active-active in every location of that GVC from one definition. Locations can be Control Plane-managed regions on AWS, GCP, and Azure, Kubernetes clusters you already run joined through Control Plane’s Bring Your Own Kubernetes (BYOK), or clusters created through Control Plane’s Managed Kubernetes (MK8s). On Control Plane-managed locations there is no Kubernetes cluster to operate. MK8s runs worker nodes, load balancers, and storage in your AWS account or GCP project, or on servers you provide (documented providers include Generic, AWS, GCP, Hetzner, and Triton), while Control Plane operates the Kubernetes control plane.
Networking. Control Plane’s built-in global endpoint routes each request to the nearest healthy location, and every workload has a deny-by-default internal firewall with mTLS between services. Control Plane runs the service mesh for you, so there is no separate mesh to install or operate.
Identity. Control Plane’s Universal Cloud Identity gives workloads access to 600+ AWS, GCP, and Azure services with no long-lived cloud keys in your code. You connect each cloud account once through an IAM role or service-account grant, and workloads receive short-lived, least-privilege credentials at runtime, in place of the per-cluster federation setup in step 5.
Day 2 operations. Control Plane handles autoscaling, built-in observability, and security for every workload.
Tooling. The CLI, console, Terraform and Pulumi providers, and the Control Plane MCP server all work through the same Control Plane API, so Control Plane complements the infrastructure as code tools you already run.
Availability, cost, and compliance. The 99.999% availability SLA applies to workloads running at least two replicas in at least two locations, and those locations can be on different providers. You pay for the CPU and memory a workload reserves, with no contracts or minimums. Customers typically cut compute costs 30 to 50 percent compared with running directly on AWS, GCP, or Azure. Control Plane is PCI DSS Level 1, SOC 2 Type II, HIPAA, and GDPR compliant.
Portability. Workloads on Control Plane stay standard container images, and you can export Control Plane resources to Terraform with the CLI. Your containers, Git repository, and infrastructure as code remain yours, which keeps the exit path short compared with a cloud-specific managed service.
See how to run the same app on AWS, GCP, and Azure, and for teams reconsidering Kubernetes itself, the best Kubernetes alternatives.
FAQ
Short answers for teams planning multi-cloud Kubernetes.
How do I run Kubernetes on EKS, GKE, and AKS with one set of tools?
Provision all three clusters from one Terraform or OpenTofu codebase. Register them with one Argo CD instance or install Flux on each, and keep one base of manifests with a Kustomize overlay per cloud for StorageClass names, load balancer annotations, and identity bindings. Use Gateway API for ingress, External Secrets Operator for secrets, one OpenTelemetry Collector configuration, one Kyverno or Gatekeeper policy library, and Rancher or Red Hat Advanced Cluster Management for one access and inventory layer. With Control Plane, existing EKS, GKE, and AKS clusters join one GVC through BYOK, and one workload definition deploys to all three.
Is Kubernetes itself a form of lock-in?
No. Kubernetes is an open-source CNCF project with a consistent API across providers. The lock-in risk comes from the cloud-specific services attached to it.
Can I use managed Kubernetes (EKS, GKE, AKS) and still avoid lock-in?
Yes. The API server, etcd, and scheduler are largely interchangeable across EKS, GKE, and AKS. Keep the add-ons you attach portable, using the layer table above.
How do I move a Kubernetes workload from one cloud to another?
Create the target cluster from your infrastructure as code, point your GitOps controller at it with that cloud’s overlay, and move data with Velero file-system backups or database-native replication; native cloud volume snapshots do not transfer between clouds. Run the workload in both places, shift traffic gradually through the global traffic layer, then retire the old deployment.
Do I need a service mesh for multi-cloud Kubernetes?
Not always. Cilium Cluster Mesh provides cross-cluster connectivity and network policy without a full mesh. If you need mTLS and L7 traffic policy between services, Istio or Linkerd provides both.
Which multi-cloud Kubernetes cost do teams most often underestimate?
Cross-cloud egress. Replication, service calls, and log shipping between clouds add transfer charges, so design data placement to minimize cross-cloud traffic and track egress per service.
Does CSI make storage portable?
No. CSI is the interface that EBS, Persistent Disk, and Azure Disk already use, so data stays on each cloud’s disks. Use portable storage such as Rook-Ceph or Longhorn, or replicate at the application layer, and move data between clouds with Velero or database replication.
Can Control Plane replace my multi-cluster management tooling?
For running workloads, yes. Control Plane deploys, networks, secures, and observes workloads across clouds from one API and console. Control Plane-managed locations and MK8s clusters need no control plane work from your team. Clusters joined through BYOK run Control Plane workloads in the same GVC, and your team keeps operating those clusters.
What is the minimum multi-cloud setup to reduce lock-in risk?
Run primary workloads on one cloud and keep a validated environment on a second cloud where you can deploy the same workloads on demand. Keep manifests in GitOps, keep the second cloud’s infrastructure as code current, and run portability drills on a fixed schedule. Active-active can come later.
To run the same workloads across AWS, GCP, Azure, and your own infrastructure without having to operate the clusters yourself, talk to the Control Plane team or sign up free.
Originally published on the Control Plane blog.
Top comments (0)