Skip to content

KubedAI/eks-hybrid-azure-stack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EKS Hybrid Nodes on Azure

Extend an Amazon EKS cluster to Azure by running Azure VMs as Kubernetes worker nodes — managed from a single EKS control plane.

This project provisions the full stack end-to-end: an EKS cluster, a site-to-site IPsec VPN between AWS and Azure, Cilium CNI for cross-cloud pod networking, and Azure VMs that automatically join the cluster via cloud-init. Everything is driven from one config.env file.

Why

Running Kubernetes across clouds is hard. You need encrypted connectivity, identity federation without long-lived secrets, overlay networking that works across providers, and automation that ties it all together. This project solves that:

Challenge How it's solved
Cross-cloud connectivity IPsec VPN tunnel (AES-256) between AWS VPN Gateway and Azure VPN Gateway
Authentication without static keys IAM Roles Anywhere — X.509 certificates auto-rotated every hour
Pod networking across clouds Cilium CNI with Geneve tunneling for seamless pod-to-pod communication
Configuration drift Single config.env drives every script — zero hardcoded values
Node provisioning cloud-init auto-joins Azure VMs to the EKS cluster on first boot

When to Use This

Core principle: Orchestrate anywhere, compute where the data lives.

Use Case Why EKS Hybrid on Azure?
Data lives in Azure Run compute next to Azure Blob/SQL — avoid moving terabytes over the wire
Existing Azure infrastructure Add Kubernetes orchestration to VMs you already own without migrating them to AWS
GPU/HPC on Azure Tap into Azure NC/ND-series GPUs managed from a single EKS control plane
Data sovereignty Keep data in an Azure region for compliance while using EKS for orchestration
Gradual migration Move workloads to AWS incrementally — hybrid nodes bridge the transition
Burst capacity Overflow to Azure VMs when AWS capacity is constrained or reserved instances are full

See Architecture & Use Cases for detailed scenarios, advantages, and trade-offs.

Architecture

flowchart LR
    subgraph AWS["AWS VPC (10.0.0.0/16)"]
        direction TB
        EKS["EKS Control Plane"]
        subgraph EC2["EC2 Node Group"]
            N1["Node 1\n(VPC CNI)"]
            N2["Node 2\n(VPC CNI)"]
        end
        VGW["VPN Gateway"]
        IAM["IAM Roles\nAnywhere"]
        EKS --> EC2
    end

    subgraph Azure["Azure VNet (10.80.0.0/16)"]
        direction TB
        AZVPN["VPN Gateway"]
        subgraph Subnet["Workload Subnet (10.80.1.0/24)"]
            HN1["Hybrid Node 1\n(Cilium CNI)"]
            HN2["Hybrid Node N\n(Cilium CNI)"]
        end
        AZVPN --- Subnet
    end

    VGW <-->|"IPsec VPN\n(AES-256)"| AZVPN
    EKS -->|"K8s API"| HN1 & HN2
    IAM -.->|"X.509 cert auth\n(auto-rotate 1hr)"| HN1 & HN2

    subgraph Pods["Pod Networking"]
        direction LR
        AWSP["AWS Pods\n(VPC CNI)"]
        AZP["Hybrid Pods\n(10.81.0.0/16)"]
    end

    EC2 --> AWSP
    Subnet --> AZP
    AWSP <-->|"Geneve Tunnel"| AZP

    style AWS fill:#ff9900,color:#fff,stroke:#cc7a00
    style Azure fill:#0078d4,color:#fff,stroke:#005a9e
    style Pods fill:#2d6a4f,color:#fff,stroke:#1b4332
    style EC2 fill:#ffcc80,color:#000,stroke:#cc7a00
    style Subnet fill:#80b3e0,color:#000,stroke:#005a9e
Loading

What gets created:

AWS Azure Networking
EKS cluster with hybrid node support Resource Group IPsec VPN tunnel between gateways
EC2 managed node group VNet + workload/gateway subnets Cilium CNI (Geneve overlay)
VPN Gateway + Customer Gateway VPN Gateway (VpnGw1) NSG + Security Group rules
IAM Roles Anywhere (Trust Anchor, Profile) Ubuntu 22.04 VMs with cloud-init Route tables for cross-cloud traffic

Quick Start

Prerequisites

  • AWS: CLI configured, eksctl v0.150.0+, kubectl, helm
  • Azure: CLI authenticated (az login), Contributor access
  • Local: OpenSSL, SSH, Bash

1. Configure

cp config.env.template config.env
nano config.env   # Set AWS_ACCOUNT_ID, AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID

2. Deploy

cd setup && ./deploy-all.sh

Deploys everything in order. Takes ~60-90 min (Azure VPN Gateway creation is the bottleneck at ~45 min).

3. Verify

kubectl get nodes -o wide           # 2 AWS nodes + Azure hybrid nodes
./setup/check-vpn-status.sh         # VPN tunnel health
kubectl apply -f examples/test-hybrid-workload.yaml
kubectl get pods -o wide             # Pods running on Azure with 10.81.x.x IPs

4. Cleanup

cd cleanup && ./cleanup-all.sh       # ~25 min, saves ~$670/month

Project Structure

config.env.template                  # All configuration lives here
setup/
  00-load-config.sh                  # Config loader (all scripts source this)
  01-deploy-eks-cluster.sh           # EKS + eksctl (20 min)
  02-setup-aws-vpn.sh               # VPN Gateway + Customer Gateway (5 min)
  03-setup-azure-infrastructure.sh   # VNet, VPN Gateway, NSG, routes (45 min)
  04-connect-vpn-tunnels.sh          # Wire up AWS <-> Azure VPN (5 min)
  05-install-cilium.sh               # Cilium CNI for hybrid pods (5 min)
  06-create-azure-vm.sh [N]          # Azure VM + auto-join via cloud-init (10 min)
  07-join-hybrid-node.sh             # Manual join (optional, for re-joins)
  deploy-all.sh                      # Runs everything end-to-end
  check-vpn-status.sh               # VPN health check utility
  aws-eks-cluster.yaml.template      # eksctl config template (envsubst)
cleanup/
  01-07 cleanup scripts              # Reverse-order teardown
  cleanup-all.sh                     # Full cleanup with confirmation
examples/
  test-hybrid-workload.yaml          # Basic hybrid node test
  cross-cloud-communication-test.yaml
  multi-cloud-deployment.yaml
  spark-pi-job.yaml                  # Apache Spark on hybrid nodes
docs/
  01-architecture-and-use-cases.md   # Design deep-dive
  02-connectivity-options.md         # VPN vs Direct Connect vs Cloud Exchange
  03-iam-roles-anywhere.md           # Certificate auth handshake explained
  04-implementation-guide.md         # Step-by-step walkthrough

How It Works

flowchart LR
    A["config.env"] -->|"source"| B["00-load-config.sh"]
    B --> C["Setup Scripts\n01-07"]
    C -->|"envsubst"| D["eksctl YAML"]
    C -->|"state files"| E["~/.eks-hybrid-azure/\n$CLUSTER_NAME/*.env"]
    E -->|"read by"| F["Cleanup Scripts\n01-07"]
    B --> F

    style A fill:#6c757d,color:#fff
    style B fill:#ffc107,color:#000
    style E fill:#17a2b8,color:#fff
Loading

All configuration flows from config.env. Scripts save runtime state (VPN IDs, IPs, ARNs) to ~/.eks-hybrid-azure/$CLUSTER_NAME/ so subsequent scripts and cleanup can reference them. Every script is idempotent — safe to re-run.

Configuration

All values are set in config.env (copy from config.env.template). Key settings:

Variable Default Purpose
CLUSTER_NAME spark-hybrid-test Names all AWS/Azure resources
AWS_REGION us-west-2 AWS region
AZURE_LOCATION westus2 Azure region
AWS_VPC_CIDR 10.0.0.0/16 AWS VPC network
AZURE_VNET_CIDR 10.80.0.0/16 Azure VNet network
HYBRID_POD_CIDR 10.81.0.0/16 Cilium pod overlay
K8S_VERSION 1.34 Kubernetes version
NODE_INSTANCE_TYPE t3.medium AWS EC2 instance type
AZURE_VM_SIZE Standard_D2s_v3 Azure VM size

CIDRs must not overlap. The defaults are chosen to avoid collisions.

Cost

Resource Monthly
EKS Cluster $73
EC2 Nodes (2x) $60
Azure VM $70
AWS VPN $36
Azure VPN Gateway $140
NAT Gateway + other $291
Total ~$670/month

Save 30-40% with Reserved Instances. Delete resources when not in use.

Scale

Add more hybrid nodes at any time:

./setup/06-create-azure-vm.sh 2    # Adds hybrid-node-2
./setup/06-create-azure-vm.sh 3    # Adds hybrid-node-3

Each VM auto-joins the cluster via cloud-init. No manual SSH or configuration needed.

Documentation

Guide Description
Quick Start Fastest path to a running cluster
Architecture & Use Cases Design decisions, network layout, use cases
Connectivity Options VPN vs Direct Connect vs Cloud Exchange
IAM Roles Anywhere Certificate auth handshake, trust chain, rotation
Implementation Guide Detailed step-by-step with code examples
Setup Guide Script-by-script deployment reference
Cleanup Guide Teardown details and cost savings
Examples Spark, cross-cloud, multi-cloud workloads

Troubleshooting

Symptom Debug command Common cause
VPN not connecting ./setup/check-vpn-status.sh PSK mismatch, NSG blocking UDP 500/4500
Node not joining ssh ... sudo journalctl -u kubelet -n 100 Certificate issue, IAM Roles Anywhere misconfigured
Pods stuck Pending kubectl -n kube-system logs ds/cilium Cilium IPAM pool exhausted
Node NotReady kubectl describe node <name> Cilium not running on hybrid node

See the Implementation Guide for detailed troubleshooting.

Important

  • Never commit config.env — it contains account IDs and is gitignored
  • Certificates are gitignored — generate fresh ones per deployment
  • Set up billing alerts — this stack costs ~$22/day
  • Test in dev first — don't deploy to production without validation

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Test end-to-end
  4. Submit a pull request

License

Apache License 2.0 — see LICENSE for details.

About

A reference implementation for running Amazon EKS in a hybrid multi-cloud configuration with Azure-based worker nodes. This project demonstrates how to extend EKS control plane capabilities across cloud providers, enabling workloads to run on Azure compute while maintaining AWS EKS orchestration.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages