GitOps 전환기 — Part 5. ArgoCD를 활용한 CD 구성하기

ArgoCD란?

ArgoCD는 GitOps를 구현하기 위한 도구 중 하나로 쿠버네티스 애플리케이션의 자동 배포를 위한 오픈소스 도구입니다. CI/CD 과정에서 CD 부분을 담당하며, Git 저장소의 변경 사항을 감지하여 자동으로 쿠버네티스 애플리케이션에 반영시킬 수 있습니다.

GitOps란?

GitOps란 DevOps의 적용하는 실천 방법 중 하나로 클라우드 네이티브 애플리케이션을 대상으로 한 지속적인 배포에 초점을 맞추고 있습니다. 이름에서 나타나듯이 배포와 운영에 관련된 모든 요소를 Git으로 관리하는 것에 초점이 맞춰져 있습니다.

GitOps는 배포와 관련된 모든 것을 선언형 기술 형태로 작성하여 이러한 파일들을 레포지토리 형태로 관리합니다. 그리고 선언형 기술서와 운영 환경 간 상태 차이가 없도록 유지시켜주는 자동화 시스템을 구성합니다.

어떻게 변경사항을 감지할까?

ArgoCD가 Git 저장소의 변경사항을 확인하는 방법은 크게 두 가지가 있습니다.

Polling 상태의 경우 최악의 상황에 따라 3분 후에 변경사항을 반영될 수 있습니다. 그러므로 실시간 동기화를 중요하다고 생각한다면 Webhook Event를 사용하면 됩니다.

프로젝트에 적용하기

해당 게시글은 프로젝트에 ArgoCD를 어떻게 적용했는지 작성되어 있습니다. 설치 방법은 공식 문서 를 참고하시길 바랍니다.

프로젝트 구성

현재 프로젝트에서는 ctf-app, challenge-api의 이미지 해시값을 기반으로 Config Repository manifest를 업데이트하는 방식으로 구성했습니다.

ArgoCD sync 결과를 프로젝트마다 할당된 슬랙 채널에 전송할 수 있도록 설정했습니다.

CI/CD 구성도

Polling vs Webhook Event

프로젝트에서는 Polling 방식으로 수행했습니다.
지속적인 배포를 수행하기 위해서는 Webhook 방식으로 수행하는 것이 적절합니다. 그러나 관리해야 하는 프로젝트 수가 적고 ArgoCD 자체를 처음 사용하기도 해서 polling 방식을 선택하게 되었습니다.

위에서 Polling 상태의 경우 최악의 상황에 따라 3분 후에 변경사항을 반영될 수 있다고 말씀 드렸습니다. 3분이 수치 상으로 짧다고 생각할지라도 체감상으로 엄청 길게 느껴집니다. 프로젝트 수가 적고 배포 일정이 2–3시간으로 짧아 수동적으로 sync를 수행하며 비효율적인 대기 시간을 줄였습니다.

다음 프로젝트에 ArgoCD를 활용하게 된다면 Webhook 방식을 사용할 것입니다.

ArgoCD가 다른 Namespace에 배포하는 법

배포 구성도를 보면 ArgoCD는 argocd namespace에 존재하고 배포해야 할 애플리케이션은 hexactf namespace에 존재합니다.

namespace 별 쿠버네티스 애플리케이션 구성도

default가 아닌 다른 namespace에 애플리케이션을 배포하려면 project 단위로 namespace를 허용해야 합니다. 그렇지 않으면 permission denied 오류를 만날 수 있습니다.

default project가 아닌 hexactf라는 프로젝트를 생성하여 hexactf namespace 배포를 허용했습니다.

project: hexactf namespace 배포 허용

namespace 뿐만 아니라 쿠버네티스 리소스도 허용/차단을 설정할 수 있습니다.
프로젝트 중에서는 ClusterRole, ClusterRoleBinding이 필요하므로 Cluster Resource allow list에 추가했습니다.

project: resource allow list에 ClusterRole, ClusterRoleBinding 추가
challenge-api 쿠버네티스 배포 결과

Config Repository 구성

Config Repository로 관리해야 하는 프로젝트는 두 개가 있습니다. 각각의 프로젝트는 서로 다른 개발자가 저장소를 사용하고 있습니다. 저는 배포를 담당하고 있으며 Kustomize 패키징 도구를 활용하여 배포 코드를 관리하고 있습니다.

하나의 저장소에 다수의 manifest 관리의 문제점

저는 초기에 하나의 저장소에 2개의 프로젝트를 폴더로 분리하여 관리했습니다. 그 이유는 배포를 저 혼자 담당하며 분리해서 관리하는 것이 비효율적이라고 판단했기 때문입니다.

Config Repository: Kustomize 구조
ArgoCD에 등록한 application 목록

그러나 slack notification을 설정하면서 이러한 구성이 잘못되었음을 알게 되었습니다.

slack notification 설정은 공식 문서를 참고하시길 바랍니다.

비록 하나의 애플리케이션의 manifest만 변경될지라도 모든 애플리케이션이 변경되었다고 간주되어 모든 슬랙 채널에 알림을 보내는 것이었습니다. 이로 인해 다수의 불필요한 알림을 보내게 되어 팀원에게 불필요한 잡음을 준다고 생각했습니다.

문제를 해결하기 위해 slack 메세지를 보니 Revision의 해시가 같다는 공통점을 찾았습니다. 해당 저장소의 커밋 해시가 바뀌면서 하위의 모든 애플리케이션이 OutOfSync로 인식하고 sync를 수행하고 있었습니다.

challenge-api ArgoCD Slack message
ctf-app ArgoCD Slack message

ArgoCD Issue를 보면 auto-sync를 설정할때 위와 같은 작업은 자연스러운 것이라고 말합니다. 여기서 auto-sync(자동 동기화)는 ArgoCD가 Git 저장소와 Kubernetes 클러스터 리소스의 상태를 자동으로 비교하며 변경사항 발생 시 적용해주는 기능입니다.

내용을 종합했을때 제가 설정한 Config Repository 구조는 잘못되었음을 알 수 있습니다.

Argo CD uses the SHA to determine whether an auto-sync needs to occur. This would be a pretty fundamental change.
출처 — https://github.com/argoproj/argo-cd/issues/1646

하나의 저장소로만 관리할 시 프로젝트 별 변경 추적의 어려워지고 불필요한 롤백이 발생하게 됩니다. 왜냐하면 저장소 하나가 하나의 대상으로 간주되기 때문입니다.
이러한 문제점으로 인해 GitOps의 장점을 활용하지 못하게 됩니다.

Best Practice: 프로젝트 manifest 마다 저장소를 분리하자

공식 문서에 의하면 커밋 해시 단위로 manifest가 불변이여야 한다는 best practice가 있으며, 이는 곧 각각의 프로젝트는 서로 다른 저장소에 관리되어야 한다는 의미로 해석할 수 있습니다.

Ensuring Manifests At Git Revisions Are Truly Immutable
출처 — https://argo-cd.readthedocs.io/en/stable/user-guide/best_practices/#ensuring-manifests-at-git-revisions-are-truly-immutable

저장소의 분리는 관리해야 하는 저장소가 늘어나는 대신에 정확한 변경 이력 추적과 적합한 범위의 롤백이 가능하여 GitOps의 장점을 활용할 수 있게 됩니다.

추후 계획: 프로젝트 manifest 마다 저장소 분리하기
문제를 뒤늦게 인지해서 이번 프로젝트에서는 하나의 저장소에 다수의 manifest를 관리했습니다.

그러나 다음 기회에는 프로젝트마다 분리하여 불필요한 알림을 줄이고, 정확하게 변경 이력을 추적할 수 있도록 설정할 것입니다.

시리즈를 마치며

처음 CI/CD를 사용하지 않고 배포를 수행하다가 비효율성을 느껴 CI/CD를 도입하게 되었습니다. 막상 적용하고 나니 도구의 장점을 제대로 살리지 못한 것 같습니다.

다음에는 부족하다고 생각한 부분을 모두 수정하여 보완해야 할 것 같습니다.

관련 시리즈

References

<hr><p>GitOps 전환기 — Part 5. ArgoCD를 활용한 CD 구성하기 was originally published in S0okJu Technology Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>