Helm chart는 Kubernetes 리소스를 재사용 가능한 패키지와 템플릿으로 묶어 배포할 수 있게 해주는 방식이다. values 파일만 바꿔도 같은 chart에서 환경별 manifest를 만들 수 있다.
Argo CD는 Git repository에 선언된 애플리케이션 상태를 Kubernetes cluster와 맞추는 GitOps controller다. 직접 kubectl apply를 반복하는 대신, Git에 원하는 상태를 남기고 Argo CD가 그 상태를 감시하고 sync한다.
GitOps는 이처럼 Git을 배포와 운영 상태의 기준점으로 삼는 방식이다. 변경 이력, 리뷰, rollback 기준이 Git에 남기 때문에 Kubernetes 운영 흐름을 더 추적하기 쉬워진다.
참고 문서:
이번 실습에서 만들 구조는 단순하다.
local machine
-> Helm CLI
-> argo/argo-cd Helm chart 설치
-> argocd namespace에 Argo CD 구성요소 생성
-> Argo CD Application 생성
-> Git repository 또는 Helm chart source 감시
-> target namespace에 앱 배포
핵심은 두 단계를 구분하는 것이다. 먼저 Helm으로 Argo CD 자체를 설치한다. 그다음 Argo CD가 애플리케이션을 배포하게 만든다.
먼저 로컬에 Helm이 설치되어 있는지 확인한다.
helm version
macOS에서는 Homebrew로 설치할 수 있다.
brew install helm
설치 후 다시 확인한다.
helm version
Argo CD Helm chart는 argo-helm repository에서 받을 수 있다.
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
설치 가능한 chart를 확인한다.
helm search repo argo/argo-cd
운영 등에서는 chart version을 고정하는 편이 좋다. version을 고정하지 않으면 나중에 같은 명령을 다시 실행했을 때 다른 manifest가 렌더링될 수 있다.
helm show chart argo/argo-cd --version <chart-version>
Argo CD는 보통 argocd namespace에 설치한다.
kubectl create namespace argocd
이미 namespace가 있다면 다음처럼 확인만 해도 된다.
kubectl get namespace argocd
이 글에서 namespace 이름은 argocd로 통일한다.
이제 argo/argo-cd chart를 설치한다.
helm install argocd argo/argo-cd \
--namespace argocd \
--version <chart-version> \
--values values-argocd.yaml
최소 실습이라면 values 파일 없이 시작할 수도 있다.
helm install argocd argo/argo-cd \
--namespace argocd \
--version <chart-version>
예를 들어 local lab에서는 server를 외부에 바로 노출하지 않고 ClusterIP로 둔다.
server:
service:
type: ClusterIP
민감한 repository credential, token, webhook secret, SSO secret은 values 파일에 평문으로 넣지 않는다. argo-cd Helm chart README도 민감 정보를 version control에 clear text로 넣지 않는 방식을 권장한다.
설치 후에는 Helm release와 Kubernetes 리소스를 같이 확인한다.
helm list -n argocd
kubectl get pod,svc -n argocd
여기서 보고 싶은 것은 Argo CD 구성요소가 생성됐고 Pod가 정상 상태로 올라오는지다.
argocd-application-controller
argocd-applicationset-controller
argocd-dex-server
argocd-notifications-controller
argocd-redis
argocd-repo-server
argocd-server
정확한 구성요소와 이름은 chart version과 values에 따라 달라질 수 있다.
문제가 생기면 Events와 Pod describe를 먼저 본다.
kubectl get events -n argocd --sort-by=.lastTimestamp
kubectl describe pod -n argocd <argocd-pod-name>
Argo CD가 설치되면 첫 애플리케이션을 배포한다. 가장 단순한 방법은 public Helm chart나 public Git repository를 source로 쓰는 것이다.
Helm chart 기반 Application 예시는 다음과 같다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx
namespace: argocd
spec:
project: default
source:
repoURL: https://charts.bitnami.com/bitnami
chart: nginx
targetRevision: <chart-version>
helm:
releaseName: nginx
valuesObject:
service:
type: ClusterIP
destination:
server: https://kubernetes.default.svc
namespace: nginx
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
적용한다.
kubectl apply -f application-nginx.yaml
Application 상태를 확인한다.
kubectl get application -n argocd
kubectl describe application nginx -n argocd
target namespace에 실제 리소스가 생겼는지도 본다.
kubectl get deploy,svc,pod -n nginx
Argo CD 문서 기준으로 Application은 source와 destination을 핵심으로 갖는다. source는 원하는 상태가 있는 위치이고, destination은 그 상태를 적용할 cluster와 namespace다.
여기까지 하면 “Argo CD 설치”는 끝난다. GitOps 실습으로 만들려면 Git 변경이 cluster 상태 변경으로 이어지는지 확인해야 한다.
가장 작은 흐름은 이렇다.
1. Application manifest 또는 Helm values를 Git repository에 둔다.
2. Argo CD가 해당 repository와 revision을 source로 보게 한다.
3. Git에서 values를 변경한다.
4. Argo CD가 OutOfSync 상태를 감지한다.
5. sync 후 cluster 리소스가 원하는 상태로 바뀌었는지 확인한다.
예를 들어 nginx chart의 replica 수나 Service type을 바꿔볼 수 있다.
source:
helm:
valuesObject:
replicaCount: 2
service:
type: ClusterIP
변경 후 확인할 evidence는 Argo CD 상태와 Kubernetes 리소스 상태다.
kubectl get application nginx -n argocd
kubectl describe application nginx -n argocd
kubectl get deploy,svc,pod -n nginx
Argo CD CLI를 쓴다면 diff와 sync도 확인한다.
argocd app diff nginx
argocd app sync nginx
argocd app get nginx
문제가 생겼을 때는 단계별로 나눠서 본다.
helm list -n argocd
helm status argocd -n argocd
kubectl get pod,svc -n argocd
kubectl get events -n argocd --sort-by=.lastTimestamp
kubectl get application -n argocd
kubectl describe application <app-name> -n argocd
kubectl get deploy,svc,pod -n <target-namespace>
kubectl get events -n <target-namespace> --sort-by=.lastTimestamp
helm template <release-name> <repo-or-chart> \
--version <chart-version> \
--values values.yaml
어느 단계에서 막혔는지 나누면 원인이 빨리 좁혀진다. Helm chart 설치 문제인지, Argo CD Application 문제인지, target namespace의 Kubernetes 리소스 문제인지 섞어 보지 않는 게 핵심이다.