Alright, let’s get our hands dirty with multi-cluster federation. You’ve got a few Kubernetes clusters humming along nicely, and now you need them to actually talk to each other and share workloads without you manually playing switchboard operator. This is where tools like Liqo and Admiralty come in. They represent the modern, less-invasive approach to this problem, and frankly, they’re a lot more elegant than the old-school, hair-pulling methods.

The core idea here is peer-to-peer service discovery. Instead of a clunky central control plane that becomes a single point of failure and a configuration nightmare, these tools let your clusters form a sort of mesh. They discover each other, establish secure tunnels, and then transparently extend their APIs. When you deploy a service in Cluster A, Cluster B just sees it, as if by magic. Well, not magic—just some very clever engineering.

Why Liqo and Admiralty Beat the Old Guard

You might be wondering why we’re not just using the deprecated Kubernetes Federation v2 (KubeFed). Simple: it was a beast. Managing it felt like you needed a PhD in “Federation Studies,” and its model of pushing identical resources to multiple clusters was rigid and often didn’t match real-world needs. Liqo and Admiralty flip the script. They’re about pulling and discovering.

Liqo, in particular, creates virtual kubelets in your local cluster that actually represent real nodes in your remote cluster. It’s a genius bit of sleight of hand. Your cluster thinks it’s just scheduling pods onto another node, but that “node” is an entire cluster in a different region. This means any tool that works with standard Kubernetes—your Helm charts, your GitOps workflows, your boring kubectl commands—just keep working. They don’t need to be “federation-aware.” The federation happens at the infrastructure level, which is where it damn well should be.

Getting Started with Liqo: Peering Clusters

First, you’ll need to install Liqo on all clusters you want to peer. Helm is the way to go. Let’s assume you have two clusters: ctx-cluster-a and ctx-cluster-b.

# Add the Liqo Helm repository
helm repo add liqo https://helm.liqo.io/
helm repo update

# Install Liqo on Cluster A
kubectl config use-context ctx-cluster-a
helm install liqo liqo/liqo -n liqo-system --create-namespace

# Repeat for Cluster B
kubectl config use-context ctx-cluster-b
helm install liqo liqo/liqo -n liqo-system --create-namespace

After installation, you need to generate a peer command from one cluster and run it on the other. It’s like a digital handshake.

# On Cluster A, generate the peer command
kubectl config use-context ctx-cluster-a
liqoctl generate peer-command --only-command

This will output a long liqoctl peer ... command. You then take that entire command and run it on Cluster B.

# On Cluster B, run the peer command from Cluster A
kubectl config use-ctx ctx-cluster-b
liqoctl peer <...long-generated-command-here...>

Now, check your peer status. You should see them happily connected.

liqoctl status peer

The Magic of Offloading Pods

Here’s the fun part. Once peered, you can “offload” workloads to the remote cluster. You don’t do this by editing your Deployments; you do it by labeling namespaces. This is Liqo being smart again—it keeps the decision at the right abstraction layer.

# This label tells Liqo to enable offloading for the 'my-offloaded-apps' namespace
apiVersion: v1
kind: Namespace
metadata:
  name: my-offloaded-apps
  labels:
    liqo.io/enabled: "true"

Now, any pod you create in the my-offloaded-apps namespace might get scheduled onto the virtual node representing your remote cluster. Liqo’s scheduler makes the decision based on resource availability and policies you set. You can also be more explicit with topology spread constraints, but the namespace label is the 90% solution.

Admiralty’s Mutating Webhook Approach

While Liqo uses virtual kubelets, Admiralty takes a slightly different path. It uses mutating webhooks. When you create a pod with a specific annotation, the webhook intercepts it and replaces the pod spec with a proxy pod. This proxy then schedules a “shadow pod” on the remote cluster. It’s less transparent than Liqo’s node trick but can be more flexible for complex scheduling policies.

Creating a pod for offloading in Admiralty might look like this:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  annotations:
    multicluster.admiralty.io/elect: ""
spec:
  containers:
  - name: my-app
    image: nginx

The key here is the elect annotation, which tells Admiralty’s webhook, “Hey, this one’s special—handle it.”

The Inevitable Rough Edges and Pitfalls

This isn’t all rainbows and unicorns. Network latency is the big one. If your clusters are on different continents, your east-coast pod talking to a west-coast database via a service IP that’s magically routed back is going to feel that lag. You absolutely must be mindful of your service topology. Use topologyKeys in your Service definitions to hint that traffic should stay local whenever possible.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - port: 80
  topologyKeys:
    - "topology.kubernetes.io/zone"
    - "*" # Fall back to any zone if none found locally

Also, debugging can get… interesting. A pod is stuck in Pending state. Is it a local resource issue? Or is the remote cluster full? You’ll be living in kubectl get virtualnodes and liqoctl output. Embrace it. And for the love of all that is holy, make sure your clusters have mutually exclusive Pod CIDR ranges. If they overlap, the networking will simply fail in bizarre and confusing ways. The tools usually check for this, but you should too.

The bottom line? Liqo and Admiralty are the tools that finally make multi-cluster Kubernetes feel like it’s not a science project. They get out of your way and let you work with the Kubernetes API you already know, just on a bigger, more powerful canvas.