Claude Skill

eks

AWS EKS Kubernetes management for clusters, node groups, and workloads. Use when creating clusters, configuring IRSA, managing node groups, deploying applications, or integrating with AWS services.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download itsmostafa-aws-agent-skills-skills_eks-e786d25.zip · 6 KB
Part of itsmostafa/aws-agent-skills — 17 skills

Install

skills CLI npx skills add https://github.com/itsmostafa/aws-agent-skills/tree/main/skills/eks
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install itsmostafa-aws-agent-skills@llmmart
Git git clone https://github.com/itsmostafa/aws-agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole itsmostafa/aws-agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

AWS EKS

Amazon Elastic Kubernetes Service (EKS) runs Kubernetes without installing and operating your own control plane. EKS manages the control plane and integrates with AWS services.

Table of Contents

Core Concepts

Control Plane

Managed by AWS. Runs Kubernetes API server, etcd, and controllers across multiple AZs.

Node Groups

Type Description
Managed AWS manages provisioning, updates
Self-managed You manage EC2 instances
Fargate Serverless, per-pod compute

IRSA (IAM Roles for Service Accounts)

Associates Kubernetes service accounts with IAM roles for fine-grained AWS permissions.

Add-ons

Operational software: CoreDNS, kube-proxy, VPC CNI, EBS CSI driver.

Common Patterns

Create a Cluster

AWS CLI:

# Create cluster role
aws iam create-role \
  --role-name eks-cluster-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "eks.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

aws iam attach-role-policy \
  --role-name eks-cluster-role \
  --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy

# Create cluster
aws eks create-cluster \
  --name my-cluster \
  --role-arn arn:aws:iam::123456789012:role/eks-cluster-role \
  --resources-vpc-config subnetIds=subnet-12345678,subnet-87654321,securityGroupIds=sg-12345678

# Wait for cluster
aws eks wait cluster-active --name my-cluster

# Update kubeconfig
aws eks update-kubeconfig --name my-cluster --region us-east-1

eksctl (Recommended):

# Create cluster with managed node group
eksctl create cluster \
  --name my-cluster \
  --region us-east-1 \
  --version 1.29 \
  --nodegroup-name standard-workers \
  --node-type t3.medium \
  --nodes 3 \
  --nodes-min 1 \
  --nodes-max 5 \
  --managed

Add Managed Node Group

# Create node role
aws iam create-role \
  --role-name eks-node-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy

# Create node group
aws eks create-nodegroup \
  --cluster-name my-cluster \
  --nodegroup-name standard-workers \
  --node-role arn:aws:iam::123456789012:role/eks-node-role \
  --subnets subnet-12345678 subnet-87654321 \
  --instance-types t3.medium \
  --scaling-config minSize=1,maxSize=5,desiredSize=3 \
  --ami-type AL2_x86_64

Configure IRSA

# Enable OIDC provider
eksctl utils associate-iam-oidc-provider \
  --cluster my-cluster \
  --approve

# Create IAM role for service account
eksctl create iamserviceaccount \
  --cluster my-cluster \
  --namespace default \
  --name my-app-sa \
  --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
  --approve

Manual IRSA setup:

# Get OIDC issuer
OIDC_ISSUER=$(aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text)
OIDC_ID=${OIDC_ISSUER##*/}

# Create trust policy
cat > trust-policy.json << EOF
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}:sub": "system:serviceaccount:default:my-app-sa",
        "oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}:aud": "sts.amazonaws.com"
      }
    }
  }]
}
EOF

aws iam create-role --role-name my-app-role --assume-role-policy-document file://trust-policy.json

Kubernetes Service Account

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app-sa
  namespace: default
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-role

Install Add-ons

# CoreDNS
aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name coredns \
  --addon-version v1.11.1-eksbuild.4

# VPC CNI
aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name vpc-cni \
  --addon-version v1.16.0-eksbuild.1

# kube-proxy
aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name kube-proxy \
  --addon-version v1.29.0-eksbuild.1

# EBS CSI Driver
aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name aws-ebs-csi-driver \
  --addon-version v1.27.0-eksbuild.1 \
  --service-account-role-arn arn:aws:iam::123456789012:role/ebs-csi-role

Deploy Application

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      serviceAccountName: my-app-sa
      containers:
      - name: app
        image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: my-app
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: my-app

CLI Reference

Cluster Management

Command Description
aws eks create-cluster Create cluster
aws eks describe-cluster Get cluster details
aws eks update-cluster-config Update cluster settings
aws eks delete-cluster Delete cluster
aws eks update-kubeconfig Configure kubectl

Node Groups

Command Description
aws eks create-nodegroup Create node group
aws eks describe-nodegroup Get node group details
aws eks update-nodegroup-config Update node group
aws eks delete-nodegroup Delete node group

Add-ons

Command Description
aws eks create-addon Install add-on
aws eks describe-addon Get add-on details
aws eks update-addon Update add-on
aws eks delete-addon Remove add-on

Best Practices

Security

  • Use IRSA for pod-level AWS permissions
  • Enable cluster encryption with KMS
  • Use private endpoint for API server
  • Enable audit logging to CloudWatch
  • Use security groups for pods
  • Implement network policies
# Enable secrets encryption
aws eks create-cluster \
  --name my-cluster \
  --encryption-config '[{
    "provider": {"keyArn": "arn:aws:kms:us-east-1:123456789012:key/..."},
    "resources": ["secrets"]
  }]' \
  ...

High Availability

  • Deploy across multiple AZs
  • Use managed node groups
  • Set pod disruption budgets
  • Configure horizontal pod autoscaling

Cost Optimization

  • Use Spot instances for non-critical workloads
  • Right-size nodes and pods
  • Use Fargate for variable workloads
  • Implement cluster autoscaler
  • Use Karpenter for efficient scaling

Troubleshooting

Cannot Connect to Cluster

# Verify kubeconfig
aws eks update-kubeconfig --name my-cluster --region us-east-1

# Check IAM identity
aws sts get-caller-identity

# Verify cluster status
aws eks describe-cluster --name my-cluster --query 'cluster.status'

Nodes Not Joining

Check:

  • Node IAM role has required policies
  • Security groups allow node-to-control-plane communication
  • Nodes have network access to API server
# Check node status
kubectl get nodes

# Check aws-auth ConfigMap
kubectl describe configmap aws-auth -n kube-system

# Check node logs (SSH to node)
journalctl -u kubelet

Pod Cannot Access AWS Services

# Verify IRSA setup
kubectl describe sa my-app-sa

# Check pod environment
kubectl exec my-pod -- env | grep AWS

# Test credentials
kubectl exec my-pod -- aws sts get-caller-identity

DNS Issues

# Check CoreDNS pods
kubectl get pods -n kube-system -l k8s-app=kube-dns

# Test DNS resolution
kubectl run test --image=busybox:1.28 --rm -it -- nslookup kubernetes

# Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns

References

Files (aws-agent-skills)
  • cluster-setup.md 8.5 KB
    # EKS Cluster Setup
    
    Comprehensive cluster configuration and setup patterns.
    
    ## Cluster Architecture Options
    
    ### Public Cluster
    
    API server accessible from internet, nodes in public subnets.
    
    ```bash
    eksctl create cluster \
      --name my-cluster \
      --region us-east-1 \
      --nodegroup-name standard-workers \
      --node-type t3.medium \
      --nodes 3
    ```
    
    ### Private Cluster
    
    API server only accessible from VPC.
    
    ```bash
    eksctl create cluster \
      --name my-cluster \
      --region us-east-1 \
      --nodegroup-name standard-workers \
      --node-type t3.medium \
      --nodes 3 \
      --node-private-networking \
      --vpc-private-subnets subnet-private1,subnet-private2
    ```
    
    ### Fully Private Cluster
    
    No public access at all, requires VPN/Direct Connect.
    
    ```bash
    aws eks create-cluster \
      --name my-cluster \
      --role-arn arn:aws:iam::123456789012:role/eks-cluster-role \
      --resources-vpc-config \
        subnetIds=subnet-private1,subnet-private2,\
        endpointPublicAccess=false,\
        endpointPrivateAccess=true
    ```
    
    ## VPC Configuration
    
    ### Required Subnets
    
    - **Control plane**: Needs subnets in at least 2 AZs
    - **Worker nodes**: Can be public or private
    - **Load balancers**: Need subnets tagged appropriately
    
    ### Subnet Tags
    
    ```bash
    # Public subnets (for public load balancers)
    aws ec2 create-tags \
      --resources subnet-12345678 \
      --tags Key=kubernetes.io/role/elb,Value=1
    
    # Private subnets (for internal load balancers)
    aws ec2 create-tags \
      --resources subnet-87654321 \
      --tags Key=kubernetes.io/role/internal-elb,Value=1
    
    # Cluster ownership (required for all subnets)
    aws ec2 create-tags \
      --resources subnet-12345678 subnet-87654321 \
      --tags Key=kubernetes.io/cluster/my-cluster,Value=shared
    ```
    
    ### VPC CNI Configuration
    
    ```bash
    # Enable prefix delegation for more IPs per node
    kubectl set env daemonset aws-node \
      -n kube-system \
      ENABLE_PREFIX_DELEGATION=true
    
    # Configure custom networking (pods in different subnets)
    kubectl set env daemonset aws-node \
      -n kube-system \
      AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
    ```
    
    ## Node Groups
    
    ### Managed Node Group with Launch Template
    
    ```bash
    # Create launch template
    aws ec2 create-launch-template \
      --launch-template-name eks-node-template \
      --launch-template-data '{
        "BlockDeviceMappings": [{
          "DeviceName": "/dev/xvda",
          "Ebs": {"VolumeSize": 100, "VolumeType": "gp3", "Encrypted": true}
        }],
        "MetadataOptions": {
          "HttpTokens": "required",
          "HttpEndpoint": "enabled"
        }
      }'
    
    # Create node group with launch template
    aws eks create-nodegroup \
      --cluster-name my-cluster \
      --nodegroup-name custom-workers \
      --node-role arn:aws:iam::123456789012:role/eks-node-role \
      --subnets subnet-12345678 subnet-87654321 \
      --launch-template name=eks-node-template,version=1 \
      --scaling-config minSize=1,maxSize=10,desiredSize=3
    ```
    
    ### Spot Instances
    
    ```bash
    eksctl create nodegroup \
      --cluster my-cluster \
      --name spot-workers \
      --node-type t3.medium,t3.large,t3a.medium,t3a.large \
      --nodes 3 \
      --spot
    ```
    
    ### ARM64 (Graviton)
    
    ```bash
    aws eks create-nodegroup \
      --cluster-name my-cluster \
      --nodegroup-name graviton-workers \
      --node-role arn:aws:iam::123456789012:role/eks-node-role \
      --subnets subnet-12345678 \
      --ami-type AL2_ARM_64 \
      --instance-types t4g.medium m6g.medium
    ```
    
    ### GPU Nodes
    
    ```bash
    aws eks create-nodegroup \
      --cluster-name my-cluster \
      --nodegroup-name gpu-workers \
      --node-role arn:aws:iam::123456789012:role/eks-node-role \
      --subnets subnet-12345678 \
      --ami-type AL2_x86_64_GPU \
      --instance-types p3.2xlarge g4dn.xlarge \
      --scaling-config minSize=0,maxSize=5,desiredSize=0
    ```
    
    ## Fargate
    
    ### Create Fargate Profile
    
    ```bash
    # Create pod execution role
    aws iam create-role \
      --role-name eks-fargate-role \
      --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [{
          "Effect": "Allow",
          "Principal": {"Service": "eks-fargate-pods.amazonaws.com"},
          "Action": "sts:AssumeRole"
        }]
      }'
    
    aws iam attach-role-policy \
      --role-name eks-fargate-role \
      --policy-arn arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy
    
    # Create Fargate profile
    aws eks create-fargate-profile \
      --cluster-name my-cluster \
      --fargate-profile-name default-fargate \
      --pod-execution-role-arn arn:aws:iam::123456789012:role/eks-fargate-role \
      --subnets subnet-private1 subnet-private2 \
      --selectors namespace=default,labels={compute=fargate}
    ```
    
    ### Deploy to Fargate
    
    ```yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: fargate-pod
      labels:
        compute: fargate  # Matches Fargate profile selector
    spec:
      containers:
      - name: app
        image: nginx
    ```
    
    ## Cluster Autoscaler
    
    ```bash
    # Create IRSA for cluster autoscaler
    eksctl create iamserviceaccount \
      --cluster my-cluster \
      --namespace kube-system \
      --name cluster-autoscaler \
      --attach-policy-arn arn:aws:iam::123456789012:policy/ClusterAutoscalerPolicy \
      --approve
    
    # Deploy cluster autoscaler
    kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
    
    # Configure for cluster
    kubectl -n kube-system annotate deployment cluster-autoscaler \
      cluster-autoscaler.kubernetes.io/safe-to-evict="false"
    
    kubectl -n kube-system set env deployment cluster-autoscaler \
      AWS_REGION=us-east-1 \
      CLUSTER_NAME=my-cluster
    ```
    
    ## Karpenter (Recommended)
    
    ```bash
    # Install Karpenter
    helm install karpenter oci://public.ecr.aws/karpenter/karpenter \
      --namespace karpenter --create-namespace \
      --set settings.clusterName=my-cluster \
      --set settings.clusterEndpoint=$(aws eks describe-cluster --name my-cluster --query "cluster.endpoint" --output text) \
      --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789012:role/karpenter-role
    
    # Create NodePool
    cat <<EOF | kubectl apply -f -
    apiVersion: karpenter.sh/v1beta1
    kind: NodePool
    metadata:
      name: default
    spec:
      template:
        spec:
          requirements:
            - key: kubernetes.io/arch
              operator: In
              values: ["amd64", "arm64"]
            - key: karpenter.sh/capacity-type
              operator: In
              values: ["spot", "on-demand"]
          nodeClassRef:
            name: default
      limits:
        cpu: 1000
      disruption:
        consolidationPolicy: WhenUnderutilized
    EOF
    ```
    
    ## Load Balancer Controller
    
    ```bash
    # Create IRSA
    eksctl create iamserviceaccount \
      --cluster my-cluster \
      --namespace kube-system \
      --name aws-load-balancer-controller \
      --attach-policy-arn arn:aws:iam::123456789012:policy/AWSLoadBalancerControllerIAMPolicy \
      --approve
    
    # Install controller
    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
    ```
    
    ### Ingress Example
    
    ```yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ingress
      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: /
            pathType: Prefix
            backend:
              service:
                name: my-service
                port:
                  number: 80
    ```
    
    ## Logging and Monitoring
    
    ### Enable Control Plane Logging
    
    ```bash
    aws eks update-cluster-config \
      --name my-cluster \
      --logging '{
        "clusterLogging": [{
          "types": ["api", "audit", "authenticator", "controllerManager", "scheduler"],
          "enabled": true
        }]
      }'
    ```
    
    ### Container Insights
    
    ```bash
    # Install CloudWatch agent and Fluent Bit
    curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml | \
      sed "s/{{cluster_name}}/my-cluster/g; s/{{region_name}}/us-east-1/g" | \
      kubectl apply -f -
    ```
    
    ## Security
    
    ### Secrets Encryption
    
    ```bash
    # Create KMS key
    aws kms create-key --description "EKS secrets encryption"
    
    # Enable encryption
    aws eks create-cluster \
      --name my-cluster \
      --encryption-config '[{
        "provider": {"keyArn": "arn:aws:kms:us-east-1:123456789012:key/..."},
        "resources": ["secrets"]
      }]' \
      ...
    ```
    
    ### Security Groups for Pods
    
    ```bash
    # Enable security groups for pods
    aws eks update-cluster-config \
      --name my-cluster \
      --resources-vpc-config \
        endpointPublicAccess=true,\
        endpointPrivateAccess=true,\
        securityGroupIds=sg-12345678
    
    # Annotate node group
    kubectl annotate node <node> \
      vpc.amazonaws.com/pod-eni=enabled
    ```
    
  • SKILL.md 9.4 KB
    ---
    name: eks
    description: AWS EKS Kubernetes management for clusters, node groups, and workloads. Use when creating clusters, configuring IRSA, managing node groups, deploying applications, or integrating with AWS services.
    last_updated: "2026-01-07"
    doc_source: https://docs.aws.amazon.com/eks/latest/userguide/
    ---
    
    # AWS EKS
    
    Amazon Elastic Kubernetes Service (EKS) runs Kubernetes without installing and operating your own control plane. EKS manages the control plane and integrates with AWS services.
    
    ## Table of Contents
    
    - [Core Concepts](#core-concepts)
    - [Common Patterns](#common-patterns)
    - [CLI Reference](#cli-reference)
    - [Best Practices](#best-practices)
    - [Troubleshooting](#troubleshooting)
    - [References](#references)
    
    ## Core Concepts
    
    ### Control Plane
    
    Managed by AWS. Runs Kubernetes API server, etcd, and controllers across multiple AZs.
    
    ### Node Groups
    
    | Type | Description |
    |------|-------------|
    | **Managed** | AWS manages provisioning, updates |
    | **Self-managed** | You manage EC2 instances |
    | **Fargate** | Serverless, per-pod compute |
    
    ### IRSA (IAM Roles for Service Accounts)
    
    Associates Kubernetes service accounts with IAM roles for fine-grained AWS permissions.
    
    ### Add-ons
    
    Operational software: CoreDNS, kube-proxy, VPC CNI, EBS CSI driver.
    
    ## Common Patterns
    
    ### Create a Cluster
    
    **AWS CLI:**
    
    ```bash
    # Create cluster role
    aws iam create-role \
      --role-name eks-cluster-role \
      --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [{
          "Effect": "Allow",
          "Principal": {"Service": "eks.amazonaws.com"},
          "Action": "sts:AssumeRole"
        }]
      }'
    
    aws iam attach-role-policy \
      --role-name eks-cluster-role \
      --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
    
    # Create cluster
    aws eks create-cluster \
      --name my-cluster \
      --role-arn arn:aws:iam::123456789012:role/eks-cluster-role \
      --resources-vpc-config subnetIds=subnet-12345678,subnet-87654321,securityGroupIds=sg-12345678
    
    # Wait for cluster
    aws eks wait cluster-active --name my-cluster
    
    # Update kubeconfig
    aws eks update-kubeconfig --name my-cluster --region us-east-1
    ```
    
    **eksctl (Recommended):**
    
    ```bash
    # Create cluster with managed node group
    eksctl create cluster \
      --name my-cluster \
      --region us-east-1 \
      --version 1.29 \
      --nodegroup-name standard-workers \
      --node-type t3.medium \
      --nodes 3 \
      --nodes-min 1 \
      --nodes-max 5 \
      --managed
    ```
    
    ### Add Managed Node Group
    
    ```bash
    # Create node role
    aws iam create-role \
      --role-name eks-node-role \
      --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [{
          "Effect": "Allow",
          "Principal": {"Service": "ec2.amazonaws.com"},
          "Action": "sts:AssumeRole"
        }]
      }'
    
    aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
    aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
    aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
    
    # Create node group
    aws eks create-nodegroup \
      --cluster-name my-cluster \
      --nodegroup-name standard-workers \
      --node-role arn:aws:iam::123456789012:role/eks-node-role \
      --subnets subnet-12345678 subnet-87654321 \
      --instance-types t3.medium \
      --scaling-config minSize=1,maxSize=5,desiredSize=3 \
      --ami-type AL2_x86_64
    ```
    
    ### Configure IRSA
    
    ```bash
    # Enable OIDC provider
    eksctl utils associate-iam-oidc-provider \
      --cluster my-cluster \
      --approve
    
    # Create IAM role for service account
    eksctl create iamserviceaccount \
      --cluster my-cluster \
      --namespace default \
      --name my-app-sa \
      --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
      --approve
    ```
    
    **Manual IRSA setup:**
    
    ```bash
    # Get OIDC issuer
    OIDC_ISSUER=$(aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text)
    OIDC_ID=${OIDC_ISSUER##*/}
    
    # Create trust policy
    cat > trust-policy.json << EOF
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Principal": {
          "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}"
        },
        "Action": "sts:AssumeRoleWithWebIdentity",
        "Condition": {
          "StringEquals": {
            "oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}:sub": "system:serviceaccount:default:my-app-sa",
            "oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}:aud": "sts.amazonaws.com"
          }
        }
      }]
    }
    EOF
    
    aws iam create-role --role-name my-app-role --assume-role-policy-document file://trust-policy.json
    ```
    
    ### Kubernetes Service Account
    
    ```yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: my-app-sa
      namespace: default
      annotations:
        eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-role
    ```
    
    ### Install Add-ons
    
    ```bash
    # CoreDNS
    aws eks create-addon \
      --cluster-name my-cluster \
      --addon-name coredns \
      --addon-version v1.11.1-eksbuild.4
    
    # VPC CNI
    aws eks create-addon \
      --cluster-name my-cluster \
      --addon-name vpc-cni \
      --addon-version v1.16.0-eksbuild.1
    
    # kube-proxy
    aws eks create-addon \
      --cluster-name my-cluster \
      --addon-name kube-proxy \
      --addon-version v1.29.0-eksbuild.1
    
    # EBS CSI Driver
    aws eks create-addon \
      --cluster-name my-cluster \
      --addon-name aws-ebs-csi-driver \
      --addon-version v1.27.0-eksbuild.1 \
      --service-account-role-arn arn:aws:iam::123456789012:role/ebs-csi-role
    ```
    
    ### Deploy Application
    
    ```yaml
    # deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: my-app
      template:
        metadata:
          labels:
            app: my-app
        spec:
          serviceAccountName: my-app-sa
          containers:
          - name: app
            image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
            ports:
            - containerPort: 8080
            resources:
              requests:
                cpu: 100m
                memory: 128Mi
              limits:
                cpu: 500m
                memory: 512Mi
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: my-app
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: nlb
    spec:
      type: LoadBalancer
      ports:
      - port: 80
        targetPort: 8080
      selector:
        app: my-app
    ```
    
    ## CLI Reference
    
    ### Cluster Management
    
    | Command | Description |
    |---------|-------------|
    | `aws eks create-cluster` | Create cluster |
    | `aws eks describe-cluster` | Get cluster details |
    | `aws eks update-cluster-config` | Update cluster settings |
    | `aws eks delete-cluster` | Delete cluster |
    | `aws eks update-kubeconfig` | Configure kubectl |
    
    ### Node Groups
    
    | Command | Description |
    |---------|-------------|
    | `aws eks create-nodegroup` | Create node group |
    | `aws eks describe-nodegroup` | Get node group details |
    | `aws eks update-nodegroup-config` | Update node group |
    | `aws eks delete-nodegroup` | Delete node group |
    
    ### Add-ons
    
    | Command | Description |
    |---------|-------------|
    | `aws eks create-addon` | Install add-on |
    | `aws eks describe-addon` | Get add-on details |
    | `aws eks update-addon` | Update add-on |
    | `aws eks delete-addon` | Remove add-on |
    
    ## Best Practices
    
    ### Security
    
    - **Use IRSA** for pod-level AWS permissions
    - **Enable cluster encryption** with KMS
    - **Use private endpoint** for API server
    - **Enable audit logging** to CloudWatch
    - **Use security groups for pods**
    - **Implement network policies**
    
    ```bash
    # Enable secrets encryption
    aws eks create-cluster \
      --name my-cluster \
      --encryption-config '[{
        "provider": {"keyArn": "arn:aws:kms:us-east-1:123456789012:key/..."},
        "resources": ["secrets"]
      }]' \
      ...
    ```
    
    ### High Availability
    
    - **Deploy across multiple AZs**
    - **Use managed node groups**
    - **Set pod disruption budgets**
    - **Configure horizontal pod autoscaling**
    
    ### Cost Optimization
    
    - **Use Spot instances** for non-critical workloads
    - **Right-size nodes and pods**
    - **Use Fargate** for variable workloads
    - **Implement cluster autoscaler**
    - **Use Karpenter** for efficient scaling
    
    ## Troubleshooting
    
    ### Cannot Connect to Cluster
    
    ```bash
    # Verify kubeconfig
    aws eks update-kubeconfig --name my-cluster --region us-east-1
    
    # Check IAM identity
    aws sts get-caller-identity
    
    # Verify cluster status
    aws eks describe-cluster --name my-cluster --query 'cluster.status'
    ```
    
    ### Nodes Not Joining
    
    **Check:**
    - Node IAM role has required policies
    - Security groups allow node-to-control-plane communication
    - Nodes have network access to API server
    
    ```bash
    # Check node status
    kubectl get nodes
    
    # Check aws-auth ConfigMap
    kubectl describe configmap aws-auth -n kube-system
    
    # Check node logs (SSH to node)
    journalctl -u kubelet
    ```
    
    ### Pod Cannot Access AWS Services
    
    ```bash
    # Verify IRSA setup
    kubectl describe sa my-app-sa
    
    # Check pod environment
    kubectl exec my-pod -- env | grep AWS
    
    # Test credentials
    kubectl exec my-pod -- aws sts get-caller-identity
    ```
    
    ### DNS Issues
    
    ```bash
    # Check CoreDNS pods
    kubectl get pods -n kube-system -l k8s-app=kube-dns
    
    # Test DNS resolution
    kubectl run test --image=busybox:1.28 --rm -it -- nslookup kubernetes
    
    # Check CoreDNS logs
    kubectl logs -n kube-system -l k8s-app=kube-dns
    ```
    
    ## References
    
    - [EKS User Guide](https://docs.aws.amazon.com/eks/latest/userguide/)
    - [EKS API Reference](https://docs.aws.amazon.com/eks/latest/APIReference/)
    - [EKS CLI Reference](https://docs.aws.amazon.com/cli/latest/reference/eks/)
    - [eksctl](https://eksctl.io/)
    - [EKS Best Practices Guide](https://aws.github.io/aws-eks-best-practices/)
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related