Deploying Private Docker Images from ECR to Kubernetes

Colin J. Ihrig

Kubernetes allows Docker images to be pulled from arbitrary registries and spun up as pods in a cluster. Both public and private Docker registries are supported. For example, the following Deployment (copied from the Kubernetes documentation) pulls the nginx:1.14.2 image from Docker Hub. Note that a similar configuration is possible in a Pod definition.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

In order to pull the nginx:1.14.2 image from the public Amazon Elastic Container Registry (ECR), the image field can be updated to public.ecr.aws/nginx/nginx:1.14.2, as shown in the updated example below:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: public.ecr.aws/nginx/nginx:1.14.2
        ports:
        - containerPort: 80

Similarly, if you are using a private ECR image, the image field can be updated to aws_account_id.dkr.ecr.region.amazonaws.com/repository:tag, where:

  • aws_account_id is your AWS account ID. For example, 123456789012.
  • region is the name of the AWS region. For example, us-east-1.
  • repository is the image's repository name in the registry. For example, nginx.
  • tag is the image's tag. For example, latest or 1.14.2.

Handling authentication

Kubernetes can be configured to authenticate with your registry using a Docker config Secret.

First, obtain the necessary password using the aws ecr get-login-password command. If you are using ECR's public registry, use the aws ecr-public get-login-password command instead. Note that these passwords are only valid for 12 hours.

aws ecr get-login-password --region us-east-1

Next, create the Docker config Secret as shown below. In this example, the username will always be AWS, and the password is the value obtained in the previous step.

kubectl create secret docker-registry secret-name \
  --docker-server=123456789012.dkr.ecr.us-east-1.amazonaws.com \
  --docker-email=your@email.com \
  --docker-username=AWS \
  --docker-password=your_password

Once the secret has been created, update the Deployment to use it when pulling images via the imagePullSecrets section as shown below:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
      imagePullSecrets:
        - name: secret-name

Once these changes are applied, you should be able to pull images from ECR.