GitOps는 버전 관리 도구인 git 이용해 DevOps를 지원하는 방법입니다. 쉽게 표현하면 코드를 git에 저장해두고 코드에 써 있는 대로 원하는 동작을 수행하는 것 입니다. 쿠버네티스에서는 git 코드 기반으로 선언적으로 리소스(인프라, 서버, 권한 등)를 동기화하고, 그 코드는 관리자들의 협업을 통해 관리하는 방법입니다. 따라서 관리자의 로컬 환경의 리소스가 아닌, 팀에서 함께 관리하는 공개 리소스를 운영할 수 있습니다. 이 블로그에서는 쿠버네티스를 위한 GitOps 도구인 Argo CD에 대해 소개합니다.
이 포스팅은 k8s, helm 사용법을 알고 계시다면 읽기 편합니다!
✨ 소개
DevOps에서 리소스 관리 및 배포를 하는 방식은 크게 두 가지가 있습니다. 하나는 '직접 관리' 하는 방식, 또 하나는 'GitOps'를 하는 방식 입니다. 직접 관리하는 방식은 작업자의 로컬 컴퓨터, 메모, 사내문서 등 공유/자동화하기 힘든 방식입니다. 이는 초기단계에서는 빠르지만, 지속적인 관리를 위해서는 다른 방식을 선택하는 것이 좋습니다. 바로 'GitOps'입니다.
여는 말에서 언급했듯이 GitOps는 협업이 가능한 선언적 리소스 (인프라, 워크로드) 관리방법 입니다. 이 방법을 이용하면 관리포인트가 늘어나는 단점이 있지만 직접관리하는 방법과 비교해 두 가지 큰 장점이 있습니다.
- 재현성: '어? 그거 제 컴퓨터에서는 됐는데요?' 를 방지할 수 있습니다 - 선언적 관리는 리소스의 상태를 보장한다는 점 입니다. Synced 상태의 GitOps는 담당자가 선언한 리소스가 쿠버네티스에 잘 반영되었다고 믿을 수 있습니다. (근데, 아주 가끔 버그가 있을 수 있어요 😅)
- 코드리뷰: '아, 이거 그렇게 하는 거 아닌데요' 를 할 수 있습니다 - 쿠버네티스 리소스는 사이트/서비스 신뢰성과 직결되기 때문에 여러 동료들의 리뷰가 있어야 합니다. Git의 Pull Request를 통해 합의된 변경점을 반영하여 리소스를 관리할 수 있습니다. GitOps는 이를 위한 좋은 방법입니다.
그럼 구체적으로 GitOps는 무엇일까요? 쉽게 그림으로 표현하겠습니다.
먼저 GitOps를 사용하지 않는 '직접 관리' 방식은 다음과 같습니다.
작업자의 로컬환경에서 리소스 변경 → 명령어로 클러스터에 반영 → 결과 확인 의 순서로 진행됩니다. 흐름이 간단한 만큼 빠른 결과를 얻을 수 있습니다. 프로덕션 환경에서는 개인이 모든 검증을 마치거나, 코드 리뷰를 하기 위해서 모두 작업자의 컴퓨터 앞으로 모여야 한다는 단점이 있습니다. 그 만큼 리스크가 올라가는 것이죠.
다른 방식인 GitOps 방식은 다음과 같습니다.
작업자의 로컬환경에서 리소스 변경 → Git에 반영 하고 구성원들의 리뷰를 거칩니다. 그리고 클러스터 환경에서 GitOps 컨트롤러 → 컨트롤러가 클러스터에 반영 → 결과 확인 의 순서로 마무리 됩니다. 흐름이 조금 복잡하고, 추가 리소스가 필요합니다. 테스트 환경에서는 중간 의사결정으로 시간이 필요하다는 단점이 있습니다. 프로덕션 환경에서는 여러 작업자가 Pull Request 방식으로 Git에 변경점을 올리고, 합의를 통하여 클러스터까지 반영할 수 있다는 장점이 있습니다. 그만큼 리스크가 내려가기 때문에 많은 기업에서 이 방식을 선택하고 있습니다. 그리고 이 때 GitOps 컨트롤러로 쓸 수 있는 것이 Argo CD 입니다.
GitOps를 위한 이 블로그의 순서는 다음과 같습니다.
- Argo CD 소개
- 쿠버네티스와 Argo CD 설정하기
- Argo App으로 매트릭 서버 배포하기
- GitOps 리포지토리 설정하기
- Argo App of Apps로 매트릭 서버 배포하기
- GitOps 응용하기
1,2,3은 Argo CD에 대한 내용입니다. 4,5,6은 Argo CD + GitOps에 대한 내용입니다. 그럼 시작해 보겠습니다.
🐙 Argo CD 소개
Argo CD는 Argo Project에서 관리하고 있는 Continuous Deployment 라는 프로젝트입니다. Argo 프로젝트 중에 가장 유명한 쿠버네티스 네이티브 앱 입니다. 심지어 개발자 중에 Argo Project라는 단어는 몰라도 ArgoCD, argocd, argo-cd 라는 이름으로 알고 계신 분들이 상당히 많습니다. 로컬 빌드로 사용할 수도 있지만, 대부분의 경우는 Argo CD가 배포된 쿠버네티스 클러스터에 밀착하여 리소스를 관리하고 있습니다. 공식 문서는 다음과 같습니다.
다른 프로젝트들도 확인하고 싶다면 이 링크를 참고해주세요. 제가 별도로 정리한 Argo CD에 대한 문서도 참고 부탁드립니다 ☺️.
🔧 쿠버네티스와 Argo CD 설정하기
먼저 쿠버네티스 클러스터를 생성합니다. `kubeconfig`를 쓸 수 있거나 최고 관리자(master)권한으로 `kubectl` 명령어를 쓸 수 있다면 어떤 쿠버네티스라도 상관없습니다. 저는 오브스택(OrbStack)로 로컬 쿠버네티스를 구성하였습니다. 여러분은 AWS EKS, GCP GKE, minikube, kind, 바닐라 k8s 등 자유롭게 설정하시면 됩니다.
간단한 로컬 쿠버네티스를 구성하고 싶으시면 제가 작성한 이 블로그를 참고해주세요. 도커 데스크탑과 오브스택의 사용법을 소개합니다.
다음은 실습을 위해 초기화한 오브스택 쿠버네티스 입니다.
클러스터에 아무 앱도 설치되어 있지 않습니다. 이 블로그에서는 클러스터에 Argo CD를 직접 설치하고, 그 뒤에 Argo CD를 이용해서 메트릭 서버를 설치합니다. 메트릭 서버는 쿠버네티스 공식 앱으로, 쿠버네티스의 노드와 파드 같은 리소스의 현재 사용량을 모니터링하는 필수 앱 입니다.
그럼 먼저 Argo CD를 설치하겠습니다. 연습용이므로 퀵스타트로 설치하겠습니다.
Argo CD 공식 리포지토리의 manifest를 이용하여 설치하겠습니다.
kubectl create ns argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/refs/heads/master/manifests/install.yaml
위 명령어를 실행하면 다음과 같이 리소스가 생성됩니다.
그리고 argocd 네임스페이스의 파드목록을 확인합니다.
kubectl get pod -n argocd
다음 명령어로 Argo 서버의 서비스를 32000 노트포트로 개방합니다.
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort", "ports": [{"port": 443, "nodePort": 32000, "targetPort": 8080}]}}'
이제 브라우저에서 http://localhost:32000 으로 접속하거나 (보안 경고 무시), 터미널에서 `curl http://localhost:3200` 명령어로 서버 응답을 확인해봅니다.
퀵스타트로 설치한 경우 로그인을 위해서는 `admin` 이라는 계정의 비밀번호를 알아야합니다. 다음 명령어로 비밀번호를 알 수 있습니다. 이 비밀번호로 접속하면 클러스터 관리자 (cluster-admin) 권한으로 Argo CD를 사용할 수 있습니다.
# 윈도우의 경우 base64 명령어가 없을 수 있습니다. wsl을 이용하는 것을 권장합니다.
kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 --decode
터미널에서 argocd 컨트롤러를 직접 제어하는 방법은 argocd-cli를 설치하는 것 입니다. 설치법은 이곳을 참고해 주세요. 설치가 되었다면, 다음 명령어로 로그인 합니다.
argocd login localhost:32000 --grpc-web --insecure
# Username: admin
# Password: <위에서 kubectl get secret으로 얻은 값, 마지막의 '%'는 제외>
그리고 다음 명령어로 앱, 프로젝트 목록을 확인합니다. 앱 목록이 비어있고, 프로젝트는 `default` 만 존재하면 됩니다.
argocd app list
# NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET
# <빈 목록이 나와야합니다>
argocd proj list
# NAME DESCRIPTION DESTINATIONS SOURCES CLUSTER-RESOURCE-WHITELIST NAMESPACE-RESOURCE-BLACKLIST SIGNATURE-KEYS ORPHANED-RESOURCES DESTINATION-SERVICE-ACCOUNTS
# default *,* * */* <none> <none> disabled <none>
여기까지 잘 진행된다면, 쿠버네티스와 Argo CD 준비가 끝났습니다.
🧑💻 Argo App으로 매트릭 서버 배포하기
이제 Argo CD의 사용자 리소스 정의(CRD, Custom Resource Definition)를 이용해 쿠버네티스 매트릭 서버를 배포해보겠습니다. 매트릭 서버의 공식 사이트는 이 링크 입니다.
그리고 시스템 리소스로 구분하여 배포하기 위해서 `system` 이라는 신규 프로젝트를 생성하겠습니다. 다음 명령어로 제약이 없는 프로젝트를 생성하겠습니다.
argocd proj create system -d "*,*" -s "*" --allow-cluster-resource "*/*"
argocd proj list
위 명령어의 결과로 프로젝트 목록을 확인할 수 있습니다.
이제 메트릭 서버를 위한 Argo CD 어플리케이션 리소스를 생성하겠습니다. 리소스에 반영할 메트릭 서버의 헬름 차트는 이 링크에서 참고해주세요. 다음 YAML 파일을 생성하여 저장하시면 됩니다.
# metrics-server.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: metrics-server
spec:
project: system # 새로 만든 프로젝트입니다
source:
repoURL: https://kubernetes-sigs.github.io/metrics-server
targetRevision: "3.12.2"
chart: metrics-server
helm:
valuesObject:
args:
- --metric-resolution=30s # 기본값 15s, 예시를 위해 설정했습니다.
destination:
server: https://kubernetes.default.svc
namespace: kube-system
syncPolicy:
automated: {} # 자동 동기화
커스텀 배포를 위한 helm values 설정은 헬름 차트 사이트를 참고하시면 됩니다.
그리고 다음 명령어로 쿠버네티스에 등록합니다.
kubectl apply -n argocd -f metrics-server.yaml
# 1분 정도 지나면 'HEALTH=Healthy'가 됩니다.
argocd app list
브라우저에서 Argo CD 서버에 접속하면 다음과 같이 나옵니다. Status의 Heath와 Sync에 모두 초록색 아이콘이 있는 것이 정상입니다.
여기까지 진행이 되었다면 다음 명령어로 리소스 사용량을 파악할 수 있습니다.
kubectl top pods -A
# metrics-server가 없다면 위 명령어를 쓸 수 없습니다.
여기까지 진행하셨다면, 내가 원하는 앱의 공식 핼름 차트를 Argo CD에서 배포하여 쿠버네티스에 설치하고, 사용(kubectl top) 할 수 있습니다.
이 과정에서 앱의 YAML 리소스는 개발자의 로컬에 있었습니다. `kubectl apply -n argocd -f metrics-server.yaml` 로 로컬에 있는 파일을 리소스로 등록했습니다. 이 다음 단계는 git에 저장된 YAML을 Argo CD의 기능으로 간접 배포하는 것 입니다. 관리해야 할 git 리포지토리가 생기는 대신, 동료 개발자 모두 git을 보면서 리소스 리뷰를 할 수 있습니다. 업무 문서에 직접 인용할 수 도 있으니 업무에도 도움이 될 거에요!
그럼 커피 한 잔 하시고 다음 섹션에서 뵙겠습니다 ☕️
📝 GitOps 리포지토리 설정하기
이제 Argo Application 리소스를 저장할 Git 리포지토리를 생성하겠습니다. 이 블로그에서는 GitHub 리포지토리에 저장하겠습니다. 여러분은 주로 사용하시는 git 플랫폼(GitHub, Bitbucket, GitLab 등)에 설정하시면 됩니다.
다음과 같이 리포지토리를 설정하였습니다.
- GitHub 리포지토리 주소: https://github.com/jyje/pilot-gitops-argocd
- 리포지토리 공개여부: 공개
리포지토리는 다음과 같은 파일/폴더 구조를 가집니다:
.
├── LICENSE
├── README.md
└── clusters # 클러스터 집합 폴더
└── jyje # 클러스터 이름
├── apps # Argo CD로 설치할 앱 집합
│ ├── metrics-server.yaml
│ ├── ... # 추가로 더 구성해도 됩니다
│ └── ...
└── apps.yaml # (중요) apps 폴더를 배포하는 앱
그리고 각 YAML 파일은 다음과 같습니다.
metrics-server.yaml
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: metrics-server
spec:
project: system # 새로 만든 프로젝트 입니다
source:
repoURL: https://kubernetes-sigs.github.io/metrics-server
targetRevision: "3.12.2"
chart: metrics-server
helm:
valuesObject:
args:
- --metric-resolution=30s
destination:
server: https://kubernetes.default.svc
namespace: kube-system
syncPolicy:
automated: {}
apps.yaml
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: apps
namespace: argocd # Argo CD가 설치된 네임스페이스
spec:
project: default # 기본 프로젝트
source:
repoURL: https://github.com/jyje/pilot-gitops-argocd
targetRevision: main
path: clusters/jyje/apps
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: argocd # Argo CD가 설치된 네임스페이스
syncPolicy:
automated: {}
---
# 프로젝트를 별도로 선언할 수 있습니다. 추가 프로젝트를 사용하지 않을 경우 생략합니다.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: system # 새로 만든 프로젝트 입니다
spec:
clusterResourceWhitelist:
- group: '*'
kind: '*'
destinations:
- namespace: '*'
server: 'https://kubernetes.default.svc'
sourceRepos:
- '*'
위 파일들로 앱을 배포하는 흐름은 다음과 같습니다.
Argo CD 설치 → apps.yaml 직접 배포 → `clusters/jyje/apps` 폴더 모니터링 → {metrics-server.yaml, ...} 간접 배포
이 때 `apps.yaml`의 역할은 리소스를 배포하는 것이 아닌, 특정 폴더를 배포합니다. 그럼 Argo CD는 그 폴더를 모니터링하여 하위 앱들을 모두 배포합니다. 이런 식으로 apps.yaml에 의해 간접적으로 배포된 하위 앱들이 각자의 리소스를 배포하게 됩니다. 이를 App of Apps 패턴이라 부릅니다.
자세한 내용은 다음 섹션에서 계속 소개하겠습니다.
🧑💻 App of Apps 패턴으로 매트릭 서버 배포하기
이전 섹션에서 생성한 git 리포지토리를 이용해 매트릭 서버를 배포해 보겠습니다. 배포하기 전에 아까 배포했었던 metrics-server를 삭제하겠습니다.
argocd app delete metrics-server
argocd app list
리스트에서 매트릭 서버가 삭제된 것을 확인하고 계속 진행합니다.
YAML 파일을 얻기 위해 git의 apps.yaml 주소를 가져옵니다. 그리고 Argo CD 가 설치된 클러스터에 다음 리소스를 배포합니다.
kubectl create -n argocd -f https://raw.githubusercontent.com/jyje/pilot-gitops-argocd/refs/heads/main/clusters/jyje/apps.yaml
# 30초 뒤
argocd app list
결과는 다음과 같습니다.
좀 더 편하게 구조를 보기 위해 브라우저에서 확인해보겠습니다.
모든 앱 목록입니다:
상위 앱인 apps와 하위 앱인 metric-server가 함께 있습니다. 저는 이를 구분하기 위해 `system` 이라는 프로젝트를 만들어 하위 앱에 적용했습니다.
상위앱인 apps를 살펴보겠습니다:
파드나 서비스같은 쿠버네티스 리소스가 아닌 apps 폴더에 있는 하위 앱을 배포하고 있습니다. 저 metrics-server 앱도 Argo CD Application 이라는 CRD이기 때문에 쿠버네티스 리소스입니다. 현재는 하위 앱이 1개 뿐입니다. git에 앱을 추가하고 5분 정도 기다리면 Argo CD가 git을 모니터링하여 추가된 리소스도 함께 배포합니다.
하위앱인 metrics-server를 살펴본 모습입니다.
이전 섹션에서 배포한 것과 동일하게 배포할 수 있습니다. 이로써 얻는 장점은, 앞으로 kubectl 명령을 입력할 필요없이 git 리포지토리에 PR로 리소스를 등록하면 신규 앱을 배포할 수 있다는 겁니다.
혼자서 인프라 및 워크로드를 관리하기 부담스러웠다면, Argo CD 기반의 GitOps를 구현하시면 됩니다. 그리고 모두에게 PR을 보내어 합의된 쿠버네티스 관리를 하실 수 있습니다 🚀
🐙 GitOps 응용하기
마무리 단계인데요. 그럼 만약 app 폴더에 Argo CD 앱이 들어있으면 어떻게 될까요? 그럼 Argo CD는 스스로를 재배포하게 됩니다. 이 경우 CRD와 권한의 호환성에 문제가 없다면 정상적으로 배포할 수 있습니다. Argo CD 설정 변경도 GitOps로 할 수 있습니다. 하지만 이 과정에서 Argo CD 컨트롤러에 문제가 생긴다면, 모든 동기화에 문제가 생길 수 있습니다. 따라서 Argo CD까지 GitOps로 관리하는 것은 팀원들의 합의를 통해 신중히 고르셔야 합니다.
비슷한 고민을 하신 분들의 링크도 함께 공유드립니다.
어렵다고 합니다... 그래서 다음 포스팅은 App of Apps 패턴으로 Argo CD 배포하기 입니다.
그리고 리포지토리에 직접 차트를 내려받아서 배포하는'Argo CD로 커스텀 차트 배포하기'도 포스팅 할 예정입니다. 읽어주셔서 감사합니다.
📝 다음 포스팅
- GitOps#2: Argo CD로 커스텀 차트 배포하기
- GitOps#3: App of Apps 패턴으로 Argo CD 배포하기
'DevOps' 카테고리의 다른 글
🍩 호머(Homer)#2: 호머로 만든 쿠버네티스 네이티브 대시보드를 소개합니다 (0) | 2024.11.26 |
---|---|
🐙 GitOps#2: Argo CD와 Git으로 커스텀 차트 배포하기 (1) | 2024.11.25 |
📝 k8s+STDIN: 쿠버네티스에서 YAML 파일 없이 리소스 생성하기 (0) | 2024.11.12 |
🐶 k9s: 쿠버네티스 클러스터 관리를 위한 커맨드라인 UI 도구를 소개합니다 (1) | 2024.11.10 |
☸️ 로컬 쿠버네티스: 연습용 쿠버네티스 클러스터 사용법을 소개합니다 (1) | 2024.11.09 |
어제보다 오늘 더 공부 잘하는 코딩냥이. 어제보다 오늘 더 일 잘하는 코딩냥이.
포스팅이 좋았다면, 오류를 발견했다면, 더 좋은 아이디어가 있다면 댓글 부탁드립니다!