Post

Argo CD with Kubernetes

Argo CD with Kubernetes

CloudNet@ Gasida님이 진행하는 CI/CD + ArgoCD + Vault Study를 진행하며 학습한 내용을 공유합니다.

이번 포스트에서는 Argo CD를 사용한 CD (Continuous Delivery) 과정에 대해 다루겠습니다.

실습 환경은 Jenkins + ArgoCD 실습 환경 구축의 실습 환경을 사용합니다.


1. Argo CD란?

Argo CD는 Kubernetes 환경에서 GitOps 방식으로 애플리케이션을 지속적으로 배포(Continuous Delivery) 하기 위한 선언적(Declarative) CD 도구입니다.

공식 정의를 한 줄로 정리하면 다음과 같습니다.

Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.

즉, 애플리케이션의 원하는 상태(Desired State) 를 Git 저장소에 선언적으로 정의해 두고, Argo CD가 Git을 기준으로 Kubernetes 클러스터의 실제 상태를 계속 맞춰 주는 도구입니다.


1.1. GitOps 관점에서 본 Argo CD

Argo CD는 GitOps 패턴에 따라 Git 저장소를 단일 진실 공급원(Single Source of Truth) 으로 사용합니다.

  • 애플리케이션 정의, 환경 설정, 인프라 구성은 모두 선언적(Declarative) 으로 작성합니다.
  • 이 선언적 구성은 반드시 버전 관리(Version controlled) 되어야 합니다.
  • 배포와 라이프사이클 관리는 자동화(Automated), 감사 가능(Auditable), 이해하기 쉬운(Understandable) 형태여야 합니다.

Argo CD는 이 원칙을 따르며, Git에 정의된 상태를 기준으로 클러스터를 자동으로 동기화합니다.


1.2. Kubernetes Manifest 정의 방식

Argo CD에서 사용할 Kubernetes Manifest 는 여러 방식으로 정의할 수 있습니다.

  • Kustomize
  • Helm Chart
  • Jsonnet
  • Plain YAML/JSON 디렉터리
  • 위 도구들을 래핑한 Custom Config Management Plugin

Argo CD는 위와 같은 도구들에 정의 된 내용을 기반으로 결과물(최종 Manifest)을 생성하고, 이를 기반으로 클러스터의 상태를 관리합니다.


2. Argo CD 아키텍처

공식 문서에서 표현하는 전체 구조를 간단히 요약하면 다음과 같이 볼 수 있습니다.

Git -> (DESIRED) Argo CD (LIVE) -> Kubernetes

  • Git
    원하는 상태(Desired State), 즉 애플리케이션과 인프라 구성이 선언적으로 정의되어 있음
  • Argo CD
    Git의 상태(Desired)와 클러스터의 실제 상태(Live)를 비교하고, 필요 시 동기화(Sync) 수행
  • Kubernetes
    실제로 애플리케이션이 실행되는 환경

Argo CD Architecture Overview

Argo CD Architecture Docs


2.1. 주요 컴포넌트

Argo CD는 여러 컴포넌트가 함께 동작하면서 GitOps CD 파이프라인을 구성합니다.

Argo CD Component Architecture

2.1.1. API Server

Web UI, CLI, CI/CD 시스템과 통신하는 gRPC / REST API 서버

주요 역할
  • 애플리케이션 생성, 조회, 상태 확인 등 Application 관리 및 상태 보고
  • Sync, Rollback, 사용자 정의 액션 등 애플리케이션 동작(Operation) 수행
  • Repository / Cluster 인증 정보 관리 (Kubernetes Secret에 저장)
  • 외부 Identity Provider와 연동한 인증(Authentication) / 권한 위임
  • RBAC 정책 적용
  • Git Webhook 이벤트 리스너 역할

실제로 사용자가 Web UI 혹은 argocd CLI로 수행하는 대부분의 요청은 API Server를 통해 처리됩니다.


2.1.2. Repository Server

Git 저장소와 연결돼 매니페스트를 생성해 주는 내부 서비스

주요 역할
  • Git 저장소를 로컬 캐시 형태로 유지
  • 다음 입력값을 기반으로 최종 Kubernetes Manifest 생성
    • Repository URL
    • Revision (commit, tag, branch)
    • Application path
    • 도구별 설정 (Helm values.yaml, Parameters 등)
  • Kustomize/Helm/Jsonnet 등 Config Management Tool을 실행해 최종 YAML 생성

즉, “Git에 정의된 소스 → 실제 적용 가능한 K8s Manifest”로 변환하는 역할을 합니다.


2.1.3. Application Controller

“Git과 클러스터 상태를 비교하고, OutOfSync를 감지 및 조정하는 컨트롤러”

주요 역할
  • Kubernetes 클러스터에 배포된 실제 상태(Live State) 를 지속적으로 모니터링
  • Git 저장소에 정의된 원하는 상태(Target/Desired State) 와 비교
  • 두 상태가 다를 경우 OutOfSync 상태로 표시
  • 설정에 따라:
    • 자동으로 Sync 수행 (자동 동기화)
    • 혹은 사용자 승인 후 수동 Sync만 수행
  • Sync 라이프사이클에 따라 다음 Hook 호출
    • PreSync, Sync, PostSync

즉, Application Controller는 GitOps에서 말하는 “폐쇄 루프(Closed Loop) 조정 로직” 을 담당하는 핵심 컴포넌트입니다.


2.1.4. 기타 컴포넌트

  • Redis
    • K8s API 및 Git 요청을 줄이기 위한 캐시 레이어
    • 빈번한 조회에 대한 성능 개선 역할
  • Notifications (Argo CD Notifications)
    • 특정 이벤트(예: Sync 실패, Health 상태 변경)를 Slack, Email 등으로 알림
    • GitOps 파이프라인의 이벤트를 팀에 빠르게 전달
  • Dex
    • OIDC 등 외부 인증 제공자(IdP)를 추상화하는 인증 프록시
    • GitHub, GitLab, OIDC, LDAP, SAML 2.0 등과의 SSO 연동에 사용
  • ApplicationSet Controller
    • 여러 클러스터 혹은 여러 애플리케이션을 템플릿 기반으로 한 번에 관리
    • 예: N개 클러스터에 동일 애플리케이션 배포, 클러스터 목록/ConfigMap/리포지토리 구조 등을 기반으로 Application들을 자동 생성

Argo CD Components Docs


3. Argo CD 주요 기능

Argo CD가 제공하는 주요 기능을 GitOps 관점에서 정리하면 다음과 같습니다.

  • 자동화된 애플리케이션 배포
    • 지정된 대상 환경(Target Cluster)으로 애플리케이션을 자동 배포
  • 다양한 Config Management 도구 지원
    • Kustomize, Helm, Jsonnet, Plain YAML 등 지원
  • 멀티 클러스터 관리
    • 하나의 Argo CD 인스턴스로 여러 Kubernetes 클러스터에 배포 및 관리 가능
  • SSO 통합
    • OIDC, OAuth2, LDAP, SAML 2.0, GitHub, GitLab, Microsoft, LinkedIn 등과 연동
  • 멀티 테넌시 및 RBAC
    • 팀·조직 단위 권한 분리를 위한 RBAC와 멀티 테넌시 지원
  • Rollback / Roll-anywhere
    • Git에 커밋된 어느 시점으로든 구성 롤백 가능
  • Health 상태 분석
    • 각 리소스의 Health 상태를 분석해 UI에서 시각화
  • Configuration Drift 감지 및 시각화
    • Git과 실제 클러스터 간 구성 차이를 자동 감지 및 표시
  • 자동 / 수동 Sync 모드 지원
    • 자동 동기화(자동 수정) 또는 수동 승인 후 동기화 선택 가능
  • Web UI 제공
    • 실시간 애플리케이션 상태, 이벤트, 리소스 구조를 시각적으로 확인 가능
  • CLI 제공
    • argocd CLI를 통한 자동화 및 CI 파이프라인 연동
  • Webhook 통합
    • GitHub, GitLab, Bitbucket 등 Git Webhook을 받아 즉각적인 Sync 트리거
  • Access Token 기반 자동화
    • Script/CI에서 사용 가능한 토큰 발급
  • Lifecycle Hook (PreSync, Sync, PostSync)
    • Blue-Green, Canary 등 복잡한 배포 전략 구현 가능
  • Audit Trail 제공
    • 애플리케이션 이벤트 및 API 호출 기록을 통해 감사(Audit) 가능
  • Prometheus Metrics
    • Prometheus 연동을 통한 모니터링 및 알림
  • Helm Parameter Override
    • Git 내 정의된 Helm 파라미터를 상황에 맞게 Override 가능

4. Argo CD 설치 및 기본 설정

Artifact Hub - Argo CD
Argo CD Docs - Getting Started

4.1. Argo CD 설치

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
##############################################################
# 디렉터리 생성 및 이동
##############################################################
mkdir cicd-labs
cd cicd-labs

##############################################################
# 네임스페이스 생성 및 파라미터 파일 작성
##############################################################
kubectl create ns argocd
cat <<EOF > argocd-values.yaml
dex:
  enabled: false

server:
  service:
    type: NodePort
    nodePortHttps: 30002
  extraArgs:
    - --insecure  # HTTPS 대신 HTTP 사용
EOF

##############################################################
# 설치 : Argo CD v3.1.9 , (참고) 책 버전 v2.10.5
##############################################################
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 9.0.5 -f argocd-values.yaml --namespace argocd

##############################################################
# 확인
##############################################################
kubectl get pod,svc,ep,secret,cm -n argocd
kubectl get crd | grep argo
# applications.argoproj.io                     2024-04-14T08:12:16Z
# applicationsets.argoproj.io                  2024-04-14T08:12:17Z
# appprojects.argoproj.io                      2024-04-14T08:12:16Z

kubectl get appproject -n argocd -o yaml

# configmap
kubectl get cm -n argocd argocd-cm -o yaml
kubectl get cm -n argocd argocd-rbac-cm -o yaml
# ...
# data:
#   policy.csv: ""
#   policy.default: ""
#   policy.matchMode: glob
#   scopes: '[groups]'

# 최초 접속 암호 확인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
# vIkG90xaTZ1u2p5I-kk

##############################################################
# Argo CD 웹 접속 주소 확인 : 초기 암호 입력 (admin 계정)
##############################################################
open "http://127.0.0.1:30002" # macOS
## Windows OS경우 직접 웹 브라우저에서 http://<Ubuntu Eth0 IP>:30002 접속

4.2. Argo CD 웹 접속 확인 및 admin 계정 암호 변경 (qwe12345)

4.2.1. 접속 확인

Argo CD Main

4.2.2. 계정 암호 변경

Argo CD Change Password

4.3. ops-deploy Repository 등록

Settings -> Repository -> CONNECT REPO 클릭

  • connection method : VIA HTTP/HTTPS
  • Type : git
  • Name (optional) : gogs
  • Project : default
  • Repo URL : http://***<자신의 IP>***:3000/devops/ops-deploy
  • Username : devops
  • Password : ******

입력 후 CONNECT 클릭

Argo CD Add Repository Argo CD Check Gogs Repository


5. Argo CD를 통해 Repository(ops-deploy)의 nginx helm chart 배포

5.1. Helm Chart 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
##############################################################
# Gogs 터미널 진입 (docker-compose.yaml 파일이 위치한 경로에서 실행)
##############################################################
docker compose exec --privileged -u root gogs bash

---

##############################################################
# 디렉터리 및 git 초기 세팅
##############################################################
cd /data

MyIP=172.28.8.232
TOKEN=48bf0caa1c0eeaf85eea28858c3dd472c16d9103
echo $MyIP $TOKEN

git clone http://devops:$TOKEN@$MyIP:3000/devops/ops-deploy.git
cd ops-deploy

#
git config --local user.name "devops"
git config --local user.email "a@a.com"
git config --local init.defaultBranch main
git config --local credential.helper store
git --no-pager config --local --list
git --no-pager branch
git remote -v

##############################################################
# Nginx Helm Chart 생성
##############################################################
VERSION=1.26.1
mkdir nginx-chart
mkdir nginx-chart/templates

cat > nginx-chart/VERSION <<EOF
$VERSION
EOF

cat > nginx-chart/templates/configmap.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}
data:
  index.html: |
{{ .Values.indexHtml | indent 4 }}
EOF

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

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

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

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

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


tree nginx-chart
# nginx-chart
# ├── Chart.yaml
# ├── VERSION
# ├── templates
# │   ├── configmap.yaml
# │   ├── deployment.yaml
# │   └── service.yaml
# ├── values-dev.yaml
# └── values-prd.yaml

# 아래 확인은 skip
helm template dev-nginx nginx-chart -f nginx-chart/values-dev.yaml
helm template prd-nginx nginx-chart -f nginx-chart/values-prd.yaml
DEVNGINX=$(helm template dev-nginx nginx-chart -f nginx-chart/values-dev.yaml | sed 's/---//g')
PRDNGINX=$(helm template prd-nginx nginx-chart -f nginx-chart/values-prd.yaml | sed 's/---//g')
diff <(echo "$DEVNGINX") <(echo "$PRDNGINX")

# git push
git status && git add . && git commit -m "Add nginx helm chart" && git push -u origin main

5.2. Gogs Helm Chart 확인

Gogs Helm Chart

5.3. Argo CD Application 생성

Argo CD Nginx Application - 1 Argo CD Nginx Application - 2

  • GENERAL
    • App Name : dev-nginx
    • Project Name : default
    • SYNC POLICY : Manual
      • AUTO-CREATE NAMESPACE : 클러스터에 네임스페이스가 없을 시 argocd에 입력한 이름으로 자동 생성
      • APPLY OUT OF SYNC ONLY : 현재 동기화 상태가 아닌 리소스만 배포
    • SYNC OPTIONS : AUTO-CREATE NAMESPACE(Check)
    • PRUNE PROPAGATION POLICY
      • foreground : 부모(소유자, ex. deployment) 자원을 먼저 삭제함
      • background : 자식(종속자, ex. pod) 자원을 먼저 삭제함
      • orphan : 고아(소유자는 삭제됐지만, 종속자가 삭제되지 않은 경우) 자원을 삭제함
  • Source
    • Repo URL : 설정되어 있는 것 선택
    • Revision : HEAD
    • PATH : nginx-chart
  • DESTINATION
    • Cluster URL : <기본값>
      • NAMESPACE : dev-nginx
  • HELM
    • Values files : values-dev.yaml

⇒ 작성 후 상단 CREATE 클릭

5.4. Argo CD Application 생성 확인

Check Argo CD Application

  • dev-nginx App 클릭 후 상세 정보 확인 -> DIFF 클릭 확인

![Check Argo CD Application Diff(/assets/img/ci-cd/ci-cd-study/check-nginx-argocd-application-diff.webp)

1
2
3
4
5
6
7
8
9
##############################################################
# argocd application 리소스 확인
##############################################################
kubectl get applications -n argocd
# NAME        SYNC STATUS   HEALTH STATUS
# dev-nginx   OutOfSync     Missing

# 상세 확인
kubectl describe applications -n argocd dev-nginx
추가 옵션 설명
  • PRUNE : GIt에서 자원 삭제 후 배포시 K8S에서는 삭제되지 않으나, 해당 옵션을 선택하면 삭제시킴
  • FORCE : --force 옵션으로 리소스 삭제
  • APPLY ONLY : ArgoCD의 Pre/Post Hook은 사용 안함 (리소스만 배포)
  • DRY RUN : 테스트 배포 (배포에 에러가 있는지 한번 확인해 볼때 사용)

5.5. Argo CD Application Sync

SYNC 클릭 -> 생성될 리소스 확인 -> K8S(Live) 반영 확인

Argo CD Nginx Application Sync

1
2
3
4
5
6
7
8
##############################################################
# Argo CD Application Sync 전 모니터링
##############################################################
# Terminal 1 - 상태 모니터링
kubectl get applications -n argocd -w

# Terminal 2 - 반복 접속 시도
while true; do curl -s --connect-timeout 1 http://127.0.0.1:30000 ; date ; echo "------------" ; sleep 1 ; done

Argo CD Application Sync Result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
##############################################################
# Argo CD Application Manifest 및 Kubernetes 리소스 확인
##############################################################
# 아래처럼 yaml 로 Application Manifest 확인 가능
kubectl get applications -n argocd -o yaml | kubectl neat
# apiVersion: v1
# items:
# - apiVersion: argoproj.io/v1alpha1
#   kind: Application
#   metadata:
#     name: dev-nginx
#     namespace: argocd
#   spec:
#     destination:
#       namespace: dev-nginx
#       server: https://kubernetes.default.svc
#     project: default
#     source:
#       helm:
#         valueFiles:
#         - values-dev.yaml
#       path: nginx-chart
#       repoURL: http://172.28.8.232:3000/devops/ops-deploy
#       targetRevision: HEAD
#     syncPolicy:
#       syncOptions:
#       - CreateNamespace=true
# kind: List
# metadata: {}

# 배포 확인
kubectl get all -n dev-nginx -o wide
# NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
# pod/dev-nginx-59f4c8899-4g5pr   1/1     Running   0          3m31s   10.244.1.18   myk8s-worker   <none>           <none>

# NAME                TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE     SELECTOR
# service/dev-nginx   NodePort   10.96.18.23   <none>        80:30000/TCP   3m31s   app=dev-nginx

# NAME                        READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES         SELECTOR
# deployment.apps/dev-nginx   1/1     1            1           3m31s   nginx        nginx:1.26.1   app=dev-nginx

# NAME                                  DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES         SELECTOR
# replicaset.apps/dev-nginx-59f4c8899   1         1         1       3m31s   nginx        nginx:1.26.1   app=dev-nginx,pod-template-hash=59f4c8899

5.6. Argo CD Application Delete

Argo CD Application Delete

1
2
3
4
##############################################################
# 해당 Argo CD Application 에 속한 Kubernetes 리소스 삭제 모니터링
##############################################################
watch -d kubectl get all -n dev-nginx -o wide

6. Argo CD를 통해 Repository(ops-deploy)의 nginx helm chart 배포 2: Argo CD Declarative Setup

Argo CD의 애플리케이션, 프로젝트, 설정은 Kubernetes 매니페스트(Manifest)를 사용해 선언적으로(Declaratively) 정의할 수 있습니다. 이들은 argocd CLI를 직접 사용할 필요 없이, kubectl apply 명령만으로 업데이트할 수 있다.

Argo CD Docs - Declarative Setup

6.1. dev-nginx Application 생성 및 Auto Sync

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
##############################################################
# 환경변수 세팅 및 Declarative 한 방법으로 Application 생성
##############################################################
MyIP=172.28.8.232
echo $MyIP

cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: dev-nginx
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    helm:
      valueFiles:
      - values-dev.yaml
    path: nginx-chart
    repoURL: http://$MyIP:3000/devops/ops-deploy
    targetRevision: HEAD
  syncPolicy:
    automated:
      prune: true
    syncOptions:
    - CreateNamespace=true
  destination:
    namespace: dev-nginx
    server: https://kubernetes.default.svc
EOF

###############################################################
# 생성된 Application 및 리소스 확인 (Auto Sync 옵션이 켜져 있어 Sync를 수동으로 누르지 않아도 됨)
##############################################################
kubectl get applications -n argocd dev-nginx
# NAME        SYNC STATUS   HEALTH STATUS
# dev-nginx   Synced        Healthy


# Application Manifest 및 상세 확인 
kubectl get applications -n argocd dev-nginx -o yaml
kubectl describe applications -n argocd dev-nginx
# ...
#   Finalizers:
#     resources-finalizer.argocd.argoproj.io
# ...

# 생성된 Kubernetes 리소스 확인
kubectl get pod,svc,ep,cm -n dev-nginx
# NAME                            READY   STATUS    RESTARTS   AGE
# pod/dev-nginx-59f4c8899-bcrjb   1/1     Running   0          2m24s

# NAME                TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
# service/dev-nginx   NodePort   10.96.23.232   <none>        80:30000/TCP   2m24s

# NAME                  ENDPOINTS        AGE
# endpoints/dev-nginx   10.244.1.19:80   2m24s

# NAME                         DATA   AGE
# configmap/dev-nginx          1      2m24s
# configmap/kube-root-ca.crt   1      17m


# 접속 확인
curl http://127.0.0.1:30000
# <!DOCTYPE html>
# <html>
# <head>
#   <title>Welcome to Nginx!</title>
# </head>
# <body>
#   <h1>Hello, Kubernetes!</h1>
#   <p>DEV : Nginx version 1.26.1</p>
# </body>
# </html>

open http://127.0.0.1:30000

# Argo CD App 삭제
kubectl delete applications -n argocd dev-nginx

6.2. (참고) K8S Finalizers 와 Argo Finalizers 동작

Kubernetes Docs - Finalizers Kubernetes Blog - Using Finalizers to Control Deletion

Kubernetes Blog - Using Finalizers to Control Deletion

https://kubernetes.io/blog/2021/05/14/using-finalizers-to-control-deletion/

  • Kubernetes에서 finalizers는 리소스의 metadata.finalizers 필드에 정의된 이름 목록으로, 리소스가 삭제 요청을 받았을 때(즉, kubectl delete나 API 호출로 삭제가 시작될 때) 바로 제거되지 않고, 지정된 작업이 완료될 때까지 “종료 중”(Terminating) 상태로 유지되게 합니다.
  • ArgoCD는 이 메커니즘을 활용해 애플리케이션 삭제 시 관리 대상 리소스의 정리(cleanup)를 제어합니다.
  • ArgoCD에서 가장 흔히 사용되는 finalizer는 resources-finalizer.argocd.argoproj.io입니다. 이 finalizer는 애플리케이션이 삭제될 때 해당 애플리케이션이 관리하는 모든 리소스(예: Pod, Service, ConfigMap 등)를 함께 삭제하도록 보장합니다.
  • ArgoCD Finalizers의 목적
    1. 리소스 정리 보장: 애플리케이션 삭제 시 관련 리소스가 남지 않도록 보장합니다. 이는 GitOps 워크플로우에서 선언적 상태를 유지하는 데 중요합니다.
    2. 의도치 않은 삭제 방지: finalizer가 없으면 실수로 Argo App을 삭제해도 K8S 리소스가 남아 혼란이 생길 수 있습니다. finalizer는 이를 방지합니다.
    3. App of Apps 패턴 지원: 여러 애플리케이션을 계층적으로 관리할 때, 상위 애플리케이션 삭제 시 하위 리소스까지 정리되도록 합니다.

7. Repo(ops-deploy)에 Webhook 를 통해 Argo CD 에 즉시 반영 trigger하여 k8s 배포 할 수 있게 설정 - Docs

Argo CD는 매니페스트 변경 사항을 감지하기 위해 3분마다 Git 저장소를 폴링합니다. 폴링 지연을 방지하기 위해 API 서버가 웹훅 이벤트를 수신하도록 구성할 수 있습니다. Argo CD는 GitHub, GitLab, Bitbucket, Bitbucket Server, Azure DevOps 및 Gogs의 Git 웹훅 알림을 지원합니다. 아래에서는 GitHub에 Git 웹훅을 구성하는 방법을 설명하지만, 다른 제공업체에도 동일한 프로세스가 적용됩니다.

Argo CD Docs - Git Webhook Configuration

7.1. Repo(ops-deploy)에 webhooks 설정 : Gogs 선택

  • Payload URL : http://172.28.8.232:30002/api/webhook <- IP부분은 각자 자신의 IP로 변경
  • 나머지 항목 ‘기본값’ ⇒ Add webhook
  • 이후 생성된 webhook 클릭 후 Test Delivery 클릭 후 정상 응답 확인

Gogs Create Argocd Webhook

Webhook 생성

Gogs Webhook Test

생성한 webhook 클릭 후 테스트 실행

7.2. dev-nginx Application 생성 및 Auto Sync

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
##############################################################
# 환경변수 세팅 및 Declarative 한 방법으로 Application 생성
##############################################################
MyIP=172.28.8.232
echo $MyIP

cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: dev-nginx
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    helm:
      valueFiles:
      - values-dev.yaml
    path: nginx-chart
    repoURL: http://$MyIP:3000/devops/ops-deploy
    targetRevision: HEAD
  syncPolicy:
    automated:
      prune: true
    syncOptions:
    - CreateNamespace=true
  destination:
    namespace: dev-nginx
    server: https://kubernetes.default.svc
EOF

###############################################################
# 생성된 Application 및 리소스 확인 (Auto Sync 옵션이 켜져 있어 Sync를 수동으로 누르지 않아도 됨)
##############################################################
kubectl get applications -n argocd dev-nginx
# NAME        SYNC STATUS   HEALTH STATUS
# dev-nginx   Synced        Healthy

# Application Manifest 및 상세 확인 
kubectl get applications -n argocd dev-nginx -o yaml
kubectl describe applications -n argocd dev-nginx
# ...
#   Finalizers:
#     resources-finalizer.argocd.argoproj.io
# ...

# 생성된 Kubernetes 리소스 확인
kubectl get pod,svc,ep,cm -n dev-nginx


# 접속 확인
curl http://127.0.0.1:30000
# <!DOCTYPE html>
# <html>
# <head>
#   <title>Welcome to Nginx!</title>
# </head>
# <body>
#   <h1>Hello, Kubernetes!</h1>
#   <p>DEV : Nginx version 1.26.1</p>
# </body>
# </html>
open http://127.0.0.1:30000

7.3. Git(Gogs) 수정 후 ArgoCD 즉시 반영 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 다른 터미널에서 모니터링 실행 (유지)
watch -d kubectl get all -n dev-nginx -o wide

##############################################################
# Gogs 터미널 진입 (docker-compose.yaml 파일이 위치한 경로에서 실행)
##############################################################
docker compose exec --privileged -u root gogs bash 

---

##############################################################
# 차트 경로 진입
##############################################################
cd /data/ops-deploy/nginx-chart


##############################################################
# 차트 수정 및 변경 사항 확인 (즉시 반영됨)
##############################################################
# 1. replica (1 -> 2)
sed -i "s|replicaCount: 1|replicaCount: 2|g" values-dev.yaml
git add values-dev.yaml && git commit -m "Modify nginx-chart : values-dev.yaml" && git push -u origin main

# 2. replica (2 -> 3)
sed -i "s|replicaCount: 2|replicaCount: 3|g" values-dev.yaml
git add values-dev.yaml && git commit -m "Modify nginx-chart : values-dev.yaml" && git push -u origin main

# 2. replica (3 -> 1)
sed -i "s|replicaCount: 3|replicaCount: 1|g" values-dev.yaml
git add values-dev.yaml && git commit -m "Modify nginx-chart : values-dev.yaml" && git push -u origin main

##############################################################
# Argo CD Application 삭제
##############################################################
kubectl delete applications -n argocd dev-nginx

8. Reference


궁금하신 점이나 추가해야 할 부분은 댓글이나 아래의 링크를 통해 문의해주세요.
Written with KKamJi

This post is licensed under CC BY 4.0 by the author.