This repository has been archived by the owner on Dec 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f4c6753
Showing
12 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
cronjob.yaml | ||
LICENSE | ||
NOTICE | ||
README.md | ||
serviceaccount.yaml | ||
examples | ||
iam-permission.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.DS_Store | ||
.vscode/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Contributing Guidelines | ||
|
||
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional | ||
documentation, we greatly value feedback and contributions from our community. | ||
|
||
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary | ||
information to effectively respond to your bug report or contribution. | ||
|
||
## Reporting Bugs/Feature Requests | ||
|
||
We welcome you to use the GitHub issue tracker to report bugs or suggest features. | ||
|
||
When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already | ||
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: | ||
|
||
* A reproducible test case or series of steps | ||
* The version of our code being used | ||
* Any modifications you've made relevant to the bug | ||
* Anything unusual about your environment or deployment | ||
|
||
## Contributing via Pull Requests | ||
|
||
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: | ||
|
||
1. You are working against the latest source on the *main* branch. | ||
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. | ||
3. You open an issue to discuss any significant work - we would hate for your time to be wasted. | ||
|
||
To send us a pull request, please: | ||
|
||
1. Fork the repository. | ||
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. | ||
3. Ensure local tests pass. | ||
4. Commit to your fork using clear commit messages. | ||
5. Send us a pull request, answering any default questions in the pull request interface. | ||
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. | ||
|
||
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and | ||
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). | ||
|
||
## Finding contributions to work on | ||
|
||
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. | ||
|
||
## Code of Conduct | ||
|
||
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). | ||
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact | ||
[email protected] with any additional questions or comments. | ||
|
||
## Security issue notifications | ||
|
||
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. | ||
|
||
## Licensing | ||
|
||
See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: MIT-0 | ||
|
||
ARG AWS_CLI_VERSION=2.1.12 | ||
|
||
FROM amazon/aws-cli:${AWS_CLI_VERSION} | ||
|
||
RUN yum update -y \ | ||
&& yum install -y openssl \ | ||
&& yum clean all | ||
|
||
# See https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html for other kubectl versions or AWS China regions | ||
ARG KUBECTL_DOWNLOAD_URL=https://amazon-eks.s3.us-west-2.amazonaws.com/1.18.9/2020-11-02/bin/linux/amd64/kubectl | ||
ARG KUBECTL_SHA256_URL=https://amazon-eks.s3.us-west-2.amazonaws.com/1.18.9/2020-11-02/bin/linux/amd64/kubectl.sha256 | ||
|
||
RUN curl -o kubectl ${KUBECTL_DOWNLOAD_URL} \ | ||
&& curl -o kubectl.sha256 ${KUBECTL_SHA256_URL} \ | ||
&& openssl sha1 -sha256 kubectl \ | ||
&& chmod +x ./kubectl \ | ||
&& mv ./kubectl /usr/local/bin/kubectl | ||
|
||
COPY entrypoint.sh / | ||
|
||
ENTRYPOINT ["/entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of this | ||
software and associated documentation files (the "Software"), to deal in the Software | ||
without restriction, including without limitation the rights to use, copy, modify, | ||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
# Amazon ECR "Public" credentials helper script for Kubernetes | ||
|
||
Amazon ECR "Public" credentials helper script for Kubernetes (`ecr-public-creds-helper-for-k8s` for short) allows your Kubernetes clusters pull public container images from [Amazon ECR Public](https://aws.amazon.com/blogs/aws/amazon-ecr-public-a-new-public-container-registry/) registries **as authenticated users** to get the limit upgraded to `10` pulls per second which is `1` for unauthenticated users as described [here](https://docs.aws.amazon.com/AmazonECR/latest/public/public-service-quotas.html), and unlimited data bandwidth as described [here](https://aws.amazon.com/ecr/pricing/). | ||
|
||
`ecr-public-creds-helper-for-k8s` is one of the workarounds to access ECR Public as authenticated users from your Kubernetes clusters until 1) Amazon ECR Public get supported by the upstream Kubernetes project and/or 2) Official Amazon ECR Public support for AWS Fargate by Amazon EKS. | ||
|
||
`ecr-public-creds-helper-for-k8s` runs in your cluster as a Kubernetes CronJob every 8 hours by default. It authenticates against ECR Public and stores the auth token as Kubernetes Secrets within namespaces you specified. | ||
|
||
Each pod (even on AWS Fargate) will reference that Kubernetes Secret in its namespace by specifying the `imagePullSecrets` field in the PodSpec. You may also want to patch the `default` service account in each namespace to avoid writing `imagePullSecrets` in all PodSpecs, see the comments at the [entrypoint.sh#L21](entrypoint.sh#L21) for further details. | ||
|
||
See the "[Create a Secret by providing credentials on the command line](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-secret-by-providing-credentials-on-the-command-line)" section and the "[Create a Pod that uses your Secret](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-pod-that-uses-your-secret)" in the Kubernetes documentation to understand how it works. | ||
|
||
## Motivations | ||
|
||
This project aims to fill the gap between Amazon EKS (Kubernetes, both EC2 and Fargate) and Amazon ECR Public. There are two pain points for users at the time of release of this repository as follows: | ||
|
||
1. Kubernetes supports Amazon ECR (the private one) to pull private ECR images with automatic auth via IAM roles, but still the latest version (1.20, at this moment) of Kubernetes doesn't support ECR Public yet. Thus there is no straightforward way to pull ECR Public container images from EKS/Kubernetes clusters as authenticated users. This means users are forced to access ECR Public as unauthenticated users from their Kubernetes clusters, resulting that pulls from ECR Public could be throttled easily and frequently. | ||
1. [A PR in the "awslabs/amazon-ecr-credential-helper" GitHub repository](https://github.com/awslabs/amazon-ecr-credential-helper/pull/253) could solve the pain point #1 someday, but the "awslabs/amazon-ecr-credential-helper" itself cannot be used for EKS/Fargate workloads by its design. EKS/Fargate users, not only EKS/EC2 users, obviously need a way to use ECR Public as authenticated users, so this is also the pain point that this project addresses. | ||
|
||
## Installation | ||
|
||
### Step 0 - Clone repo | ||
|
||
```shell | ||
$ git clone https://github.com/aws-containers/amazon-ecr-public-creds-helper-for-k8s.git | ||
$ cd amazon-ecr-public-creds-helper-for-k8s | ||
``` | ||
|
||
### Step 1 - Build and Push creds-helper container image | ||
|
||
```shell | ||
$ export CREDS_HELPER_CONTAINER_IMAGE=<your-creds-helper-container-image-name-here> | ||
|
||
$ docker build -t ${CREDS_HELPER_CONTAINER_IMAGE} . | ||
|
||
$ docker push ${CREDS_HELPER_CONTAINER_IMAGE} | ||
``` | ||
|
||
### Step 2 - Create namespace | ||
|
||
Create a namespace for `ecr-public-creds-helper-for-k8s` to run as a CronJob in your Kubernetes cluster. | ||
|
||
```shell | ||
$ kubectl apply -f namespace.yaml | ||
namespace/ecr-public-creds-helper created | ||
``` | ||
|
||
### Step 3 - Create service account | ||
|
||
Create a service account to allow `ecr-public-creds-helper-for-k8s` to edit Kubernetes secrets. | ||
|
||
```shell | ||
$ kubectl apply -f serviceaccount.yaml | ||
serviceaccount/sa-secrets-editor created | ||
clusterrole.rbac.authorization.k8s.io/secrets-editor created | ||
clusterrolebinding.rbac.authorization.k8s.io/edit-secrets created | ||
``` | ||
|
||
### Step 4 - Create IAM role | ||
|
||
Create an AWS IAM role to allow `ecr-public-creds-helper-for-k8s` to authenticate against Amazon ECR Public. We use the mechanism called [IAM Roles for Service Accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) to map it to the service account which you created in the previous step. | ||
|
||
If you have not enabled IRSA in your Kubernetes cluster yet, please follow the [IRSA documentation](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) and/or the [blog post](https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/) for enabling IRSA for your Kubernetes cluster. | ||
|
||
#### Steps with eksctl | ||
|
||
We're going to use `eksctl` here to show the steps to create and map the IAM role in an EKS cluster, but you can also use the AWS CLI, the AWS management console, CloudFormation, Terraform or whatever you want to use. | ||
|
||
```shell | ||
$ export POLICY_ARN=$(aws iam create-policy --policy-name AmazonECRPublicAuthOnlyPolicy --policy-document file://iam-permission.json --query Policy.Arn --output text) | ||
## Check you've created the policy successfully | ||
$ echo ${POLICY_ARN} | ||
arn:aws:iam::YOUR_AWS_ACCOUNT_ID:policy/AmazonECRPublicAuthOnlyPolicy | ||
|
||
$ export EKS_CLUSTER_NAME=<your-eks-cluster-name-here> | ||
|
||
$ eksctl create iamserviceaccount --cluster=${EKS_CLUSTER_NAME} \ | ||
--name=sa-secrets-editor \ | ||
--namespace=ecr-public-creds-helper \ | ||
--attach-policy-arn=${POLICY_ARN} \ | ||
--override-existing-serviceaccounts \ | ||
--approve | ||
``` | ||
|
||
### Step 5 - Configure and Apply | ||
|
||
#### Configure cronjob.yaml | ||
|
||
Edit the [cronjob.yaml](cronjob.yaml) before running `ecr-public-creds-helper-for-k8s` in your Kubernetes cluster. | ||
|
||
```shell | ||
$ vim cronjob.yaml | ||
``` | ||
|
||
There are two **required** fields to change. | ||
|
||
##### 1. `image` field | ||
|
||
Replace `${CREDS_HELPER_CONTAINER_IMAGE}` in [line.22 in the cronjob.yaml](cronjob.yaml#L22) with your creds helper container image name which you built and pushed in the Step 1. | ||
|
||
##### 2. `env.value` field | ||
|
||
Replace the value (`default foo bar`) of `TARGET_NAMESPACES` environment variable in [line.26 in the cronjob.yaml](cronjob.yaml#L26) with a space-delimited list which includes one or multiple Kuberentes namespaces where your pods need the auth token for ECR Public. | ||
|
||
Let's say you want to pull ECR Public container images in three namespaces (`default`, `prometheus`, `my-app`) with auth token, then the `env.value` field will look like: `value: "default prometheus my-app"`. | ||
|
||
`ecr-public-creds-helper-for-k8s` will store the auth token as Kubernetes Secrets in these namespaces. | ||
|
||
#### Apply cronjob.yaml | ||
|
||
Run `ecr-public-creds-helper-for-k8s` in your Kubernetes cluster. | ||
|
||
```shell | ||
$ kubectl apply -f cronjob.yaml | ||
cronjob.batch/ecr-public-creds-helper created | ||
``` | ||
|
||
### Step 6 - (Optional but recommended) Run Job manually | ||
|
||
Create an initial auth token manually to let your pods use it without waiting the initial cronjob to be started. Note that `ecs-public-creds-helper-for-k8s` [refreshes the auth token in every 8 hours by default](cronjob.yaml#L8). | ||
|
||
```shell | ||
$ kubectl create job initial-creds-job \ | ||
-n ecr-public-creds-helper \ | ||
--from=cronjob/ecr-public-creds-helper | ||
job.batch/initial-creds-job created | ||
|
||
## Check the pod log to make sure it works as expected | ||
$ export POD_NAME=$(kubectl get pods --selector=job-name=initial-creds-job -n ecr-public-creds-helper -o jsonpath='{.items[0].metadata.name}') | ||
|
||
$ echo ${POD_NAME} | ||
initial-creds-job-r4fbp # you'll see something like this | ||
|
||
$ kubectl logs ${POD_NAME} -n ecr-public-creds-helper | ||
### You'll see the same number of lines as the namespaces you specified in the "TARGET_NAMESPACES" in the cronjob.yaml | ||
secret/ecr-public-token created | ||
secret/ecr-public-token created | ||
secret/ecr-public-token created | ||
|
||
$ kubectl delete job initial-creds-job -n ecr-public-creds-helper | ||
job.batch "initial-creds-job" deleted | ||
``` | ||
|
||
## Use auth tokens in Pods | ||
|
||
Now your pod can use the auth token (Kubernetes secret) created by `ecr-public-creds-helper-for-k8s` to pull public container images as an authenticated user from Amazon ECR Public registries. | ||
|
||
You can reference the auth token from your pods like: | ||
|
||
```yaml | ||
apiVersion: v1 | ||
kind: Pod | ||
# ~ snip ~ | ||
spec: | ||
# ~ snip ~ | ||
imagePullSecrets: | ||
- name: ecr-public-token | ||
# ~ snip ~ | ||
``` | ||
|
||
See also [examples/pod.yaml](examples/pod.yaml) for full example. | ||
|
||
If you don't want to add `imagePullSecrets` in each PodSpec, you may want to see the comments in the [entrypoint.sh](entrypoint.sh#L18). | ||
|
||
## Security | ||
|
||
See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. | ||
|
||
## License | ||
|
||
Licensed under the MIT-0 License. See the [LICENSE](LICENSE) file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
--- | ||
apiVersion: batch/v1beta1 | ||
kind: CronJob | ||
metadata: | ||
name: ecr-public-creds-helper | ||
namespace: ecr-public-creds-helper | ||
spec: | ||
schedule: "0 */8 * * *" # Every 8 hours, Note: An auth token for ECR Public is valid for 12 hours | ||
successfulJobsHistoryLimit: 2 | ||
failedJobsHistoryLimit: 2 | ||
jobTemplate: | ||
spec: | ||
backoffLimit: 3 | ||
template: | ||
spec: | ||
serviceAccountName: sa-secrets-editor | ||
terminationGracePeriodSeconds: 0 | ||
restartPolicy: Never | ||
containers: | ||
- name: kubectl | ||
imagePullPolicy: Always | ||
image: ${CREDS_HELPER_CONTAINER_IMAGE} ### <- 1. EDIT HERE !!! | ||
env: | ||
# Specify "existing" namespaces as a space-delimited list where you want to create Kubernetes secrets with auth token for ECR Public | ||
- name: TARGET_NAMESPACES | ||
value: "default foo bar" ### <- 2. EDIT HERE !!! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: MIT-0 | ||
|
||
#!/usr/bin/env bash | ||
set -euo pipefail | ||
|
||
REGISTRY=https://public.ecr.aws | ||
AUTH_USER=AWS | ||
AUTH_TOKEN=$(aws ecr-public get-authorization-token --region us-east-1 --output=text --query 'authorizationData.authorizationToken' | base64 -d | cut -d: -f2) | ||
|
||
for n in $(echo ${TARGET_NAMESPACES}) | ||
do | ||
kubectl delete secret ecr-public-token \ | ||
-n "${n}" \ | ||
--ignore-not-found | ||
kubectl create secret docker-registry ecr-public-token \ | ||
-n "${n}" \ | ||
--docker-server=${REGISTRY} \ | ||
--docker-username=${AUTH_USER} \ | ||
--docker-password=${AUTH_TOKEN} | ||
# Uncomment the following lines if you want to make all pods use this auth token without specifying it in each PodSpec. | ||
#kubectl patch serviceaccount default \ | ||
# -n "${n}" | ||
# -p '{"imagePullSecrets":[{"name":"ecr-public-token"}]}' | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: ecr-public-authenticated-access-example | ||
namespace: default | ||
spec: | ||
containers: | ||
- name: my-container | ||
image: public.ecr.aws/r6p5x8p7/everlasting-hey-yo:latest | ||
# Use the Kubernetes secret created by ecr-public-creds-helper-for-k8s | ||
imagePullSecrets: | ||
- name: ecr-public-token |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Effect": "Allow", | ||
"Action": [ | ||
"ecr-public:GetAuthorizationToken", | ||
"sts:GetServiceBearerToken" | ||
], | ||
"Resource": "*" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
apiVersion: v1 | ||
kind: Namespace | ||
metadata: | ||
name: ecr-public-creds-helper |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
--- | ||
apiVersion: v1 | ||
kind: ServiceAccount | ||
metadata: | ||
name: sa-secrets-editor | ||
namespace: ecr-public-creds-helper | ||
--- | ||
# As you may realized, this is not the minimum permissions | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRole | ||
metadata: | ||
name: secrets-editor | ||
rules: | ||
- apiGroups: [""] | ||
resources: ["secrets"] | ||
verbs: ["create", "delete"] | ||
--- | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRoleBinding | ||
metadata: | ||
name: edit-secrets | ||
subjects: | ||
- kind: ServiceAccount | ||
name: sa-secrets-editor | ||
namespace: ecr-public-creds-helper | ||
roleRef: | ||
kind: ClusterRole | ||
name: secrets-editor | ||
apiGroup: rbac.authorization.k8s.io |