0Pricing
AWS Solutions Architect · Lesson

EKS Networking: VPC CNI and Load Balancing

Use the Amazon VPC CNI plugin so pods get native VPC IP addresses, and expose services with the AWS Load Balancer Controller.

EKS Networking: VPC CNI and Load Balancing is a free AWS Solutions Architect lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AWS Solutions Architect learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Kubernetes Networking Basics

Kubernetes requires every pod to have a unique, routable IP address and for pods to communicate with each other without NAT. The Container Network Interface (CNI) plugin is responsible for assigning IPs and configuring network routes on worker nodes. Different Kubernetes platforms use different CNI implementations; AWS uses the Amazon VPC CNI plugin to integrate Kubernetes networking directly with the VPC layer.

Amazon VPC CNI Plugin

The Amazon VPC CNI plugin assigns each pod an IP address directly from your VPC's subnet CIDR range. This means pods are first-class VPC citizens — they can be accessed by other VPC resources, on-premises systems via VPN/Direct Connect, and security groups without any overlay network translation. Each EC2 worker node maintains a pool of secondary private IPs (one per ENI slot) that are assigned to pods as they schedule.

# Check the VPC CNI version installed in your cluster
kubectl describe daemonset aws-node -n kube-system | grep Image

# View the secondary IPs assigned to a node
aws ec2 describe-network-interfaces \
  --filters 'Name=attachment.instance-id,Values=i-0abcdef1234567890' \
  --query 'NetworkInterfaces[].PrivateIpAddresses[].PrivateIpAddress'

ENI and IP Address Warm Pool

The VPC CNI plugin maintains a warm pool of pre-allocated IP addresses on each node to allow fast pod scheduling. When a node starts, the CNI attaches multiple ENIs and assigns secondary IPs up to the WARM_IP_TARGET or MINIMUM_IP_TARGET environment variables. The maximum number of pods a node can run is therefore limited by the instance's ENI count multiplied by the IPs per ENI, which varies by instance type.

# Check maximum pods supported by an instance type
aws ec2 describe-instance-types \
  --instance-types m5.large \
  --query 'InstanceTypes[].NetworkInfo.{MaxENIs:MaximumNetworkInterfaces,IPv4sPerENI:Ipv4AddressesPerInterface}'

# Max pods formula: (MaxENIs x (IPv4sPerENI - 1)) + 2
# m5.large: 3 ENIs x (10-1) + 2 = 29 pods

Security Groups for Pods

By default, all pods on a node share the node's security group. With the Security Groups for Pods feature, you can assign individual security groups to specific pods using the SecurityGroupPolicy custom resource. This allows fine-grained network access control — for example, only a database pod can receive traffic on port 5432 from the API pod's security group. This feature requires the VPC CNI version 1.7.7 or later and a trunk ENI on the node.

# Define a SecurityGroupPolicy (custom resource)
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
  name: db-pod-sg-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      role: database
  securityGroups:
    groupIds:
    - sg-0db1234567890abcd

Kubernetes Service Types on EKS

Kubernetes Services expose a set of pods under a stable DNS name and IP. On EKS, the three relevant service types are: ClusterIP (internal cluster communication only), NodePort (opens a port on every node — rarely used on EKS), and LoadBalancer (provisions an AWS load balancer automatically). The LoadBalancer type is how most internet-facing EKS services are exposed.

# Expose a deployment with a LoadBalancer service
kubectl expose deployment my-api \
  --type=LoadBalancer \
  --name=my-api-svc \
  --port=80 \
  --target-port=8080

# Check the assigned AWS load balancer hostname
kubectl get svc my-api-svc -o wide

AWS Load Balancer Controller

The AWS Load Balancer Controller is an open-source Kubernetes controller that manages ALB and NLB resources on behalf of EKS clusters. When you create a Kubernetes Ingress object, the controller provisions an Application Load Balancer. When you create a Service of type LoadBalancer with the correct annotations, it provisions a Network Load Balancer. The controller replaces the older in-tree Kubernetes load balancer provider.

# Install AWS Load Balancer Controller with Helm
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=my-cluster \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set region=us-east-1 \
  --set vpcId=vpc-0abc1234def567890

Kubernetes Ingress with ALB

An Kubernetes Ingress object defines HTTP/HTTPS routing rules — path-based and host-based — into your cluster. The AWS Load Balancer Controller reads Ingress objects annotated with kubernetes.io/ingress.class: alb and creates a corresponding Application Load Balancer with listener rules that match. This eliminates the need to manually create ALBs and target groups for each application service.

# Ingress YAML that creates an ALB
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  namespace: production
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  rules:
  - http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-svc
            port:
              number: 80

NLB for TCP/UDP Workloads

When your workload requires TCP or UDP (not HTTP) — such as a game server, gRPC service, or database proxy — use the NLB instead of ALB. Annotate the Kubernetes Service with service.beta.kubernetes.io/aws-load-balancer-type: 'external' and service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: 'ip'. The controller provisions an NLB with pod IPs as direct targets, bypassing node-level port forwarding for lower latency.

# Service YAML that creates an NLB with IP targets
apiVersion: v1
kind: Service
metadata:
  name: grpc-svc
  namespace: production
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: 'external'
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: 'ip'
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
  type: LoadBalancer
  selector:
    app: grpc-server
  ports:
  - port: 50051
    targetPort: 50051
    protocol: TCP

DNS Resolution Within the Cluster

EKS runs CoreDNS as the cluster DNS provider. Every service gets a DNS name in the format service-name.namespace.svc.cluster.local, which resolves to the service's ClusterIP. Pods are also discoverable via DNS. CoreDNS is deployed as a Deployment (not a DaemonSet), and its replicas should be scaled based on cluster size. EKS manages CoreDNS as an add-on, allowing automated version upgrades.

# Verify DNS resolution from within a pod
kubectl run dns-test --image=busybox --rm -it --restart=Never -- \
  nslookup kubernetes.default.svc.cluster.local

# Expected output: Name: kubernetes.default.svc.cluster.local
# Address: 10.100.0.1 (ClusterIP of the kubernetes service)

Network Policies in EKS

Kubernetes NetworkPolicy objects define allow rules for pod-to-pod and pod-to-external traffic. By default, all pods in a cluster can communicate freely. To enforce zero-trust networking you can install the Amazon VPC CNI network policy controller (available since VPC CNI v1.14). Network policies are evaluated at the Linux kernel level using eBPF, providing high-performance enforcement without an overlay network.

# NetworkPolicy: allow traffic to api pods only from frontend pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow-frontend
  namespace: production
spec:
  podSelector:
    matchLabels:
      role: api
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 8080

VPC CNI Troubleshooting Tips

Common EKS networking issues include IP address exhaustion (fix by enabling prefix delegation or adding larger subnets), pods stuck in Pending because the node has no available secondary IPs, and intermittent DNS resolution failures caused by insufficient CoreDNS replicas. Use kubectl describe pod to check events, kubectl describe node to see allocated IP counts, and CloudWatch Container Insights to monitor DNS error rates at cluster scale.

# Enable prefix delegation to increase pod density per node
kubectl set env daemonset aws-node \
  -n kube-system \
  ENABLE_PREFIX_DELEGATION=true \
  WARM_PREFIX_TARGET=1

# Check current IP usage on a node
kubectl describe node ip-10-0-1-100.ec2.internal | grep -A5 'Allocatable'

Quick Check

Test your understanding of AWS Solutions Architect (SAA-C03) concepts from this lesson.

Lesson Recap

In this lesson you learned: the Amazon VPC CNI plugin assigns native VPC IPs to every pod for seamless VPC integration, the AWS Load Balancer Controller provisions ALBs for HTTP Ingress and NLBs for TCP/UDP Services, and Security Groups for Pods enable pod-level network access control. Next up we explore IRSA to bind fine-grained IAM roles to Kubernetes service accounts.

Frequently asked questions

Is the “EKS Networking: VPC CNI and Load Balancing” lesson free?

Yes — the full text of “EKS Networking: VPC CNI and Load Balancing” is free to read here on the web, and the AWS Solutions Architect course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AWS Solutions Architect course, upgrade to CoddyKit PRO.

What will I learn in “EKS Networking: VPC CNI and Load Balancing”?

Use the Amazon VPC CNI plugin so pods get native VPC IP addresses, and expose services with the AWS Load Balancer Controller. You practise AWS Solutions Architect with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start AWS Solutions Architect?

No prior experience is required. AWS Solutions Architect on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “EKS Networking: VPC CNI and Load Balancing” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this AWS Solutions Architect lesson?

Yes. Every AWS Solutions Architect lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. EKS Control Plane and Worker Nodes
  2. Fargate Profiles for Serverless Pods
  3. EKS Networking: VPC CNI and Load Balancing
  4. IAM Roles for Service Accounts (IRSA)
← Back to AWS Solutions Architect