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:
- Kubernetes Service Account (SA): You create a Service Account in your Kubernetes cluster. This SA doesn’t inherently have AWS permissions.
- 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.
- IAM OIDC Provider: Your EKS cluster is configured with an IAM OIDC provider. This provider allows AWS IAM to trust tokens issued by Kubernetes.
- Pod Startup: When a pod starts and requests credentials (e.g., via the AWS SDK), it obtains a short-lived Kubernetes Service Account token.
- 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.
- 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, andecr:BatchGetImagepermissions for the specific ECR repository. - ECR Repository URI: The full URI of the ECR image you’re trying to pull.
Example Configuration Steps:
-
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
Resourceto a specific ECR repository for better security. -
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.
-
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
ServiceAccountmanifest:
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 - 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
-
Apply the Service Account:
kubectl apply -f serviceaccount.yaml -
Update your Deployment:
- Reference the
ecr-pull-sain your pod’sserviceAccountNamefield, as shown in the initial example.
- Reference the
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.