Amazon EKS — Data Plane

3 minute read

EKS Data Plane

The data plane is where your applications actually run. Unlike the control plane (AWS-managed), the data plane is your responsibility. You choose the compute type, instance sizes, and scaling strategy.


Data Plane Options

EKS Data Plane Options
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  ┌─────────────────┐  ┌────────────────┐  ┌──────────┐│
│  │ Managed Node    │  │ Self-Managed   │  │ Fargate  ││
│  │ Groups          │  │ Node Groups    │  │          ││
│  │                 │  │                │  │          ││
│  │ AWS manages:    │  │ You manage:    │  │ AWS runs ││
│  │ • AMI updates   │  │ • Everything   │  │ each pod ││
│  │ • Node draining │  │ • ASG          │  │ in its   ││
│  │ • Health checks │  │ • AMI          │  │ own      ││
│  │                 │  │ • Upgrades     │  │ microVM  ││
│  │ You control:    │  │                │  │          ││
│  │ • Instance type │  │ Best for:      │  │ No nodes ││
│  │ • Scaling       │  │ • Custom AMIs  │  │ to manage││
│  │ • Labels/taints │  │ • Special HW   │  │          ││
│  └─────────────────┘  └────────────────┘  └──────────┘│
│                                                         │
│  ◄── Most managed            Most control ──►           │
│  (Fargate)             (Self-Managed Nodes)             │
└─────────────────────────────────────────────────────────┘

Comparison

Feature Managed Node Groups Self-Managed Nodes Fargate
Node management AWS handles AMI updates, draining You handle everything No nodes (serverless)
Instance types Any EC2 type Any EC2 type N/A (resource-based)
Scaling Auto Scaling Group (managed) Auto Scaling Group (yours) Per-pod
DaemonSets ✅ Yes ✅ Yes ❌ No
GPU workloads ✅ Yes ✅ Yes ❌ No
Privileged containers ✅ Yes ✅ Yes ❌ No
Custom AMIs Limited Full control ❌ No
Cost EC2 pricing EC2 pricing Per vCPU/GB/sec
Best for Most workloads Custom requirements Bursty, serverless

For most EKS users, managed node groups are the best choice:

# eksctl config
managedNodeGroups:
  - name: general
    instanceType: m5.xlarge
    desiredCapacity: 3
    minSize: 2
    maxSize: 10
    privateNetworking: true
    labels:
      workload: general

What AWS manages for you:

  • AMI selection and updates
  • Node health monitoring
  • Graceful draining during updates (respects PodDisruptionBudgets)
  • Integration with EKS API for version management

Self-Managed Node Groups

Use when you need:

  • Custom AMIs (security hardening, pre-installed software)
  • Special hardware (FPGA, custom GPU drivers)
  • Full control over the Auto Scaling Group
# eksctl config
nodeGroups:    # Note: nodeGroups, not managedNodeGroups
  - name: custom
    instanceType: p3.2xlarge
    desiredCapacity: 2
    ami: ami-0abc123def456
    overrideBootstrapCommand: |
      #!/bin/bash
      /etc/eks/bootstrap.sh my-cluster --kubelet-extra-args '--node-labels=workload=gpu'

Fargate

Serverless pods — no nodes to manage:

# eksctl config
fargateProfiles:
  - name: default
    selectors:
      - namespace: default
      - namespace: kube-system

Deep dive: See Chapter 6 — Fargate for full coverage.


Hybrid Approach (Best of Both)

Most production clusters use a mix:

Production Cluster — Hybrid Data Plane
┌─────────────────────────────────────────────────────┐
│                                                     │
│  Managed Node Group: "general"                      │
│  m5.xlarge × 3-10 (On-Demand)                      │
│  → Web servers, API services                        │
│                                                     │
│  Managed Node Group: "spot"                         │
│  m5.large × 0-20 (Spot)                             │
│  → Batch jobs, workers, non-critical                │
│                                                     │
│  Fargate Profile: "batch"                           │
│  → Cron jobs, one-off tasks                         │
│                                                     │
│  Self-Managed: "gpu"                                │
│  p3.2xlarge × 1-4 (Custom AMI)                      │
│  → ML inference                                     │
└─────────────────────────────────────────────────────┘

Node Components

Every worker node (EC2-based) runs:

Component Purpose
kubelet Communicates with API server, manages pod lifecycle
kube-proxy Manages iptables/IPVS rules for Service networking
VPC CNI (aws-node) Assigns VPC IP addresses to pods
containerd Container runtime (replaced Docker in K8s 1.24+)

Common Mistakes

Mistake Impact
Using self-managed when managed works Extra operational burden for no benefit
All On-Demand instances Paying 2-3x more than needed
No node group separation Can’t scale or manage workloads independently
Fargate for everything No DaemonSets, higher per-pod cost for steady workloads

Quick Reference

Recommendation Data Plane Type
Default choice Managed Node Groups
Custom AMI needed Self-Managed Nodes
Serverless / bursty Fargate
Cost optimization Spot Managed Node Groups
GPU / ML Self-Managed (or managed with GPU AMI)

What’s Next?

Let’s explore how kubectl reaches the API server: API Server Endpoint.