Ssoon
Argo CD in Practice – 3) Argo CD 운영 : 가시성 활성화 본문
🔍 Enabling Observability – Argo CD 모니터링
- 잘못된 설정, 오래된 버전, immutable 필드 업데이트 시도, 대규모 동기화, SSH 키 누락, 혹은 대형 애플리케이션으로 인한 timeout 문제 등이 발생할 수 있습니다. 이럴 때 필요한 것이 바로 Observability(가시성) 입니다.
- Observability는 시스템의 상태(health), 성능(performance), 그리고 행동(behavior) 을 이해하는 능력을 제공합니다.
📈 Observability의 핵심 – Argo CD Metrics
- 다행히 Argo CD는 다양한 metrics를 Prometheus 형식으로 제공합니다.
- 이를 통해 시스템이 **과부하(Overutilized)**인지 **저활용(Underutilized)**인지 파악할 수 있고, 문제가 발생했을 때 특정 애플리케이션 담당 팀에게 **알림(Alert)**을 보낼 수도 있습니다.
- Argo CD의 모니터링과 알림은 두 방향으로 구분할 수 있습니다:
- 운영팀(Operating Team) – Argo CD 자체를 운영 및 유지보수하는 팀
- 마이크로서비스팀(Microservices Teams) – 각 애플리케이션을 개발하고 배포하는 팀
"Observability는 문제를 사전에 감지하고, 복잡한 환경에서 신속하게 대응할 수 있도록 돕는 운영의 핵심 요소다."
🧠 Monitoring with Prometheus
- Prometheus는 Kubernetes와 더불어 클라우드 네이티브 모니터링의 표준으로 자리 잡았습니다.
Kubernetes가 CNCF 첫 번째 프로젝트였다면, Prometheus는 두 번째로 CNCF에 합류한 프로젝트입니다.
🛠️ kube-prometheus-stack 설치
- Helm 저장소 prometheus-community 추가
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
"prometheus-community" has been added to your repositories
- 파라미터 파일 생성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ cat <<EOT > monitor-values.yaml
prometheus:
prometheusSpec:
scrapeInterval: "15s"
evaluationInterval: "15s"
service:
type: NodePort
nodePort: 30002
grafana:
defaultDashboardsTimezone: Asia/Seoul
adminPassword: prom-operator
service:
type: NodePort
nodePort: 30003
alertmanager:
enabled: false
defaultRules:
create: false
prometheus-windows-exporter:
prometheus:
monitor:
enabled: false
EOT
⚙️ 주요 설정 내용
- Prometheus (프로메테우스)
- 수집 주기: 15초마다 메트릭을 수집(scrapeInterval)하고, 15초마다 알림 규칙을 평가(evaluationInterval)합니다.
- 접속 방식: Prometheus 서비스에 외부에서 접속할 수 있도록 NodePort 타입을 사용하고, 포트 번호를 30002로 고정합니다.
- Grafana (그라파나)
- 시간대: 대시보드의 기본 시간대를 **'Asia/Seoul' (서울)**로 설정합니다.
- 비밀번호: 관리자(admin) 계정의 비밀번호를 **'prom-operator'**로 설정합니다.
- 접속 방식: Grafana 서비스에 외부에서 접속할 수 있도록 NodePort 타입을 사용하고, 포트 번호를 30003으로 고정합니다.
- 비활성화하는 기능들
- Alertmanager: 알림(Alert)을 관리하는 alertmanager 컴포넌트를 비활성화합니다 (enabled: false).
- 기본 규칙: 차트에 포함된 기본 알림 규칙(defaultRules)을 생성하지 않습니다 (create: false).
- Windows Exporter: Windows 노드 모니터링(prometheus-windows-exporter) 관련 기능도 비활성화합니다.
- 배포
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 75.15.1 \
-f monitor-values.yaml --create-namespace --namespace monitoring
NAME: kube-prometheus-stack
LAST DEPLOYED: Sat Nov 8 17:48:44 2025
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
NOTES:
kube-prometheus-stack has been installed. Check its status by running:
kubectl --namespace monitoring get pods -l "release=kube-prometheus-stack"
Get Grafana 'admin' user password by running:
kubectl --namespace monitoring get secrets kube-prometheus-stack-grafana -o jsonpath="{.data.admin-password}" | base64 -d ; echo
Access Grafana local instance:
export POD_NAME=$(kubectl --namespace monitoring get pod -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=kube-prometheus-stack" -oname)
kubectl --namespace monitoring port-forward $POD_NAME 3000
Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.
- kube-prometheus-stack: 릴리스 이름입니다. Helm을 통해 설치된 리소스들을 이 이름으로 관리합니다.
- prometheus-community/kube-prometheus-stack: 설치할 Helm 차트입니다. Prometheus, Grafana, Alertmanager 등을 포함한 통합 모니터링 스택입니다.
- --version 75.15.1: 특정 버전의 차트를 설치합니다. 안정성과 호환성을 위해 명시한 것으로 보입니다.
- -f monitor-values.yaml: 사용자 정의 설정 파일을 적용합니다. 앞서 작성한 설정이 여기에 포함됩니다.
- --create-namespace: 지정한 네임스페이스(monitoring)가 없으면 자동으로 생성합니다.
- --namespace monitoring: 리소스를 설치할 네임스페이스입니다.

🛠️ Argo CD 구성요소에 대한 ServiceMonitor 생성
- 테스트용 파드
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
EOF
pod/nginx created
- ServiceMonitor 생성
- Prometheus가 Argo CD의 메트릭을 수집하도록 설정하는 '규칙'을 생성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-metrics
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-metrics
endpoints:
- port: metrics
namespaceSelector:
matchNames:
- argocd
EOF
servicemonitor.monitoring.coreos.com/argocd-metrics created
- ServiceMonitor 생성
- argocd-server-metrics 라는 또 다른 서비스를 Prometheus가 모니터링하도록 추가
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-server-metrics
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-server-metrics
endpoints:
- port: metrics
namespaceSelector:
matchNames:
- argocd
EOF
servicemonitor.monitoring.coreos.com/argocd-server-metrics created
- ServiceMonitor 생성
- Prometheus가 Argo CD의 repo-server 컴포넌트에서 메트릭을 수집할 수 있도록 설정
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-repo-server-metrics
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-repo-server
endpoints:
- port: metrics
namespaceSelector:
matchNames:
- argocd
EOF
servicemonitor.monitoring.coreos.com/argocd-repo-server-metrics created
- ServiceMonitor 생성
- ApplicationSet 컨트롤러, Dex 인증 서버, HA Redis 프록시, 그리고 알림 컨트롤러까지 모두 모니터링 하도록 설정
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-applicationset-controller-metrics
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-applicationset-controller
endpoints:
- port: metrics
namespaceSelector:
matchNames:
- argocd
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-dex-server
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-dex-server
endpoints:
- port: metrics
namespaceSelector:
matchNames:
- argocd
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-redis-haproxy-metrics
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-redis-ha-haproxy
endpoints:
- port: http-exporter-port
EOF - argocd:ctor:.io/name: argocd-notifications-controller-metrics
servicemonitor.monitoring.coreos.com/argocd-applicationset-controller-metrics created
servicemonitor.monitoring.coreos.com/argocd-dex-server created
servicemonitor.monitoring.coreos.com/argocd-redis-haproxy-metrics created
servicemonitor.monitoring.coreos.com/argocd-notifications-controller created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ kubectl get servicemonitors -n monitoring | grep argocd
argocd-applicationset-controller-metrics 31s
argocd-dex-server 31s
argocd-metrics 4m35s
argocd-notifications-controller 31s
argocd-redis-haproxy-metrics 31s
argocd-repo-server-metrics 102s
argocd-server-metrics 2m56s

- argo.. 관련 메트릭 확인

"Prometheus Operator를 사용하면 Argo CD의 모든 주요 컴포넌트에서 metrics를 자동으로 수집할 수 있다."
📊 Grafana 대시보드로 시각화하기
- Prometheus가 metrics를 수집하기 시작하면, Grafana Dashboard를 통해 시각화할 수 있습니다.
- Argo CD 공식 문서에서는 예시 대시보드를 제공합니다:📎 Argo CD Metrics Dashboard
- 또한 Grafana의 공식 문서를 참고해 대시보드 import를 수행하면 됩니다. 📎 Grafana Import Dashboard Guide
"Grafana는 Prometheus에서 수집한 데이터를 직관적으로 시각화해 운영자가 즉시 이상 징후를 파악할 수 있게 돕는다."
그라파나 대시보드 추가 후 확인
✅ Grafana 로그인 정보
- Username: admin
- Password: prom-operator
https://github.com/argoproj/argo-cd/blob/master/examples/dashboard.json



⚙️ Metrics for the Operating Team
- 운영팀은 Argo CD의 **핵심 컴포넌트(Repo Server, Controller)**의 상태를 모니터링해야 합니다.
이 컴포넌트들이 원활하게 작동해야 전체 시스템의 성능이 유지되기 때문입니다.
🚨 OOMKilled 감지
- 가장 중요한 metric 중 하나는 Argo CD 자체 metric이 아닌, OOMKilled 이벤트입니다.
이는 노드의 OS가 메모리 초과로 인해 컨테이너를 강제 종료시킬 때 발생합니다. - 다음 Prometheus 쿼리는 최근 5분 이내 OOMKilled된 컨테이너를 감지합니다:
sum by (pod, container, namespace) (
kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}
)
* on (pod,container) group_left
sum by (pod, container) (
changes(kube_pod_container_status_restarts_total[5m])
) > 0
- 이 알림이 일주일에 몇 번 정도면 괜찮지만, 하루에 여러 번 발생한다면 조치가 필요합니다.
- 대응 방안은 다음과 같습니다:
- Deployment/StatefulSet의 replicas 수 증가 → 부하 분산
- 컨테이너의 CPU/Memory 자원 상향 조정
- 병렬 처리 제한 파라미터 조정
- Repo Server: --parallelismlimit
- Controller: --kubectl-parallelism-limit
"OOMKilled는 자원 부족이나 과도한 병렬 작업의 신호이며, 시스템 조정을 통해 해결할 수 있다."
⚡ System Load Metrics
- 시스템의 부하 상태를 파악하기 위한 대표적인 metric은 두 가지입니다.
🧩 Repo Server 부하 지표
- Repo Server는 Git 리포지토리에서 내용을 가져와 템플릿을 렌더링합니다.
이때 대기 중인 요청 수를 나타내는 metric은 다음과 같습니다:
argocd_repo_pending_request_total
- 이 수치는 가능한 한 0에 가까워야 합니다.
단기간 증가하는 것은 괜찮지만, 지속적으로 높은 수치를 보인다면 성능 문제가 있을 수 있습니다.
참고: HPA를 통한 자동 스케일링은 간단하지 않으므로 관련 논의는 이슈 #2559를 참고하세요.
🧠 Application Controller 부하 지표
- Application Controller는 apply 및 auth 명령을 실행합니다.
현재 대기 중인 명령의 수는 아래 metric으로 확인할 수 있습니다:
argocd_kubectl_exec_pending
- 이 값이 --kubectl-parallelism-limit 설정값과 같거나 높은 상태가 오랫동안 지속되면 동기화 지연 문제가 발생할 수 있습니다.
"부하 지표는 시스템의 병목을 조기에 감지해 성능 저하를 예방할 수 있는 중요한 신호다."
👩💻 Metrics for Microservices Teams
- 플랫폼 팀이 개발팀에게 셀프서비스 환경을 제공하려면, 각 개발팀도 자신들의 Argo CD Application 상태를 모니터링하고
문제 발생 시 직접 알림을 받을 수 있어야 합니다. - 대표적인 두 가지 metric은 다음과 같습니다:
- Application Synchronization Status
- Application Health Status
🔁 Application Synchronization Status
- 이 metric은 애플리케이션의 동기화 실패 여부를 감지합니다.
다음 쿼리는 최근 5분 내 Failed 상태로 변경된 Application을 찾아냅니다.
sum by (name) (
changes(argocd_app_sync_total{
phase="Failed",
exported_namespace="argocd",
name=~"accounting.*"
}[5m])
) > 0
- 이 쿼리는 argocd 네임스페이스 내에서 이름이 accounting으로 시작하는 애플리케이션만 필터링합니다.
"동기화 실패 알림을 통해 개발팀은 배포 실패를 즉시 인지하고 빠르게 대응할 수 있다."
❤️ Application Health Status
- 이 metric은 **애플리케이션이 비정상 상태(Degraded)**인지 여부를 추적합니다. 이는 동기화 이벤트와 별개로 발생할 수 있습니다.
- 예를 들어, 3개의 replica를 요청했지만 2개만 실행 중이라면 Degraded 상태로 표시됩니다.
- 다음 쿼리는 argocd 네임스페이스에서 이름이 prod로 시작하고 app으로 끝나지 않는 애플리케이션 중 Degraded 상태인 것을 감지합니다:
argocd_app_info{
health_status="Degraded",
exported_namespace="argocd",
name=~"prod.*",
name!~".*app"
}
"Degraded 상태는 프로덕션 환경에서 성능 저하나 장애를 의미하므로 즉시 점검이 필요하다."
📌 핵심 요약
- Observability는 복잡한 Kubernetes 환경에서 시스템의 상태를 명확히 파악하기 위한 필수 요소
- Prometheus Operator로 Argo CD의 metrics를 손쉽게 수집
- ServiceMonitor를 통해 Application Controller, API Server, Repo Server의 데이터를 모니터링
- Grafana Dashboard로 시각화하여 실시간으로 상태 확인
- 운영팀은 OOMKilled, Repo Load, Controller Load 지표를 주로 모니터링
- 개발팀은 Sync Status와 Health Status를 기반으로 배포 안정성을 확인
- 마지막으로 Argo CD Notifications를 통해 자동 알림을 설정하면 완벽한 모니터링 체계 구축 가능
"모니터링은 단순한 데이터 수집이 아니라, 빠른 문제 인지와 지속 가능한 운영을 위한 전략적 도구다."
'CICD Study [1기]' 카테고리의 다른 글
| Argo CD in Practice – 4) 접근 제어 : 서비스 계정 (0) | 2025.10.19 |
|---|---|
| Argo CD in Practice – 4) 접근 제어 : 선언적 사용자 (0) | 2025.10.19 |
| Argo CD in Practice – 3) Argo CD 운영 : 재해 복구 계획 수립 (0) | 2025.10.19 |
| Argo CD in Practice – 3) Argo CD 운영 : 고가용성(HA) 설치 구성 (0) | 2025.10.19 |
| Argo CD in Practice – 2) Argo CD 시작하기 (0) | 2025.10.19 |
Comments