[DevOps] ArgoCD를 활용한 GitOps
지난 글에 이어 CloudNet@의 CI/CD 스터디를 진행한 내용을 담고 있습니다.
Argo CD: GitOps 기반 Kubernetes 배포의 완성형 솔루션
Argo CD는 Kubernetes 환경에서 GitOps 패턴을 구현하는 선언적, 지속적 배포 도구입니다. 애플리케이션의 정의, 구성, 환경이 Git에 버전 관리되고 이를 기반으로 자동화된 배포와 라이프사이클 관리를 제공합니다. 이 글에서는 Argo CD의 핵심 구성 요소와 기능, 그리고 이를 활용해 Kubernetes 애플리케이션을 효과적으로 관리하는 방법을 살펴봅니다.
Argo CD의 주요 개념과 작동 방식
Argo CD는 Git 저장소를 기준으로 Kubernetes 클러스터 상태를 관리합니다. GitOps 철학에 따라 애플리케이션 상태를 선언적으로 정의하며, 이를 다양한 형식으로 지원합니다.
- 지원 애플리케이션 형식
Argo CD 아키텍처
Argo CD는 주요 구성 요소를 통해 Git과 Kubernetes 간의 배포 자동화를 관리합니다.
- API 서버
- 역할: Web UI, CLI, CI/CD 시스템과 상호작용하는 REST/gRPC 서버
- 주요 기능:
- 애플리케이션 관리 및 상태 보고
- 애플리케이션 동기화, 롤백 등 작업 수행
- Git 웹훅 이벤트 처리
- 외부 인증 시스템 연계 (SSO 지원)
- RBAC(역할 기반 접근 제어) 정책 적용
- Repository 서버
- 역할: Git 저장소와 연결하여 배포를 위한 Kubernetes 매니페스트 생성
- 주요 기능:
- Git 저장소 URL, 브랜치, 경로, Helm 매개변수 등을 기반으로 매니페스트 생성
- 로컬 Git 캐싱으로 성능 최적화
- Application Controller
- 역할: Kubernetes 리소스를 모니터링하고 Git 상태와 비교
- 주요 기능:
- OutOfSync 상태 탐지 및 동기화 작업 수행
- PreSync, Sync, PostSync 후크를 통한 복잡한 배포 관리
- Redis
- 역할: Kubernetes API와 Git 요청을 캐싱하여 성능 개선
- Notification
- 역할: 이벤트 알림 및 사용자 정의 트리거 제공
- Dex
- 역할: OIDC, LDAP, SAML 2.0 등 외부 인증 관리
- ApplicationSet Controller
- 역할: 멀티 클러스터 배포를 위한 애플리케이션 패키징 관리
Argo CD의 주요 기능
Argo CD는 강력한 배포 기능과 사용자 경험을 제공합니다.
- 자동화된 애플리케이션 배포
- Git 상태를 기준으로 Kubernetes 클러스터를 동기화
- Drift Detection: 실시간 상태 비교 및 차이점 시각화
- 헬스 체크 및 상태 분석
- 다양한 구성 관리 도구 지원
- Kustomize, Helm, Jsonnet, YAML 등
- 보안 및 인증
- SSO 통합: GitHub, GitLab, LDAP, Microsoft 등
- RBAC 정책: 멀티 테넌시 환경 지원
- 다양한 배포 전략
- Canary, Blue/Green 배포를 위한 PreSync, Sync, PostSync 후크 지원
- 기타 기능
- 실시간 Web UI 및 CLI 지원
- Webhook 연동 (GitHub, GitLab, BitBucket 등)
- Prometheus 메트릭 제공
- 감사 로그 및 배포 기록 추적
GitOps와 Argo CD의 장점
- 중앙 집중형 소스 관리
- Git을 기준으로 모든 애플리케이션 상태를 관리하므로 투명성과 추적 가능성이 향상됩니다.
- 자동화와 일관성
- 선언적 구성을 통해 배포 및 관리를 자동화하여 휴먼 에러를 줄이고 안정성을 확보합니다.
- 멀티 클러스터 지원
- 다양한 환경과 클러스터를 중앙에서 관리하며, 대규모 운영을 간소화합니다.
argocd 설치하기
1. 네임스페이스 생성
kubectl create ns argocd
2. 파라미터 파일 작성
cat <<EOF > argocd-values.yaml
dex:
enabled: false
server:
service:
type: NodePort
nodePortHttps: 30002
EOF
3. 설치 및 확인
# 설치
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 7.7.10 -f argocd-values.yaml --namespace argocd
# 확인
kubectl get pod,svc,ep -n argocd
kubectl get crd | grep argo
4. 암호 확인 / 브라우저 접속
# 최초 접속 암호 확인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
<암호>
# Argo CD 웹 접속 주소 확인 : 초기 암호 입력 (admin 계정)
open "https://127.0.0.1:30002" # macOS
5. argoCD를 활용한 배포
- Helm Chart 디렉토리 설정
mkdir nginx-chart
cd nginx-chart
mkdir templates
2. Configmap 생성
cat > templates/configmap.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}
data:
index.html: |
{{ .Values.indexHtml | indent 4 }}
EOF
3. Deployment 생성
cat > templates/deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- name: nginx
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
ports:
- containerPort: 80
volumeMounts:
- name: index-html
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
volumes:
- name: index-html
configMap:
name: {{ .Release.Name }}
EOF
4. Service 생성
cat > templates/service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
spec:
selector:
app: {{ .Release.Name }}
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30000
type: NodePort
EOF
5. values.yaml
cat > values.yaml <<EOF
indexHtml: |
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Nginx!</title>
</head>
<body>
<h1>Hello, Kubernetes!</h1>
<p>Nginx version 1.26.1</p>
</body>
</html>
image:
repository: nginx
tag: 1.26.1
replicaCount: 1
EOF
6. Chart.yaml 생성
cat > Chart.yaml <<EOF
apiVersion: v2
name: nginx-chart
description: A Helm chart for deploying Nginx with custom index.html
type: application
version: 1.0.0
appVersion: "1.26.1"
EOF
7. helm 차트 배포
# 이전 배포 삭제
kubectl delete deploy,svc --all
# Nginx 배포
helm install dev-nginx . -f values.yaml
8. 배포 확인
# Helm 배포 상태 확인
helm list
# 배포된 리소스 확인
kubectl get deploy,svc,ep,cm dev-nginx -owide
9. 서비스 접속 확인
# Nginx 서비스 확인
curl http://127.0.0.1:30000
curl -s http://127.0.0.1:30000 | grep version
open http://127.0.0.1:30000
Repo(ops-deploy) 에 nginx helm chart 를 Argo CD를 통한 배포 진행하기
다음과 같이 argoCD를 활용해 nginx helm 차트를 배포해 봅니다.
1. Git 저장소 클론 및 초기 설정
cd ~/cicd-labs
git clone http://192.168.254.124:3000/devops/ops-deploy.git
cd ops-deploy
# 사용자 설정
git config user.name "devops"
git config user.email "zitrocy@gmail.com"
git config init.defaultBranch main
git config credential.helper store
2. Helm Chart 디렉토리 및 파일 생성
VERSION=1.26.1
mkdir nginx-chart
mkdir nginx-chart/templates
3. ConfigMap 템플릿
cat > nginx-chart/templates/configmap.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}
data:
index.html: |
{{ .Values.indexHtml | indent 4 }}
EOF
4. Deployment 템플릿
cat > nginx-chart/templates/deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- name: nginx
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
ports:
- containerPort: 80
volumeMounts:
- name: index-html
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
volumes:
- name: index-html
configMap:
name: {{ .Release.Name }}
EOF
5. Service 템플릿
cat > nginx-chart/templates/service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
spec:
selector:
app: {{ .Release.Name }}
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30000
type: NodePort
EOF
6. values-dev.yaml & values-prd.yaml
# values-dev.yaml
cat > nginx-chart/values-dev.yaml <<EOF
indexHtml: |
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Nginx!</title>
</head>
<body>
<h1>Hello, Kubernetes!</h1>
<p>DEV : Nginx version $VERSION</p>
</body>
</html>
image:
repository: nginx
tag: $VERSION
replicaCount: 1
EOF
# values-prd.yaml
cat > nginx-chart/values-prd.yaml <<EOF
indexHtml: |
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Nginx!</title>
</head>
<body>
<h1>Hello, Kubernetes!</h1>
<p>PRD : Nginx version $VERSION</p>
</body>
</html>
image:
repository: nginx
tag: $VERSION
replicaCount: 2
EOF
7. Chart.yaml
cat > nginx-chart/Chart.yaml <<EOF
apiVersion: v2
name: nginx-chart
description: A Helm chart for deploying Nginx with custom index.html
type: application
version: 1.0.0
appVersion: "$VERSION"
EOF
8. Git 커밋 및 푸시
git status && git add . && git commit -m "Add nginx helm chart" && git push -u origin main