EKS pods can authenticate to pull images from ECR by leveraging IAM roles for service accounts (IRSA).

Here’s how it works in practice:

Let’s say you have a deployment that needs to pull an image from ECR.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest # Your ECR image
        ports:
        - containerPort: 80
      serviceAccountName: ecr-pull-sa # This is the key!

The serviceAccountName: ecr-pull-sa in the pod spec tells Kubernetes to associate this pod with a specific Service Account. This Service Account is then linked to an IAM Role, which grants the necessary permissions to pull images from ECR.

The Problem This Solves:

Traditionally, you’d inject AWS credentials into your pods (e.g., via environment variables or mounted files). This is a security risk. IRSA eliminates the need for explicit AWS credentials within the pod, making your EKS cluster more secure. The pod "assumes" an IAM role dynamically.

How it Works Internally:

  1. Kubernetes Service Account (SA): You create a Service Account in your Kubernetes cluster. This SA doesn’t inherently have AWS permissions.
  2. IAM Role for Service Account (IRSA) Annotation: You annotate the Kubernetes Service Account with a specific IAM role ARN. This annotation is the crucial link. It tells the AWS IAM OIDC provider for your EKS cluster how to map this SA to an IAM Role.
  3. IAM OIDC Provider: Your EKS cluster is configured with an IAM OIDC provider. This provider allows AWS IAM to trust tokens issued by Kubernetes.
  4. Pod Startup: When a pod starts and requests credentials (e.g., via the AWS SDK), it obtains a short-lived Kubernetes Service Account token.
  5. Token Exchange: The AWS IAM metadata service (running on the EKS node) intercepts this request. It exchanges the Kubernetes SA token for temporary AWS credentials by communicating with the IAM OIDC provider.
  6. ECR Access: The pod then uses these temporary AWS credentials to authenticate with ECR and pull the image.

The Levers You Control:

  • Kubernetes Service Account: The name of the SA you assign to your pods.
  • IAM Role ARN: The ARN of the IAM role that grants ECR pull permissions. This role must have a trust policy that allows your EKS OIDC provider to assume it.
  • IAM Policy: The IAM policy attached to the role. This policy needs ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:GetDownloadUrlForLayer, and ecr:BatchGetImage permissions for the specific ECR repository.
  • ECR Repository URI: The full URI of the ECR image you’re trying to pull.

Example Configuration Steps:

  1. Create an IAM Policy for ECR Pull:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "ecr:GetAuthorizationToken",
                    "ecr:BatchCheckLayerAvailability",
                    "ecr:GetDownloadUrlForLayer",
                    "ecr:BatchGetImage"
                ],
                "Resource": "*"
            }
        ]
    }
    

    Note: You can scope the Resource to a specific ECR repository for better security.

  2. Create an IAM Role for the Service Account:

    • Go to the IAM console, create a new role.
    • Select "AWS account" as the trusted entity type.
    • Choose "Web identity" as the type of trusted entity.
    • Select your EKS cluster’s OIDC provider.
    • For "Audience," enter sts.amazonaws.com.
    • Attach the IAM policy created in step 1.
    • Give the role a name, e.g., EksECRPullRole.
  3. Create a Kubernetes Service Account and Annotate It:

    • Get your EKS cluster’s OIDC provider ARN. You can find this in the EKS console under your cluster’s "Configuration" tab, in the "Details" section. It looks like oidc.eks.<region>.amazonaws.com/id/<OIDC_ID>.
    • Get the ARN of the IAM role you just created.
    • Create a ServiceAccount manifest:
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ecr-pull-sa
      namespace: default # Or your application's namespace
      annotations:
        # Replace with your cluster's OIDC provider and the IAM role ARN
        eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/EksECRPullRole
    
  4. Apply the Service Account:

    kubectl apply -f serviceaccount.yaml
    
  5. Update your Deployment:

    • Reference the ecr-pull-sa in your pod’s serviceAccountName field, as shown in the initial example.

The ECR image URI must be correct and the specified ECR repository must exist and contain the image. If the image URI is malformed or the image doesn’t exist, the pod will fail to start.

The next concept you’ll likely encounter is how to manage secrets for other AWS services that your pods might need to interact with, beyond just ECR image pulling.

Want structured learning?

Take the full Eks course →