Self-hosted service
submariner-io/submariner avatar
submariner-io/submariner

Submariner: connecting Pods and Services across Kubernetes clusters

Networking component for interconnecting Pods and Services across Kubernetes clusters.

2,692 stars212 forksGoApache-2.0

At a glance

What is it?
Submariner links the overlay networks of separate Kubernetes clusters so Pods and Services can reach each other directly. It is CNI-agnostic, installs through an Operator wrapped by subctl or Helm, and the README still calls the project early stage.
Who is it for?
Adopt Submariner when you run multiple Kubernetes clusters on distinct Pod and Service CIDRs and need cross-cluster Pod and Service reachability without changing CNI. Do not adopt it if you need a single cluster, or if you cannot accept that the README itself warns about bugs and points most operational detail to the website.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Submariner actually connects, and who needs it

The README describes Submariner as a tool built to connect overlay networks of different Kubernetes clusters. That sentence is the whole product. In a normal multi-cluster setup, each cluster has its own Pod CIDR and its own Service CIDR, and a Pod in cluster A has no route to a Pod IP in cluster B. Submariner creates that route.

The audience is platform teams running more than one cluster who want cross-cluster Pod-to-Pod and Service-to-Service traffic without flattening the clusters into one network or rebuilding them on a single CNI. The README states the project is designed to be network plugin (CNI) agnostic and supports both encrypted and non-encrypted tunnels. That agnosticism is the reason to pick it over a CNI-specific multi-cluster mode: you keep the CNI you already run in each cluster.

The README also says Submariner is in an early stage, and while we welcome usage and experimentation, it is quite possible that you could run into bugs. Take that literally. This is not a component to drop into a production platform without a rollback story of your own, and the README does not document one.

The network path: gateway nodes and the vx-submariner tunnel

Submariner does not mesh every node with every other node. The README states that traffic between two clusters will transit between the leader elected (in each cluster) gateway nodes, through the configured cable driver. Each cluster elects a gateway node, and those gateways carry the cross-cluster traffic.

The first hop is local. When the source Pod is on a worker node that is not the elected gateway node, traffic destined for the remote cluster transits through the submariner VXLAN tunnel named vx-submariner to the local cluster gateway node. On the gateway node, traffic is forwarded to the remote cluster over the configured tunnel.

The last hop depends on what the destination address is. Once traffic reaches the destination gateway node, the README says it is routed in one of two ways depending on the destination CIDR. If the destination CIDR is a Pod network, the traffic is routed via CNI-programmed network. If the destination CIDR is a Service network, traffic is routed through the facility configured via kube-proxy on the destination gateway node.

That split is the design's centre of gravity. Pod traffic rides the CNI; Service traffic rides kube-proxy. It also means the gateway node is a chokepoint: cross-cluster bandwidth is bounded by what that one node can move, and a gateway failure forces a re-election before traffic resumes.

Installing Submariner with subctl and verifying the link

The README states Submariner is always deployed using a Go-based Kubernetes custom controller, called an Operator, that provides API-based installation and management. Deployment tools like the subctl command line utility and Helm charts wrap the Operator. The recommended deployment method is subctl, as it is currently the default in CI and provides diagnostic features.

The README does not print install commands. It points to the subctl Deployment docs and the Helm Deployment docs on submariner.io. What the repository does show is the image set the Makefile builds, which is the clearest signal of what actually runs in a cluster.

makefile
IMAGES ?= submariner-gateway submariner-route-agent submariner-globalnet
export LOCAL_COMPONENTS := submariner-gateway submariner-globalnet submariner-routeagent
MULTIARCH_IMAGES ?= $(IMAGES)
PLATFORMS ?= linux/amd64,linux/arm64

Those three images map to the roles described above: the gateway carries cross-cluster traffic, the route agent handles the non-gateway nodes, and globalnet is a separate component for clusters whose CIDRs would otherwise collide. The README does not explain globalnet, so treat its presence in the Makefile as a pointer to the website docs rather than a documented feature.

Verification is a first-class step in the README rather than an afterthought. It points to the subctl verify docs and the Automated Troubleshooting docs on the website. Run the verification between each pair of clusters you joined; a two-cluster mesh has one pair, a five-cluster mesh has ten, and a partially connected mesh is the failure mode this step exists to catch.

Gateway election and the single-node bandwidth ceiling

The leader-elected gateway model is deliberate and it has a cost the README does not soften. All inter-cluster traffic passes through one node per cluster, so the aggregate cross-cluster throughput is the throughput of that node's network path. A cluster whose workloads mostly talk to a remote cluster will saturate its gateway long before it saturates its own fabric.

The route-agent component exists to handle the non-gateway nodes. On those nodes, traffic is pushed into the vx-submariner VXLAN tunnel toward the local gateway, which means every remote-bound packet takes an extra encapsulation and decapsulation step on the source side. That is the price of not running a full mesh.

The README does not document what happens to in-flight connections when the gateway role moves. It also does not document rollback. If you need a documented failover behaviour with measured convergence times, this README is silent, and the Known Issues page on the website is the place to check before you commit.

When Submariner is the wrong tool

If you run a single Kubernetes cluster, Submariner adds a gateway node, a route agent and a tunnel for no benefit. The README's own framing, connecting overlay networks of different Kubernetes clusters, assumes at least two clusters.

If your clusters already share one flat network with non-overlapping CIDRs and routing between them, you may not need an overlay at all. Submariner exists to bridge separate overlay networks; where there is only one overlay, there is nothing to bridge.

If you need cross-cluster traffic to be handled by a service mesh with per-request policy, retries and observability, Submariner operates at a different layer. It moves packets between Pod and Service CIDRs; it does not inspect requests. The README says nothing about L7 policy, and its two verification paths, subctl verify and automated troubleshooting, test connectivity, not application semantics.

Finally, if your clusters use overlapping Pod or Service CIDRs, the README's routing model, which decides the path by destination CIDR, has no way to disambiguate. The README does not describe a supported workaround for overlap, although the Makefile's submariner-globalnet image suggests the project has a component aimed at that area.

Cilium Cluster Mesh and the difference in approach

Cilium Cluster Mesh is the alternative most teams compare against, and the difference is structural rather than cosmetic. Cluster Mesh requires Cilium as the CNI in every cluster it joins. Submariner's README states the opposite constraint: Submariner is designed to be network plugin (CNI) agnostic.

That single sentence drives everything else. Cluster Mesh can integrate tightly with its own datapath because it owns the datapath. Submariner cannot, because it must work over Calico, OVN-Kubernetes, or whatever else each cluster runs. The evidence is in the dependency list: the repository's go.mod carries projectcalico/api, ovn-org/libovsdb and ovn-kubernetes/go-controller alongside tigera/operator/api, which is what CNI-agnostic support looks like in practice.

The practical trade-off: if every cluster already runs Cilium and you are happy to keep it that way, Cluster Mesh gives you a tighter integration. If your clusters run different CNIs, or you are not willing to standardise the CNI to get cross-cluster connectivity, Submariner is the option that does not force that decision.

Licence, release cadence and upgrade cost

Submariner is licensed under Apache-2.0, a permissive licence that allows commercial use and modification. The repository carries a LICENSE file at the top level. This is a description of the licence identifier, not legal advice; if you redistribute Submariner inside a product, read the licence text and your own counsel's guidance.

The release history in the repository shows three lines in flight at once: v0.23.3 on 2026-09-23, v0.22.2 on 2026-09-22, and v0.25.0-rc1 on 2026-09-15. Patch releases on older minor lines alongside a release candidate on a newer one is the pattern of a project that backports fixes. The last push to the devel branch was on 2026-09-24.

Upgrade cost is the part the README does not cover. It documents installation through the Operator, subctl and Helm, but it does not document an upgrade procedure or a version compatibility matrix between the Operator, the gateway and the route agent. The go.mod pins k8s.io modules at v0.36.4 and controller-runtime at v0.24.1, so a Kubernetes version bump on your side may force a Submariner upgrade rather than the other way around. Budget for testing subctl verify after every upgrade.

Editorial conclusion

Adopt Submariner when you run multiple Kubernetes clusters on distinct Pod and Service CIDRs and need cross-cluster Pod and Service reachability without changing CNI. Do not adopt it if you need a single cluster, or if you cannot accept that the README itself warns about bugs and points most operational detail to the website. Before committing, verify that each cluster's Pod and Service CIDRs do not overlap, that the gateway nodes can reach each other on the tunnel ports your cable driver uses, and that subctl verify passes between every pair of clusters you intend to connect.

Frequently asked questions

What is Submariner?

Submariner is a tool built to connect overlay networks of different Kubernetes clusters, according to its README. It is CNI-agnostic and supports both encrypted and non-encrypted tunnels between connected clusters.

How do I use Submariner?

The README states Submariner is always deployed using a Go-based Kubernetes custom controller called an Operator, and that subctl and Helm charts wrap that Operator. The recommended method is subctl, which the README says is the default in CI and provides diagnostic features.

How do I set up Submariner across two clusters?

The README points to the subctl Deployment docs and the Helm Deployment docs on submariner.io for the actual steps, and says subctl is the recommended deployment method. It does not print the commands itself, so the website docs are the source to follow.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. submariner-io/submariner on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/submariner-io-submariner.svg)](https://hysenlabs.com/projects/submariner-io-submariner)