Argo CD
관련한 포스팅은 해당 내용을 마지막으로 마무리가 될 꺼 같다. 이외의 다른 설정값이나 사용 방법들은 구글링을 통해 충분히 찾아서 해결할 수 있을 것으로 생각이 됩니다.
이번 포스팅에서는 Pull
방식으로 도커 이미지 태그를 업데이트 하고 AWS EKS
에 자동으로 배포할 수 있도록 Argo CD
에서 개발하고 있는 Argo CD Image Updater
설정 방법에 대해서 알아보도록 하겠습니다.
그럼 pull
방식이 있으면 push 방식도 있냐고 물어볼 수 있는데, 대표적으로 pull
, push
두가지 방식이 존재합니다. 해당 포스팅은 GitOps
에 대한 내용을 다루는 부분이 아님으로 간략하게만 짚고 넘어가면 다음과 같습니다. (AWS
기준으로 설명을 작성하겠습니다.)
해당 이미지는 AWS CDK 활용법에서 제안한 AWS GitOps 인프라입니다.
하나의 프로젝트에 자신이 개발하는 애플리케이션 레포지토리와 CDK용 레포지토리 2개가 존재합니다.
위와 같이 사용자가 이미지를 배포를 하기 위해서 push
를 하게되면 트리거에 따라서 배포 프로세스가 실행되는 방식을 push
방식이라고 합니다.
반면에 Pull
방식은 이미지를 배포할 때 배포 파이프라인을 가동시키는 것이 아닌 배포 파이프라인을 대신하는 툴(Argo CD
, Flux CD
등)이 자동으로 변경점을 인식해서 쿠버네티스에 배포하는 방식을 말합니다. (위의 이미지는 Argo CD Tutorial 영상에서 발췌했습니다.)
그럼 둘 중에 뭐가 더 좋은 방식이라고 할 수 있냐? 무조건적인 답은 아니지만 GitOps
개념을 만든 Weavework
에서 권장하는 방식은 Pull
방식이라고 합니다. 자세한 내용은 삼성 SDS에서 설명한 자료를 한번 읽어보시면 이해가 좀 더 쉽게 되실꺼라고 생각됩니다.
❗️ 주의 ❗️
들어가기에 앞서Argo CD Image Updater
플러그인을 사용하려면 쿠버네티스 리소스를Helm chart
혹은Kustomize
형식으로 배포를 해주셔야지만 사용이 가능합니다!!
이제 진짜 본격적으로 자동으로 이미지 태그를 업데이트 하기 위한 절차를 밟아보도록 하자! 먼저 공식 사이트가 존재는 하는데 뭔가 설정들이 파편화 되어있어서 보는데 애좀 먹었다.
각설하고 공식 문서에 따르면 Argo CD Image Updater
플러그인은 Argo CD가 설치되어있는 클러스터에 설치해서 사용하는 것을 권장하고 있습니다. (강요는 아니라고 나와있지만 하라는대로 합시다!)
그럼 Argo CD Image Updater
설치를 위해 Argo CD
가 설치되어있는 클러스터에 터미널을 이용해서 접속합니다. 그리고 다음 명령을 입력해서 설치해줍니다. (argocd
네임스페이스가 아닌 다른 곳에 설치했다면 -n <argocd가 설치된 네임스페이스>
로 변경해줍니다.)
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
조금의 시간이 흐르면 Argo CD Image Updater
파드가 실행이 될 것이고 정상적으로 실행이 된다면 다운로드가 완료된 것 입니다.
이 부분은 Argo CD Image Updater
의 로그 레벨을 설정할 수 있는 부분인데 필요 없다면 그냥 넘어가도 무방하다.
로그 레벨 설정 방법은 다음과 같다. 아래의 명령으로 argocd-image-updater-config
설정 파일을 엽니다.
kubectl edit configmap argocd-image-updater-config -n argocd
그리고 내용을 다음과 같이 수정합니다.
apiVersion: v1
kind: ConfigMap
data:
# log.level can be one of trace, debug, info, warn or error
log.level: debug
# 생략
그리고 :wq!
로 저장하고 나오면 로그 레벨 설정이 완료된 것입니다.
그 다음으로 해줘야할 부분이 Argo CD
의 API
를 사용하기 위해서 API
용 계정을 하나 생성해주어야 한다. (현재는 Argo CD
홈페이지 로그인 계정 하나만 존재할 것이다.)
생성하기 위해서 argocd-cm
configMap 파일을 열 수 있도록 한다.
kubectl edit configmap argocd-cm -n argocd
그 다음 아래의 내용을 적을 수 있도록 한다.
apiVersion: v1
kind: ConfigMap
data:
# api 접근 용도로만 사용할꺼기 때문에 apiKey 만 적어준다
accounts.image-updater: apiKey
#생략
이렇게하고 저장하면 image-updater
라는 이름으로 계정이 생성된 모습을 볼 수 있다.
$ argocd account list
NAME ENABLED CAPABILITIES
admin true login
image-updater true apiKey
만약
FATA[0000] rpc error: code = Unauthenticated desc = invalid session: token is expired by <토큰>
에러가 뜨면argocd
로그인을 다시 진행해주고 계정 조회를 할 수 있도록 하자!
$ argocd login <argocd 주소>
WARN[0000] Failed to invoke grpc call. Use flag --grpc-web in grpc calls. To avoid this warning message, use flag --grpc-web.
Username: admin
Password:
'admin:login' logged in successfully
Context <argocd 주소> updated
그 다음 방금 생성한 계정에 RBAC
권한을 설정해주어야지만 정상적으로 Argo CD API
사용이 가능해진다. 필수로 추가해야하는 권한은 GET
과 UPDATE
이다.
계정 권한 설정을 위해 argocd-rbac-cm
configMap 파일을 열고 다음 정보를 기입한다.
kubectl edit configmap argocd-rbac-cm -n argocd
apiVersion: v1
kind: ConfigMap
data:
policy.csv: |
p, role:image-updater, applications, get, */*, allow
p, role:image-updater, applications, update, */*, allow
g, image-updater, role:image-updater
policy.default: role.readonly
# 생략
이제 계정이 준비가 다 되었으면 Argo CD
를 이용해서 도커 이미지 파일을 다운로드할 레포지토리를 등록해주어야 한다. 저는 AWS ECR
을 이용해서 도커 이미지 파일을 관리하고 있기 때문에 AWS ECR
로 등록해주겠습니다.
등록하기 위해 argocd-image-updater-config
configMap 파일을 열고 다음과 같이 수정해줍니다. (공식 문서에서는 argocd-image-updater-cm
에서 설정을 변경하라고 나와있는데 해당 configMap
파일은 없어서 가장 유사한 argocd-image-updater-config
에 설정을 해주었더니 되었습니다. 참고하시면 될 것 같습니다.)
kubectl edit configmap argocd-image-updater-config -n argocd
apiVersion: v1
data:
applications_api: argocd
argocd.grpc_web: "true"
argocd.insecure: "false"
argocd.plaintext: "false"
argocd.server_addr: <argocd 접속 주소>
kind: ConfigMap
설정 값에 따른 간략한 설명은 다음과 같습니다.
applications_api
: argocd로 고정argocd.grpc_web
: HTTP/2를 통해 GRPC 대신 GRPC_WEB 프로토콜을 사용할지 여부argocd.insecure
: Argo CD API endpoint의 잘못된 TLS 인증서를 무시할지 여부argocd.plaintext
: TLS (https) 대신 일반 텍스트 연결(http)을 사용할지 여부위에서 credentials
에 적힌 secret
생성 방법은 다음과 같습니다.
kubectl create secret docker-registry aws-ecr-creds \
--docker-server=<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<ECR REPO 이름> \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password) \
-n argocd
이제 Argo CD API
에 사용될 Access Token
을 쿠버네티스 리소스인 secret
으로 생성을 해주도록 하겠습니다.
먼저 아까 image-updater
계정에 대한 토큰을 발행해줍니다.
- 주의할 점으로 토큰은 한번 발급하면 새로 발급하지 않는 이상 조회할 수 없습니다. 필요한 경우 복사해서 다른 곳에 보관하시기 바랍니다.
- 토큰은 기본적으로 만료일이 없는
No Expired
설정이 디폴트입니다. 따라서Expired
값을 주고 싶은 경우에는-e
혹은--expires-in
옵션값을 주고0s
와 같은 식으로 작성해주시면 됩니다.
image-updater
토큰 발행은 다음 명령으로 합니다.
argocd account generate-token --account image-updater --id image-updater
명령으로 나오는 토큰을 복사해두고 Access Token secret
$YOUT_TOKEN
에다가 생성해 넣을 수 있도록 합니다.
kubectl create secret generic argocd-image-updater-secret \
--from-literal argocd.token=$YOUR_TOKEN --dry-run -o yaml |
kubectl -n argocd apply -f -
그 동안 만든 secret
을 조회하기 위해서는 다음 명령을 통해 조회할 수 있습니다.
kubectl get secrets -n argocd
기본적으로 Argo CD Image Updater
는 AWS ECR
을 공식 지원하지 않습니다. 하지만 인증 정보를 잘 설정해주면 사용할 수 있는 것으로 알고 있고 적용이 되었습니다.
먼저 컨테이너 레파지토리 정보를 설정해주어야 합니다. 설정은 아래와 같이 할 수 있습니다.
kubectl edit configmap argocd-image-updater-config -n argocd
apiVersion: v1
kind: ConfigMap
data:
applications_api: argocd
argocd.grpc_web: "true"
argocd.insecure: "false"
argocd.plaintext: "false"
argocd.server_addr: <argocd 주소>
registries.conf: | <-- 추가
registries:
- name: AWS ECR HUB
api_url: https://<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
prefix: <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
ping: yes
credentials: ext:/app/aws/ecr.sh
tagsortmode: latest-last
# 생략
간략한 설정 값 설명은 다음과 같습니다.
api_url
: suffix 없이 순수한(?) AWS ECR 주소prefix
: https:// 제외한 api_url
주소 (해당 부분을 명시하지 않으면 prefix 오류 발생)ping
: ping 요청을 보낼지에 대한 여부credentials
: ECR 이미지 엑세스 권한을 넣어준다. tagsortmode
: 태그 이미지 소트 방식에 대해서 적어준다. (latest-first
, latest-last
중 하나)여기서 핵심이 credentials
부분인데 쿠버네티스 secret
리소스로 하드코딩 방식으로 토큰값을 넣게 되면 하루가 지날 경우 만료돼서 매번 다시 생성해줘야 한다. 따라서 요청시마다 토큰값을 생성해주는 명령을 쳐서 인증할 수 있도록 구성할 예정이다.
argocd-image-updater
컨테이너 내부로 접속합니다.kubectl -n argocd exec --stdin --tty pod/argocd-image-updater-8687d55bb-mxdn2 -- /bin/sh
app
폴더 밑에 sh
파일을 생성하고 다음 내용을 적습니다. (credentials
에서 경로만 잘 맞춰면 돼서 경로는 자유롭게 하시면 됩니다. 저의 경우 ext:/app/aws/ecr.sh
라고 적었기 때문에 app
폴더 밑에 aws
폴더 생성하고 그 곳에 ecr.sh
파일을 생성할 예정입니다.)$ cd /app
$ mkdir aws
$ cd aws
$ vi ecr.sh
#!/bin/sh
aws ecr --region ap-northeast-2 get-authorization-token --output text --query 'authorizationData[].authorizationToken' | base64 -d
컨테이너에 접속해서 명령어만 치면 권한이 없다고 뜰텐데 권한 설정을 잘 못해서 유일하게 권한이 있는
app
폴더에서 작업하였습니다.
aws configure
설정을 해줍니다.$ aws configure
AWS Access Key ID: <AWS_ACCESS_KEY_ID>
AWS Secret Access Key: <AWS_SECRET_KEY_ID>
Default region name: <AWS_REGION>
Default output format:
$ argocd-image-updater test \
<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<ECR_REPO_NAME> \
--registries-conf ./app/config/registries.conf
INFO[0000] getting image image_name=<ECR_REPO_NAME> registry=<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
DEBU[0000] rate limiting is disabled prefix=<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com registry="https://<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com"
INFO[0000] Loaded 1 registry configurations from ./app/config/registries.conf
INFO[0000] /app/aws/ecr.sh dir= execID=hE99c
INFO[0003] Fetching available tags and metadata from registry image_name=<IMAGE_NAME>
INFO[0003] Found 2 tags in registry image_name=<ECR_REPO_NAME>
DEBU[0003] found 2 from 2 tags eligible for consideration image=<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<ECR_REPO_NAME>
INFO[0003] latest image according to constraint is <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<ECR_REPO_NAME>:<IMAGE_TAG>
위와 같이 로그가 나오면 성공한 것이고 실패했을 경우 실패 로그를 보고 원인을 파악해야 하는데 저의 경우에는 스무스하게 잘 되었던걸로 기억이 돼서 registries.conf
파일 경로나 ecr.sh
파일에 오타만 없으면 잘 될 것으로 생각됩니다.
마지막으로 Argo CD Image Updater
의 기능을 적용하기 위해서 Argo CD Application
의 annotations
부분에 몇개의 설정 값들을 적어주어야 합니다. 해당 annotation
을 작성하지 않으면 트리거가 일어나지 않습니다.
우선 생성한 Argo CD Application
을 선택합니다.
APP DETAILS > SUMMARY > EDIT > ANNOTATIONS
에서 + 버튼 을 눌러서 다음을 채워넣습니다.
argocd-image-updater.argoproj.io/image-list
: org/app=<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<ECR_REPO_NAME>argocd-image-updater.argoproj.io/org_app.pull-secret
: ext:/app/aws/ecr.shargocd-image-updater.argoproj.io/write-back-method
: argocd (git or argocd 택 1, 디폴트는 argocd)argocd-image-updater.argoproj.io/org_app.update-strategy
: latestargocd-image-updater.argoproj.io/org_app.allow-tags
: regexp :^[0-9a-f]{7}$CI
를 통해 AWS ECR
에 이미지를 업로드하면 다음과 같이 PARAMETERS
의 image.tag
가 업데이트 된다.💡 위의 이미지를 보시면
image.name
,image.tag
라는 변수가 보일 것이다.image.name
,image.tag
변수는argocd-image-updater
가 생성하고 관리하는 변수명이고 해당 변수와 동일하게Helm Chart
를 구성해야지만 자동 업데이트 기능을 사용할 수 있게 된다.
예를 들어,ecr.image.name
,ecr.image.tag
와 같이Argo CD Image Updater
가 모르는 태그로 이미지를 관리한다면 업데이트가 되어도 적용이 안된다.
Argo CD Image Updater
가 실행되는 로그를 보려면 다음과 같이 명령을 치면 된다.$ kubectl logs pod/argocd-image-updater-8687d55bb-mxdn2 -n argocd
time="2022-03-14T07:06:57Z" level=info msg="Starting image update cycle, considering 1 annotated application(s) for update"
time="2022-03-14T07:06:57Z" level=info msg="Setting new image to <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<ECR_REPO_NAME>:<IMAGE_TAG>" alias=org/app application=<Argo CD app name> image_name=<ECR_REPO_NAME> image_tag=<NOW_IMAGE_TAG> registry=<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
time="2022-03-14T07:06:57Z" level=info msg="Successfully updated image '<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<ECR_REPO_NAME>:<NOW_IMAGE_TAG>' to '<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<ECR_REPO_NAME>:<NEW_IMAGE_TAG>', but pending spec update (dry run=false)" alias=org/app application=<Argo CD app Name> image_name=<IMAGE_TAG> image_tag=<NOW_IMAGE_TAG> registry=<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
time="2022-03-14T07:06:57Z" level=info msg="Committing 1 parameter update(s) for application <Argo CD app Name>" application=<Argo CD app Name>
time="2022-03-14T07:07:01Z" level=info msg="Successfully updated the live application spec" application=<Argo CD app Name>
time="2022-03-14T07:07:01Z" level=info msg="Processing results: applications=1 images_considered=1 images_skipped=0 images_updated=1 errors=0"
이 부분에서 가장 많이 뜬 오류는 단연코 인증 관련 문제였다. 만약 권한이 없다는 오류가 발생하면
ecr.sh
가 정상적으로 작동하지 않는다는 것이다. 따라서 다시 그 부분을 설정해보고 시도할 수 있도록 한다.
Argo CD Image Updater
는 약 2분 간격으로 실행된다.
이렇게해서 Argo CD
를 회사에 적용하면서 파편화 되어있던 정보들을 한 곳에 모으고자 작성했던 내용이었는데 적으면서 한번 더 리마인드가 된 계기가 되었다. 근데 또 다음에 하려고 한다면 헤매지 않을까 걱정되지만 그래도 한번 해봤기 때문에 해결에 있어서는 조금 수월할 것으로 생각이 된다.
뭔가 두서도 없고 비약된 내용이 있을지도 모른다고 생각이 되지만 결론은 공식 문서에서 찾아서 한 부분이라 제 글에서 부족한 부분이라고 판단되는 부분은 공식 문서에서 찾아보시면 저보다 더 빠르게 해결할 수 있을 것으로 생각이 됩니다.
잘못된 부분이나 기타 다른 피드백 등 해주시면 빠르게 답변하도록 하겠습니다.
감사합니다.
안녕하세요! 좋은 글 감사합니다
한 가지 궁금한 부분이 생겨서 댓글 남겨요
CI를 통해서 AWS ECR에 새로운 이미지를 푸시해도 Argocd 파라미터 image.tag가 업데이트 되지 않습니다.
helm 차트 작성 시, image.tag를 어떤 식을 작성해야하는지 알 수 있을까요?
argocd-image-updater test 명령어에서는 새롭게 푸시된 이미지를 잘 인식합니다.
$argocd-image-updater test xxx.dkr.ecr.ap-northeast-2.amazonaws.com/monster-was --registries-conf-path /app/config/registries.conf
INFO[0000] latest image according to constraint is xxx.dkr.ecr.ap-northeast-2.amazonaws.com/xxx:2.0.0 application=test image_alias= image_name=xxx.ecr.ap-northeast-2.amazon
aws.com/monster-was registry_url=xxx.dkr.ecr.ap-northeast-2.amazonaws.com
답변 부탁드립니다!
안녕하세요. 좋은 글 잘 보고 있습니다. 궁금한 게 있어 댓글 남겨 봅니다. 현재 테스트를 ECR이 아닌 Harbor를 사용하려 하는데 위 과정에서 Harbor 기준으로 변경해야 할 부분을 알려주실 수 있을까요? 샘플도 좋을 거 같습니다. ^^