I am writing about how to configure AWS ECR to be used as my private docker container registry.
This can be done with a docker login
command to authenticate to an ECR registry that provides an authorization token valid for 12 hours.
Because AWS ECR does not allow a docker login password to be valid for more than 12 hours. And thus even if I create a secret for kubernetes to use, it will be invalid after 12 hours
I want to use a CI-CD system like CircleCI or Jenkins which updates my pods automatically. So i don’t want to create this secret manually each time.
So, I need to keep the secret fresh and make sure I get the valid password from AWS. The solution for this is simple – just setting up a scheduled job or cron job to do this work for me.
Step 1. Create a Kubernetes cronjob
To create a Kubernetes cronjob , which will make sure my AWS ECR docker secret stays updated and valid to pull images whenever I update the pod images.
# aws-registry-credential-cron.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: aws-registry-credential-cron
spec:
schedule: "* */8 * * *"
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 2
jobTemplate:
spec:
backoffLimit: 4
template:
spec:
serviceAccountName: default
terminationGracePeriodSeconds: 0
restartPolicy: Never
containers:
- name: kubectl
imagePullPolicy: IfNotPresent
image: xynova/aws-kubectl:latest
envFrom:
- secretRef:
name: aws-secret
command:
- "/bin/sh"
- "-c"
- |
# create docker login information by aws ecr get-login command
DOCKER_REGISTRY_SERVER=https://${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com
DOCKER_USER=AWS
DOCKER_PASSWORD=$(aws ecr get-login --region ${AWS_REGION} --registry-ids ${AWS_ACCOUNT} | cut -d' ' -f6)
# delete old secret
kubectl delete secret aws-registry || true
# create new one by run docker login information
kubectl create secret docker-registry aws-registry \
--docker-server=$DOCKER_REGISTRY_SERVER \
--docker-username=$DOCKER_USER \
--docker-password=$DOCKER_PASSWORD \
--docker-email=no@email.local
# set default pullSecret of service account default is aws-registry
kubectl patch serviceaccount default -p '{"imagePullSecrets":[{"name":"aws-registry"}]}'
- schedule: “* */8 * * *” : The refresh cronjob script will be run every 8 hours.
✗ kubectl create -f ./aws-registry-credential-cron.yaml
Step 2. Create AWS secret
Create a Kubernetes secret aws-secret
to save your AWS credential information by a command.
✗ kubectl create secret generic aws-secret \
--from-literal=AWS_ACCOUNT=YOUR_AWS_ACCOUNT_ID \
--from-literal=AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID \
--from-literal=AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY \
--from-literal=AWS_DEFAULT_REGION=ap-southeast-1 \
--from-literal=AWS_REGION=ap-southeast-1
Step 3. Add permission to service account default
I am using service account default
(serviceAccountName: default
) to run the cronjob, create and delete the secret. So, I will give default
service account the admin access and my cronjob pod can then execute all the actions.
✗ kubectl create clusterrolebinding serviceaccounts-default-cluster-admin --clusterrole=cluster-admin --group=system:serviceaccounts
Step 4. Try to run cronjob manually
You can execute the cronjob by using bellow command.
✗ kubectl create job --from=cronjob/aws-registry-credential-cron aws-registry-credential-cron-manual-001
job.batch/aws-registry-credential-cron-manual-001 created
Verify execution result by checking the log of above job aws-registry-credential-cron-manual-001
✗ kubectl logs job/aws-registry-credential-cron-manual-001
secret "aws-registry" deleted
secret "aws-registry" created
serviceaccount "default" patched
Hope everything works for you too. Happy K8s!