🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

AWS RDS Connection Timeout from EKS Pods — How to Fix It

EKS pods can't connect to RDS? Fix RDS connection timeouts from Kubernetes — covers security groups, VPC peering, subnet routing, and IAM auth issues.

DevOpsBoysApr 18, 20265 min read
Share:Tweet

Your app is running on EKS. Your RDS database is in the same VPC. But pods can't connect — you get Connection timed out or could not connect to server: Connection refused. Here's the full diagnostic playbook.

Most Common Causes

  1. Security group not allowing inbound from EKS nodes/pods
  2. RDS is in a private subnet with no route from pod subnet
  3. Wrong endpoint in connection string
  4. IAM authentication misconfigured (for RDS IAM auth)
  5. RDS in a different VPC without peering

Step 1: Verify the Basics

bash
# Get your pod's IP
kubectl get pod <pod-name> -o wide
# NAME         READY   STATUS    RESTARTS   IP           NODE
# my-app-xyz   1/1     Running   0          10.0.1.145   ip-10-0-1-10
 
# Get RDS endpoint
aws rds describe-db-instances \
  --query 'DBInstances[*].[DBInstanceIdentifier,Endpoint.Address,Endpoint.Port]' \
  --output table

Step 2: Test Connectivity from Inside the Pod

bash
# Install netcat in a debug container, or use a test pod
kubectl run debug --image=nicolaka/netshoot --rm -it -- bash
 
# Test TCP connectivity to RDS
nc -zv your-rds-endpoint.rds.amazonaws.com 5432
# Connection to your-rds-endpoint ... 5432 port [tcp/postgresql] succeeded!
# OR
# nc: connect to your-rds-endpoint port 5432 (tcp) failed: Connection timed out

If you get Connection timed out → it's a network/security group issue. If you get Connection refused → RDS is reachable but rejecting (wrong port, DB not running). If you get Could not resolve host → DNS issue.

Problem 1: Security Group Not Allowing EKS Traffic

This is the most common cause.

Find your RDS security group:

bash
aws rds describe-db-instances \
  --db-instance-identifier your-db \
  --query 'DBInstances[0].VpcSecurityGroups[*].VpcSecurityGroupId'

Find your EKS node security group:

bash
aws eks describe-cluster --name your-cluster \
  --query 'cluster.resourcesVpcConfig.clusterSecurityGroupId'

Check RDS security group inbound rules:

bash
aws ec2 describe-security-groups \
  --group-ids sg-rds-id \
  --query 'SecurityGroups[0].IpPermissions'

Fix: Add inbound rule to RDS security group:

bash
# Allow EKS node security group to reach RDS on port 5432 (PostgreSQL)
aws ec2 authorize-security-group-ingress \
  --group-id sg-rds-id \
  --protocol tcp \
  --port 5432 \
  --source-group sg-eks-nodes-id

Or in Terraform:

hcl
resource "aws_security_group_rule" "eks_to_rds" {
  type                     = "ingress"
  from_port                = 5432
  to_port                  = 5432
  protocol                 = "tcp"
  security_group_id        = aws_security_group.rds.id
  source_security_group_id = aws_security_group.eks_nodes.id
  description              = "Allow EKS nodes to connect to RDS"
}

Problem 2: Pods Use Different Security Group (VPC CNI)

When using AWS VPC CNI, pods get IPs from your VPC — but their security group might be different from the node's security group.

Check if Security Groups for Pods is enabled:

bash
kubectl describe daemonset aws-node -n kube-system | grep ENABLE_POD_ENI

If pods have their own security group, you need to allow that security group in RDS, not the node security group.

Fix with SecurityGroupPolicy:

yaml
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
  name: my-app-sgp
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: my-app
  securityGroups:
    groupIds:
      - sg-pod-security-group-id   # must include RDS access

Problem 3: RDS in Wrong Subnet / No Route

If your RDS is in a private subnet and EKS pods are in a different subnet, they need a route.

bash
# Check RDS subnets
aws rds describe-db-subnet-groups \
  --db-subnet-group-name your-subnet-group \
  --query 'DBSubnetGroups[0].Subnets[*].SubnetIdentifier'
 
# Check route table for EKS pod subnet
aws ec2 describe-route-tables \
  --filters "Name=association.subnet-id,Values=subnet-eks-id"

Both should be in the same VPC. If they're in different availability zones, that's fine — VPC routes within a VPC.

If RDS is in a different VPC, you need VPC peering or AWS Transit Gateway. No amount of security group rules will fix cross-VPC access without routing.

Problem 4: Wrong RDS Endpoint

Don't use the IP address of RDS — always use the DNS endpoint. The IP can change after a failover.

bash
# Wrong - using IP directly
DB_HOST=10.0.2.55  # ← this can change
 
# Correct - using DNS endpoint
DB_HOST=mydb.abc123def456.us-east-1.rds.amazonaws.com

Check your connection string in the pod:

bash
kubectl exec -it <pod-name> -- env | grep -i db_host
kubectl exec -it <pod-name> -- env | grep -i database_url

Problem 5: RDS IAM Authentication Issues

If you're using IAM database authentication (no passwords), you need the correct setup.

Generate a token:

bash
aws rds generate-db-auth-token \
  --hostname mydb.abc123.us-east-1.rds.amazonaws.com \
  --port 5432 \
  --region us-east-1 \
  --username mydbuser

If this fails, the IAM role doesn't have the rds-db:connect permission:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "rds-db:connect",
      "Resource": "arn:aws:rds-db:us-east-1:123456789:dbuser:db-ABCDEFG/mydbuser"
    }
  ]
}

For EKS pods, attach this policy to the IAM role associated with the pod's service account (IRSA).

Problem 6: RDS Not Publicly Accessible (Expected)

RDS should not be publicly accessible. Confirm:

bash
aws rds describe-db-instances \
  --db-instance-identifier your-db \
  --query 'DBInstances[0].PubliclyAccessible'
# false ← correct for production

If it says true and you're in a corp environment, flag it for security review.

Full Diagnostic Checklist

bash
# 1. Pod can resolve RDS DNS?
kubectl exec -it <pod> -- nslookup your-rds-endpoint.rds.amazonaws.com
 
# 2. Pod can reach RDS port?
kubectl run debug --image=nicolaka/netshoot --rm -it -- \
  nc -zv your-rds-endpoint.rds.amazonaws.com 5432
 
# 3. RDS security group allows EKS?
aws ec2 describe-security-groups --group-ids sg-rds-id \
  --query 'SecurityGroups[0].IpPermissions'
 
# 4. RDS is in available state?
aws rds describe-db-instances --db-instance-identifier your-db \
  --query 'DBInstances[0].DBInstanceStatus'
# "available" is good
 
# 5. Check RDS logs for refused connections
aws rds download-db-log-file-portion \
  --db-instance-identifier your-db \
  --log-file-name error/postgresql.log \
  --output text

Prevention: Infrastructure as Code

Define your RDS + EKS security group rules in Terraform so they're never misconfigured:

hcl
resource "aws_db_instance" "main" {
  identifier        = "production-db"
  engine            = "postgres"
  instance_class    = "db.t3.medium"
  vpc_security_group_ids = [aws_security_group.rds.id]
  db_subnet_group_name   = aws_db_subnet_group.main.name
  # never set publicly_accessible = true in production
}
 
resource "aws_security_group" "rds" {
  name   = "rds-sg"
  vpc_id = aws_vpc.main.id
 
  ingress {
    from_port       = 5432
    to_port         = 5432
    protocol        = "tcp"
    security_groups = [aws_security_group.eks_nodes.id]
  }
}

Resources

RDS connectivity issues are always one of these five problems. Run the diagnostic checklist top to bottom and you'll find it within 10 minutes.

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments