imagePullSecrets manager: 놓치지 않을거에요... Expired Authorization Token..

KEUN·2022년 7월 6일
1
post-thumbnail

만료/변경된 imagePullSecrets을 관리하기 위해 만든 imagepullsecrets-manager를 소개한다.

https://github.com/GeunjeLEE/private-registry-secret-manager

개요


현재 팀의 서비스는 오픈소스로 되어있기 때문에 github는 물론 docker hub도 공개되어있다.

하지만 최근 private(코드를 공개하지 않는) 프로젝트의 CI/CD를 구축할 일이 생기면서
상당히 귀찮은 상황을 마주하게 되었다.

github는 물론이고 docker image역시 private repository을 사용한다는 것이 그것인데,
kubernetes에서 private image를 받아오기 위해서는 credential이 필요하다는 것은 누구나 아는 사실...

나 역시도 이러한 사실을 알고 착실히 credential을 생성하고, (k8s의)secret으로 만들어 일단은 배포에 성공했더랬다...

삽질 과정


프라이빗 레지스트리에서 이미지 받아오기

처음 CI/CD를 구축하면서 배포를 위해 imager repository의 credential을 적용할 수 있는 방법을 찾아봤는데 kubernetes 공식 문서에는 아래와 같은 private image를 위해 credential을 제공하는 방법을 제시하고 있었다.

  • 1. 프라이빗 레지스트리에 대한 인증을 위한 노드 구성
    • 모든 파드는 구성된 프라이빗 레지스트리를 읽을 수 있음
    • 클러스터 관리자에 의한 노드 구성 필요
  • 2. 미리 내려받은(pre-pulled) 이미지
    • 모든 파드는 노드에 캐시된 모든 이미지를 사용 가능
    • 셋업을 위해서는 모든 노드에 대해서 root 접근이 필요
  • 3. 파드에 ImagePullSecrets을 명시
    • 자신의 키를 제공하는 파드만 프라이빗 레지스트리에 접근 가능
  • 4. 공급 업체별 또는 로컬 확장
    • 사용자 정의 노드 구성을 사용하는 경우, 사용자(또는 클라우드 제공자)가 컨테이너 레지스트리에 대한 노드 인증 메커니즘을 구현할 수 있다.

1번의 경우 worker node에 뛰어들어서 일일히 설정 잡는게 불편하다고 느꼈고,
2번의 경우 사실 저걸 왜 언급한건지 이해하지 못했다, 어차피 registry에서 받아와야하는데...
3번의 경우 가장 많이 눈에 띄는 방법이었다. (blog에서 많이 찾아볼 수 있었다.)
4번의 경우 필요하면 너가 구현해 라고 말하는 것 같았다.

때문에 3번의 방법으로 일단 최초 배포를 해둔 상태였다.

그리고 ImagePullBackOff

최조 배포 후, 조금 불안불안하긴 했으나 아니나 다를까.
얼마 뒤 pod가 image를 받아오지 못해 배포에 실패하는 현상을 마주하고 말았다.

Failed to pull image "registry.example.com/private-image:latest": rpc error: code = Unknown desc = Error response from daemon: pull access denied for registry.example.com/private-image:latest, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

살펴보니 ECR의 credential, 즉 aws get-login-password로 발급한 authorization token은 12시간의 유효기간을 가지고 있었고역시나 그것이 문제였다.(아...앙대... 배포 자동화....ㅠㅠ)

private image를 위해 repository에 접근하는 것이 아닌, 접근을 위한 credential이 문제가 되는 것 이었다.

놓치지 않을거에요... Expired Token..


이러한 credential을 자동으로 관리하기 위해 구글링을 해보았더니 이미 너드형들이 여러 솔루션을 만들어두고 블로그에 자랑하고 있었다. (admission controller로 구현해놓은 형님도 봤다..!)

몇 가지를 살펴보면서 느낀건 대단하긴 한데, 내가 도저히 따라갈 수 없었다.(혹은 너무 설정하기 복잡했다.)

그래서 나는 내 방식으로 만들고 더 나아가 나같이 코만 파고있는 사람들도 쉽게 사용할 수 있도록 만들고 싶었다.

imagePullSecrets-manager

그래서 만든 것이 imagePullSecrets-manager인데 kubernetes cronjob으로 움직이는 간단한 python script이다.

자신이 생성/관리하고 싶은 repository login 정보를 설정해두기만 하면 imagePullSecrets-manager가 나타나서 대신 생성하고, 관리해준다.

기본 동작

  • kuberenetes cronjob으로 움직인다.
  • schdule에 맞춰 python sciprt가 실행되면서 imagePullSecrets를 생성/관리/삭제 한다.

기능

  • imagePullSecrets 생성
    • repository login 정보를 설정 파일에 적어두면 그것을 바탕으로 imagePullSecrets를 생성한다.
      • ECRDOCKERHUB에 대한 유형을 지원한다.
  • imagePullSecrets 관리
    • ECR
      • expire_date가 만료되면 다시 get-login-password로 토큰을 발급해 imagePullSecrets을 업데이트한다.
    • DOCKERHUB
      • login 정보가 변경되면 imagePullSecrets를 업데이트한다.
  • imagePullSecrets 삭제
    • 더 이상 필요 없어진 credential 정보를 설정 파일에서 삭제하면 imagePullSecrets를 삭제한다.

배포

helm chart를 만들어두었기 때문에 쉽게 배포할 수 있다.

이점

  • ECR Credential의 TOKEN 유효기간을 더 이상 사람이 신경쓰지 않아도 된다.
  • 생성된 모든 imagePullSecrets을 쉽게 파악하고 관리할 수 있다.

사용법

https://github.com/GeunjeLEE/imagepullsecrets-manager

Prerequisite

아래의 툴이 필요하다.

  • kubectl
  • helm

git clone

$ git clone https://github.com/GeunjeLEE/imagepullsecrets-manager.git

configure

$ cd imagepullsecrets-manager
$ vim helm/values.yaml
---
name: imagepullsecrets-manager
namespace: default
image:
    name: nigasa12/imagepullsecrets-manager
    version: <image-version> # 2020.07.06기준 1.0.0
imagePullPolicy: IfNotPresent
job_schedule: "* * * * *"    # cron schedule / default every minute
successfulJobsHistoryLimit: 10
config:
  secrets:					 # 생성할 imagepullsecrets의 credential 
    - name: ecr-example
      kubernetes_namespace: default
      type: ECR
      credential:
        aws_access_key_id: foobargem
        aws_secret_access_key: foobargem
        aws_ecr_repository_region: ap-northeast-2
    - name: docker-example
      kubernetes_namespace: default
      type: DOCKER
      credential:
        docker_registry: docker.io
        docker_user: foobargem
        docker_password: password
        docker_email: foobargem@example.com

deploy

$ helm install imagepullsecrets-manager ./helm

update

$ helm upgrade imagepullsecrets-manager ./helm

destroy

$ helm uninstall imagepullsecrets-manager

마무으리

현재 팀의 개발환경에도 imagepullsecrets-manager를 배포하고 운영해보고 있다.
당연히 현재는 pod가 image를 받아오지 못해 배포에 실패하는 현상은 발생하지 않고 있다.

이러한 것은 imagepullsecrets-manager가 항상 imagepullsecrets를 노려보며 유효기간이 지났는지 체크해주고 있기 때문이다.

이것으로 내가 수시로 imagepullsecrets가 만료되지 않았는지 확인하는 일은 하지 않아도 된다.(어렵사리 이어붙힌 CI/CD 자동화...)

현재 팀이 너무나도 바쁜 상황이라 code review도 이루어지지 않은 허접한 코드이지만
앞으로 상황이 나아지면 팀 시니어 개발자들에게도 소개하고 code review도 진행해서 상용환경에도 적용해보고 싶은 마음이다.

profile
Let's make something for comfortable development

0개의 댓글