개요

ECR를 private registry로 설정하고 과제를 진행하면서 클러스터에서 이미지를 당겨올 때 사용하는 시크릿이 계속 만료되어 삭제하고 재생성해야하는 이슈가 있었다.

kubectl create secret -n wrtn docker-registry ecr-regcred \\
--docker-server=165998515795.dkr.ecr.ap-northeast-2.amazonaws.com \\
--docker-username=AWS \\
--docker-password=$(aws ecr get-login-password --region ap-northeast-2) \\
--docker-email=sehyeong.dev@gmail.com

그 이유는 aws ecr get-login-password --region ap-northeast-2 명령어로 생성된 토큰의 유효 기한이 12시간이기 때문이다. 매번 실습하고 다음날에 다시 배포를 하면 ImagePullBackOff 에러가 났고 시크릿을 삭제하고 다시 생성했다.

쿠버네티스에서는 리눅스 Crontab 처럼 Job을 생성해서 원하는 주기마다 실행할 수 있다. 이를 이용해서 ECR 관련 시크릿을 클러스터에 주기적으로 갱신해본다.

실행해야하는 명령어를 바탕으로 Dockerfile 준비하기

실행해야하는 명령어 (kubectl, aws-cli 필요)

# 시크릿 삭제
kubectl delete secret ecr-regcred -n wrtn

# 시크릿 생성
kubectl create secret -n wrtn docker-registry ecr-regcred \\
--docker-server=165998515795.dkr.ecr.ap-northeast-2.amazonaws.com \\
--docker-username=AWS \\
--docker-password=$(aws ecr get-login-password --region ap-northeast-2) \\
--docker-email=sehyeong.dev@gmail.com

kubectl, aws-cli가 설치된 컨테이너 생성을 위한 Dockerfile

FROM ubuntu:22.04

RUN apt-get update && apt-get install -y curl unzip

# kubectl 설치
RUN curl -LO <https://dl.k8s.io/release/v1.29.1/bin/linux/arm64/kubectl> && \\
		install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# aws-cli 설치
RUN curl "<https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip>" -o "awscliv2.zip" && \\
unzip awscliv2.zip && \\
./aws/install

Job에 대한 manifest 작성하기

apiVersion: v1
kind: ConfigMap
metadata:
  name: ecr-env
data: # 필요한 환경변수들
  ECR_REGISTRY: 165998515795.dkr.ecr.ap-northeast-2.amazonaws.com
  AWS_ACCESS_KEY_ID: AKIASNJSIKZJUYUQW3GT
  AWS_SECRET_ACCESS_KEY: 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 
  AWS_REGION: ap-northeast-2
  ECR_EMAIL: sehyeong.dev@gmail.com
apiVersion: v1
kind: ServiceAccount
metadata: # 서비스어카운트를 생성하고 
  name: secret-refresher
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-manager
rules:  # 시크릿 조회, 삭제가능한 권한을
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["create", "get", "list", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-manager-binding
subjects:
- kind: ServiceAccount
  name: secret-refresher
roleRef: # 부여한다.
  kind: Role
  name: secret-manager
  apiGroup: rbac.authorization.k8s.io
apiVersion: batch/v1
kind: CronJob
metadata:
  name: ecr-secret-refresh-job
spec:
  schedule: "0 */6 * * *" # 6시간 마다 
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: secret-refresher
          imagePullSecrets: 
          - name: ecr-regcred
          containers:
          - name: ecr-secret-refresher
            image: 165998515795.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-secret-refresher
            envFrom:
              - configMapRef:
                  name: ecr-env
            command:
            - /bin/sh
            - -c
            - |
              kubectl delete secret ecr-regcred -n wrtn
              kubectl create secret -n wrtn docker-registry ecr-regcred \\
              --docker-server=$ECR_REGISTRY \\
              --docker-username=AWS \\
              --docker-password=$(aws ecr get-login-password --region $AWS_REGION) \\
              --docker-email=$ECR_EMAIL
          restartPolicy: OnFailure