digitaloceanのkubernetesにECRのprivate registryを追加する
add AWS ECR private registry
コンテナレジストリをDigital Ocean RegistryからAWS ECRへ変更しました。
背景
circle CIからの自動デプロイのテストで、digital oceanの500MB上限に達してしまってcircle ciからのPUSHが失敗してしまうので、ECRに移行することにしました。
手順
の通りにやっても401エラーになってしまったので
でうまくいきました。
※2024/1/27 追記
namespaceがdefault以外からの参照が不可能となっていたので、Namespace毎に作成するように変更した。
下記のエラーによりimageのpullが出来なくなっていた。(エラーログはpodのdescribe)
Warning FailedToRetrieveImagePullSecret 5m45s (x2458 over 2d3h) kubelet Unable to retrieve some image pull secrets (regcred); attempting to pull the image may not succeed.
ECR準備
- ecr操作用のIAMユーザー作成
- ecr操作用のIAMユーザーへ割り当てたポリシーは
- AmazonEC2ContainerRegistryFullAccess
- AmazonEC2ContainerRegistryPowerUserでも大丈夫だと思います。(未確認)
- アクセスキーの発行
- ecr操作用のIAMユーザーへ割り当てたポリシーは
- ecrレポジトリの作成
- dititaloceanのkubernetesをシンガポールで作成しているので、ap-southeast-1 にて作成
- privateレポジトリ
- dockerからpushしてイメージを上げておく。
- aws cliのインストール
imageをECRへPUSHさせるためローカルのdockerからログインしておく
aws ecr get-login-password | docker login --username AWS --password-stdin 1234567890.dkr.ecr.ap-southeast-1.amazonaws.com
12時間でセッションは切れます。
イメージのPUSH
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s$ docker tag myimages/doks-wp:0.0.11 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com:0.0.11
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s$ docker push 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com:0.0.11
Step 1: Create a secret, a configmap, and a service account for the CronJob
ServiceAccountの作成
cat <<END>ecr-registry-helper.yaml
apiVersion: v1
kind: Secret
metadata:
name: ecr-registry-helper-secrets
namespace: doks-wp # プロジェクトごとに指定していない場合はdefault
stringData:
AWS_SECRET_ACCESS_KEY: "" # Replace with your AWS secret access key
AWS_ACCESS_KEY_ID: "" # Replace with your AWS access key ID
AWS_ACCOUNT: "" # Replace with your AWS account ID
---
apiVersion: v1
kind: ConfigMap
metadata:
name: ecr-registry-helper-cm
namespace: doks-wp # プロジェクトごとに指定していない場合はdefault
data:
AWS_REGION: "eu-southeast-1" # Replace with your ECR region
DOCKER_SECRET_NAME: regcred # Replace with your desired ECR token secret name
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-default
namespace: doks-wp # プロジェクトごとに指定していない場合はdefault
END
Step 2: Create a role and a role binding for the CronJob
目的の名前空間でシークレットを削除および作成する権限を CronJob に付与するロールとロール バインディングを作成
ServiceAccountへのロールの付与です
vi ecr-registry-helper-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: doks-wp # プロジェクトごとに指定していない場合はdefault
name: role-full-access-to-secrets
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["regcred"] # Replace with your desired ECR token secret name
verbs: ["delete"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: default-role-binding
namespace: doks-wp # プロジェクトごとに指定していない場合はdefault
subjects:
- kind: ServiceAccount
name: sa-default # Replace with your service account name if different
namespace: doks-wp # プロジェクトごとに指定していない場合はdefault
apiGroup: ""
roleRef:
kind: Role
name: role-full-access-to-secrets # Replace with your role name if different
apiGroup: ""
Step 3: Create a CronJob that runs a script to update the ECR token secret
10時間おきにECR トークン シークレットを更新する CronJob を作成
vi ecr-registry-helper-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: ecr-registry-helper
namespace: doks-wp # プロジェクトごとに指定していない場合はdefault
spec:
schedule: "0 */10 * * *" # Replace with your desired schedule
successfulJobsHistoryLimit: 2
suspend: false
jobTemplate:
spec:
template:
spec:
serviceAccountName: sa-default # Replace with your service account name if different
containers:
- name: ecr-registry-helper
image: omarxs/awskctl:v1.0
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: ecr-registry-helper-secrets # Replace with your secret name if different
- configMapRef:
name: ecr-registry-helper-cm # Replace with your configmap name if different
command:
- /bin/bash
- -c
- |-
ECR_TOKEN="$(aws ecr get-login-password --region ${AWS_REGION})"
NAMESPACE_NAME=doks-wp # プロジェクトごとに指定していない場合はdefault# Replace with your desired namespace
kubectl delete secret --ignore-not-found $DOCKER_SECRET_NAME -n $NAMESPACE_NAME
kubectl create secret docker-registry $DOCKER_SECRET_NAME --docker-server=https://${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com --docker-username=AWS --docker-password=${ECR_TOKEN} --namespace=$NAMESPACE_NAME
echo "Secret was successfully updated at $(date)"
restartPolicy: Never
apply
kubectl apply -f ecr-registry-helper.yaml
kubectl apply -f ecr-registry-helper-rbac.yaml
kubectl apply -f ecr-registry-helper-cronjob.yaml
手動で一回実行
kubectl create job -n doks-wp --from=cronjob/ecr-registry-helper ecr-registry-helper-manual
kubectl get job -n doks-wp ecr-registry-helper-manual
kubectl logs -n doks-wp -f job/ecr-registry-helper-manual
問題なければ削除
kubectl delete job -n doks-wp ecr-registry-helper-manual
確認
kubectl get serviceaccount
NAME SECRETS AGE
default 0 24d
sa-default 0 49m
kubectl get role
NAME CREATED AT
role-full-access-to-secrets 2024-01-24T23:22:39Z
kubectl get rolebinding
NAME ROLE AGE
default-role-binding Role/role-full-access-to-secrets 48m
kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
ecr-registry-helper 0 /10 False 0 11m 48m
コンテナレジストリをsecretのものを参照できるようにする
deployementごとに設定する場合
kubectl edit deployment/doks-wp-dev-web -n doks-wp
deployment.apps/doks-wp-dev-web edited
kubectl get deployment/doks-wp-dev-web -n doks-wp -o yaml | egrep -i "image\:|imagepullsecret" -A 1
- image: 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/doks-wp:0.0.11
imagePullPolicy: IfNotPresent
--
imagePullSecrets:
- name: regcred
デフォルトで参照するコンテナレジストリを変更する場合
kubectl edit serviceaccount/default
imagePullSecrets のnameを今回追加したもの(regcred)へ書き換えます
確認
digitaloceanからECRへ変更されたことを確認
kubectl get pods -n doks-wp
NAME READY STATUS RESTARTS AGE
doks-wp-dev-web-57685ff669-pt47n 1/1 Running 0 6s
doks-wp-dev-web-57df868b57-7xmf7 1/1 Terminating 0 9h
doks-wp-prod-web-848dd47496-5k4mm 1/1 Running 0 6d9h
doks-wp-prod-web-848dd47496-f6ksl 1/1 Running 0 6d9hkubectl describe pods/doks-wp-dev-web-57685ff669-pt47n -n doks-wp | grep -i image\:
Image: 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/doks-wp:0.0.11
続・確認
cronjobsが問題ないことを確認
kubectl get secret
NAME TYPE DATA AGE
ecr-registry-helper-secrets Opaque 3 12h
ocarina kubernetes.io/dockerconfigjson 1 25d
regcred kubernetes.io/dockerconfigjson 1 117mkubectl get cronjobs
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
ecr-registry-helper 0 /10 False 0 118m 12h
kubectl get jobs
NAME COMPLETIONS DURATION AGE
ecr-registry-helper-28435680 1/1 8s 11h
ecr-registry-helper-28436280 1/1 6s 118m