项目作者: bzon

项目描述 :
A Kubernetes client that creates a Secret for docker clients authenticating to ECR.
高级语言: Go
项目地址: git://github.com/bzon/ecr-k8s-secret-creator.git
创建时间: 2018-08-30T13:09:39Z
项目社区:https://github.com/bzon/ecr-k8s-secret-creator

开源协议:MIT License

下载


Docker PullsGo Report Card
codecov
Build Status

NO MAINTENANCE NOTICE

I don’t maintain this repository anymore. Feel free to fork if needed.

ECR K8S Secret Creator

This application creates a docker config.json (as a Kubernetes secret) that can authenticate docker clients to Amazon ECR. It is using the ECR GetAuthorizationToken API to fetch the token from an Amazon Region.

A docker config.json file looks like this, which may be found in $HOME/.docker/config.json after using docker login.

  1. {
  2. "auths": {
  3. "https://${AWS_PROFILE}.dkr.ecr.us-east-1.amazonaws.com": {
  4. "auth": "....."
  5. }
  6. }
  7. }

This application is like a running cron job that does aws ecr get-login, creates a docker config.json file, then create Kubernetes secret out of it.

WARNING!! If you need to run this in production environments, please build your own Docker image by following the How To Build this Project step.

How does it work?

  • Deploy this application as a Pod in the namespace to create the Secret.

  • This Pod authenticates to AWS to get a new ECR docker login token according to the -region flag.

  • It then creates a config.json according to the values retrieved from AWS.

    1. # config.json template
    2. const cfgTemplate = `{
    3. "auths": {
    4. "{{ .registry }}": {
    5. "auth": "{{ .token }}"
    6. }
    7. }
    8. }`
  • It then creates or updates the Secret according to the -secretName flag in the current namespace.

    1. apiVersion: v1
    2. type: Secret
    3. metadata:
    4. name: xxxx # -secretName
    5. namespace: xxxx # current pod namespace
    6. data:
    7. config.json: xxxxx # base64 encoded
  • You can specify secret type by using -secretType flag. This can be useful, when running kubernetes nodes outside of AWS, as in this scenario kubelet does not have pull access to ECR. Specifying -secretType=kubernetes.io/dockerconfigjson will automate creation of a secret, that can be used in manifests requiring imagePullSecrets

    1. apiVersion: v1
    2. data:
    3. .dockerconfigjson: xxxxx
    4. kind: Secret
    5. type: kubernetes.io/dockerconfigjson
    6. metadata:
    7. name: xxxx
    8. namespace: xxxx
  • It repeats the process according to the specified -interval flag. Refreshing the config.json file content in the Secret over the time specified.

  • You can now use this kubernetes secret and mount it to any pod that has a docker client that authenticates to ECR.

Why did I create this?

We are using Weave Flux to operate our GitOps deployment process. The Weave Flux operator currently does not support authentication to ECR (issue #539). As a workaround, we can use the --docker-config flag and mount a custom config.json in the flux Pod (issue #1065).

The problem is ECR token expires every 12 hours, and we need to find a way to ensure that the config.json authentication token is rotated in an automated and secure way.

How to use with Weave Flux Pod?

Complete the Deployment Guide, noting the secret name and then follow Flux Guide.

How to Deploy

IAM Role Requirement

If you are NOT using kube2iam, skip to the Deployment Step and ensure that your Pod’s EC2 instance can authenticate to your AWS Account via AWS API Keys, or AWS EC2 IAM Role.

Create IAM Policy

  1. {
  2. "Version": "2012-10-17",
  3. "Statement": [
  4. {
  5. "Effect": "Allow",
  6. "Action": "ecr:GetAuthorizationToken",
  7. "Resource": "*"
  8. }
  9. ]
  10. }
  1. aws iam create-policy --policy-name ${GET_ECR_AUTH_IAM_POLICY} --policy-document file://iam-policy.json --description "A policy that can get ECR authorization token"

Create IAM Role

  1. {
  2. "Version": "2012-10-17",
  3. "Statement": [
  4. {
  5. "Effect": "Allow",
  6. "Principal": {
  7. "Service": "ec2.amazonaws.com"
  8. },
  9. "Action": "sts:AssumeRole"
  10. },
  11. {
  12. "Sid": "",
  13. "Effect": "Allow",
  14. "Principal": {
  15. "AWS": "arn:aws:iam::${AWS_PROFILE}:role/${IAM_K8S_NODE_ROLE}"
  16. },
  17. "Action": "sts:AssumeRole"
  18. }
  19. ]
  20. }
  1. aws iam create-role --role-name ${GET_ECR_AUTH_IAM_ROLE} \
  2. --assume-role-policy-document file://ec2-iam-trust.json

Attach the IAM Policy

  1. aws iam attach-role-policy --role-name ${GET_ECR_AUTH_IAM_ROLE} \
  2. --policy-arn arn:aws:iam::${AWS_PROFILE}:policy/${GET_ECR_AUTH_IAM_POLICY}

Deployment

Create the following RBAC and deploy resources yaml files and run kubectl apply -f.

  1. ---
  2. kind: ServiceAccount
  3. apiVersion: v1
  4. metadata:
  5. name: ecr-k8s-secret-creator
  6. namespace: ${SECRET_NAMESPACE}
  7. ---
  8. kind: ClusterRole
  9. apiVersion: rbac.authorization.k8s.io/v1
  10. metadata:
  11. name: ecr-k8s-secret-creator
  12. rules:
  13. - apiGroups: [""]
  14. resources: ["secrets"]
  15. verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  16. ---
  17. kind: ClusterRoleBinding
  18. apiVersion: rbac.authorization.k8s.io/v1
  19. metadata:
  20. name: ecr-k8s-secret-creator
  21. roleRef:
  22. kind: ClusterRole
  23. name: ecr-k8s-secret-creator
  24. apiGroup: rbac.authorization.k8s.io
  25. subjects:
  26. - kind: ServiceAccount
  27. name: ecr-k8s-secret-creator
  28. namespace: ${SECRET_NAMESPACE}
  1. apiVersion: extensions/v1beta1
  2. kind: Deployment
  3. metadata:
  4. name: ecr-k8s-secret-creator
  5. namespace: ${SECRET_NAMESPACE}
  6. spec:
  7. replicas: 1
  8. selector:
  9. matchLabels:
  10. app: ecr-k8s-secret-creator
  11. template:
  12. metadata:
  13. labels:
  14. app: ecr-k8s-secret-creator
  15. # if using kube2iam
  16. # annotations:
  17. # iam.amazonaws.com/role: arn:aws:iam::${AWS_PROFILE}:role/${GET_ECR_AUTH_IAM_ROLE}
  18. spec:
  19. serviceAccount: ecr-k8s-secret-creator
  20. containers:
  21. - image: bzon/ecr-k8s-secret-creator:latest
  22. name: ecr-k8s-secret-creator
  23. args:
  24. - "-secretName=ecr-docker-secret"
  25. - "-region=us-east-1"
  26. # the default profile is the AWS account where the kubernetes cluster is running
  27. # - "-profile=${AWS_ACCOUNT_ID}"
  28. # the default interval for fetching new ecr token is 200 seconds
  29. # - "-interval=300"
  30. resources:
  31. requests:
  32. cpu: 5m
  33. memory: 16Mi
  34. limits:
  35. cpu: 20m
  36. memory: 32Mi

Check the ECR Secret Creator Pod’s logs

  1. {"level":"info","msg":"appVersion: 0.1.0","time":"2018-09-29T16:48:17Z"}
  2. {"level":"info","msg":"Flags: region=us-east-1, interval=1200, profile=, secretName=ecr-docker-secret","time":"2018-09-29T16:48:17Z"}
  3. {"level":"info","msg":"creating kubernetes secret","time":"2018-09-29T16:48:19Z"}
  4. {"level":"info","msg":"updated kubernetes secret: ecr-docker-secret","time":"2018-09-29T16:48:19Z"}

Check the Created Secret

  1. kubectl get secrets ecr-docker-secret -n ${SECRET_NAMESPACE} -o json | jq '.data["config.json"]' | tr -d '"' | base64 --decode
  2. {
  3. "auths": {
  4. "https://${AWS_PROFILE}.dkr.ecr.us-east-1.amazonaws.com": {
  5. "auth": "....."
  6. }
  7. }
  8. }

How to Build this Project

  • Install Go
  • Download the project go get github.com/bzon/ecr-k8s-secret-creator
  • Go to $GOPATH/github.com/bzon/ecr-k8s-secret-creator
  • Change the docker repository in the Makefile to your own docker repository
  • Run make docker-build
  • Run make push