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.com12時間でセッションは切れます。
イメージの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.11Step 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
ENDStep 2: Create a role and a role binding for the CronJob
目的の名前空間でシークレットを削除および作成する権限を CronJob に付与するロールとロール バインディングを作成
ServiceAccountへのロールの付与です
vi ecr-registry-helper-rbac.yamlapiVersion: 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.yamlapiVersion: 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: Neverapply
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 serviceaccountNAME SECRETS AGE
default 0 24d
sa-default 0 49m
kubectl get roleNAME CREATED AT
role-full-access-to-secrets 2024-01-24T23:22:39Z
kubectl get rolebindingNAME ROLE AGE
default-role-binding Role/role-full-access-to-secrets 48m
kubectl get cronjobNAME 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-wpdeployment.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/defaultimagePullSecrets のnameを今回追加したもの(regcred)へ書き換えます
確認
digitaloceanからECRへ変更されたことを確認
kubectl get pods -n doks-wpNAME 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 secretNAME TYPE DATA AGE
ecr-registry-helper-secrets Opaque 3 12h
ocarina kubernetes.io/dockerconfigjson 1 25d
regcred kubernetes.io/dockerconfigjson 1 117mkubectl get cronjobsNAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
ecr-registry-helper 0 /10 False 0 118m 12h
kubectl get jobsNAME COMPLETIONS DURATION AGE
ecr-registry-helper-28435680 1/1 8s 11h
ecr-registry-helper-28436280 1/1 6s 118m
