애플리케이션 개발은 테스트, 스테이징, 프로덕션 환경으로 구분이 된다.
이러한 환경은 구성은 하나의 클러스터 안에서 네임스페이스로 구분
네임스페이스로 구성하고 필요한 모드 환경을 추가한다.
시간이 지남에 따라 인프라 자원들이 서로 다른 상태가 되는 현상 발생
| 용어 | 설명 |
|---|---|
| application | 쿠버네티스 리소스 그룹은 매니페스트에 의해 규정된다. |
| Argo CD에서는 CRD에서 규정한다. | |
| application source type | helm, kustomize, jsonnet 과 같이 애플리케이션을 구축하는 데 사용하는 도구 |
| target state | 애플리케이션의 의도한 상태를 이야기하며 원천 소스인 git repository를 의미한다. |
| live state | 애플리케이션의 현재 상태로 k8s 클러스터에 배포된 상태를 의미한다. |
| sync state | 현재 상태와 target 상태가 일치하는지 확인한다. |
| sync | k8s cluster에 변화를 적용해 애플리케이션을 target 상태로 변경 |
| sync operation status | 동기화 단계에서 작업이 실패인지 성공인지 여부를 보여준다. |
| refresh | 깃 리포지터리의 최신 코드와 현재 상태의 차이점을 비교한다. |
| health status | 애플리케이션이 요청을 받을 수 있고 운영 중인 상태인지를 말해준다. |
핵심 구성요소는 쿠버네티스 컨트롤러로 구성
쿠버네티스 컨트롤러 : 클러스터의 상태를 관찰한 다음 필요한 경우 변경 사항을 적용하거나 요청한다.
CRD : Argo CD 애플리케이션, 프로젝트, 리포지터리, 클러스터의 자격 증명과 설정 값들은 쿠버네티스 매니페스트를 이용해 선언적으로 정의
kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: **control-plane**
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- containerPort: 30002
hostPort: 30002
- containerPort: 30003
hostPort: 30003
EOF
# kube-ops-view
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=**NodePort**,service.main.ports.http.nodePort=**30001** --set env.TZ="Asia/Seoul" --namespace kube-system
# kube-ops-view 접속 URL 확인 (1.5 , 2 배율)
open "http://127.0.0.1:30001/#scale=1.5"
open "http://127.0.0.1:30001/#scale=2"
kubectl create ns **argocd**
cat <<EOF > argocd-values.yaml
server:
service:
type: NodePort
nodePortHttps: 30002
extraArgs:
- --insecure # HTTPS 대신 HTTP 사용
EOF
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 -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
xjcDxnMUJ82QrnqL
open "http://localhost:30002"
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: **guestbook
namespace: argocd**
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
**source:**
helm:
valueFiles:
- **values.yaml**
path: **helm-guestbook**
repoURL: **https://github.com/argoproj/argocd-example-apps**
targetRevision: HEAD
**syncPolicy**:
automated:
enabled: true
prune: true
**selfHeal: true**
syncOptions:
- CreateNamespace=true
**destination:**
namespace: guestbook
server: https://kubernetes.default.svc
EOF
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:/# kubectl get svc -n guestbook
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
guestbook-helm-guestbook ClusterIP 10.96.80.229 <none> 80/TCP 2m43s
# nodeport 변경
kubectl patch svc -n guestbook guestbook-helm-guestbook -p '{"spec":{"type":"NodePort","ports":[{"port":80,"targetPort":80,"nodePort":30003}]}}'
안바뀌어지는 경우
self heal disabled
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:/# kubectl patch svc -n guestbook guestbook-helm-guestbook -p '{"spec":{"type":"NodePort","ports":[{"port":80,"targetPort":80,"nodePort":30003}]}}'
service/guestbook-helm-guestbook patched
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:/# kubectl get svc -n guestbook
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
guestbook-helm-guestbook NodePort 10.96.80.229 <none> 80:30003/TCP 4m44s
## nodeport로 변경 확인
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:/# curl http://localhost:30003
<html ng-app="redis">
<head>
<title>Guestbook</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<script src="controllers.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.6/ui-bootstrap-tpls.js"></script>
</head>
<body ng-controller="RedisCtrl">
<div style="width: 50%; margin-left: 20px">
<h2>Guestbook</h2>
<form>
<fieldset>
<input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br>
<button type="button" class="btn btn-primary" ng-click="controller.onRedis()">Submit</button>
</fieldset>
</form>
<div>
<div ng-repeat="msg in messages track by $index">
{{msg}}
</div>
</div>
</div>
</body>
</html>
# 삭제
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:/# kubectl delete applications -n argocd guestbook


helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace \
--set controller.publishService.enabled=true
https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#kubernetesingress-nginx
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:/# cat <<'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
ingressClassName: nginx
rules:
- host: argocd.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
EOF
127.0.0.1 argocd.example.com
kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 443:443

(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd account list
NAME ENABLED CAPABILITIES
admin true login
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# 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>
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd repo list
TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd cluster list
SERVER NAME VERSION STATUS MESSAGE PROJECT
https://kubernetes.default.svc in-cluster Unknown Cluster has no applications and is not being monitored.
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd app list
NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd login 127.0.0.1:30002 --plaintext
Username: admin
Password:
'admin:login' logged in successfully
Context '127.0.0.1:30002' updated
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd account list
NAME ENABLED CAPABILITIES
admin true login
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# 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>
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd repo list
TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd cluster list
SERVER NAME VERSION STATUS MESSAGE PROJECT
https://kubernetes.default.svc in-cluster Unknown Cluster has no applications and is not being monitored.
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd app list
NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET
https://github.com/argoproj/argocd-example-apps
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
Argo Rollouts는 Kubernetes 환경에서 블루-그린(Blue-Green), 카나리(Canary), 실시간 트래픽 조정, 자동 롤백 같은 고급 배포 전략을 구현할 수 있게 해주는 배포 컨트롤러(Deployment Controller)입니다.
블루-그린 전략은 Kubernetes의 기본 Deployment에서는 지원되지 않지만, 서드파티 Kubernetes 컨트롤러를 통해 사용할 수 있습니다. 이 예제는 Argo Rollouts를 통해 블루-그린 배포를 구현하는 방법을 보여줍니다:
argocd app create --name blue-green --repo https://github.com/argoproj/argocd-example-apps --dest-server https://kubernetes.default.svc --dest-namespace default --path blue-green && argocd app sync blue-green
애플리케이션이 동기화되면 blue-green-helm-guestbook 서비스를 통해 접근할 수 있습니다.
argocd app set blue-green -p image.tag=0.2 && argocd app sync blue-gree
이제 애플리케이션은 ks-guestbook-demo:0.1과 ks-guestbook-demo:0.2 이미지를 동시에 실행합니다. ks-guestbook-demo:0.2는 아직 blue 상태로 간주되며, 프리뷰 서비스 blue-green-helm-guestbook-preview를 통해서만 접근 가능합니다.
Rollout 리소스를 패치하여 ks-guestbook-demo:0.2를 green으로 승격시킵니다:argocd app patch-resource blue-green --kind Rollout --resource-name blue-green-helm-guestbook --patch '{ "status": { "verifyingPreview": false } }' --patch-type 'application/merge-patch+json'
이렇게 하면 ks-guestbook-demo:0.2가 green 상태로 승격되고, Rollout은 ks-guestbook-demo:0.1을 실행하는 이전 레플리카를 삭제합니다.
argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path helm-guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
Deployment, Service, ConfigMap 등 직접 기술)argocd app create helm-guestbook --repo https://github.com/argoproj/argocd-example
-apps.git --path helm-guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
Chart.yaml, values.yaml, templates/)argocd app create helm-dependency --repo https://github.com/argoproj/argocd-exampl
e-apps.git --path helm-dependency --dest-server https://kubernetes.default.svc --dest-namespace default
argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-ex
ample-apps.git --path kustomize-guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
namePrefix: kustomize-
resources:
- guestbook-ui-deployment.yaml
- guestbook-ui-svc.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
git 저장소에 code를 push 해도 argocd application이 자동으로 생성되지 않는다.
사용자가 수동으로 argocd application을 만들어야 한다.

| 구분 | 기존 설치 방식 | Autopilot 방식 |
|---|---|---|
| 설치 주체 | 사용자가 kubectl apply | Autopilot CLI |
| ArgoCD 자기 관리 여부 | ❌ 없음 (사람이 직접 관리) | ✅ 있음 (자기 자신을 GitOps로 관리) |
| Git 연동 시점 | 설치 후 수동 설정 | 설치 중 자동 연결 |
| 재현성 | 환경마다 매번 수동 작업 필요 | Git 저장소만 있으면 자동 재설치 가능 |
| 관리 패턴 | 수동 DevOps | 완전한 GitOps |
# install : Linux and WSL (using curl)
VERSION=$(curl --silent "https://api.github.com/repos/argoproj-labs/argocd-autopilot/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
curl -L --output - https://github.com/argoproj-labs/argocd-autopilot/releases/download/"$VERSION"/argocd-autopilot-linux-amd64.tar.gz | tar zx
mv ./argocd-autopilot-* /usr/local/bin/argocd-autopilot
argocd-autopilot version


argocd-autopilot repo bootstrap)argocd-autopilot repo bootstrap : 매니페스트를 푸시하고 깃 리포지터리 안에 필요한 구조를 생성(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# export GIT_TOKEN=ghp_ojW4KoKV6BGnXlNUqJl
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# export GIT_REPO=https://github.com/hp0724/autopilot.git
# Bootstrap Argo-CD
**argocd-autopilot repo bootstrap**
INFO pushing bootstrap manifests to repo
Resolving deltas: 100% (1/1), done.
INFO applying argo-cd bootstrap application
I1104 23:32:21.663669 29305 warnings.go:110] "Warning: metadata.finalizers: \"resources-finalizer.argocd.argoproj.io\": prefer a domain-qualified finalizer name including a path (/) to avoid accidental conflicts with other finalizer writers"
application.argoproj.io/autopilot-bootstrap created
INFO running argocd login to initialize argocd config
'admin:login' logged in successfully
Context 'autopilot' updated
INFO argocd initialized. password: ZNpw3JoGiyxut7tF
INFO run:
kubectl port-forward -n argocd svc/argocd-server 8080:80


| 폴더 | 역할 |
|---|---|
bootstrap/ | Argo CD 및 클러스터 초기 부트스트랩 구성 |
apps/ | 실제 배포 애플리케이션 정의 (GitOps 대상) |
projects/ | 애플리케이션 그룹화 및 정책 설정 |
.autopilot/ | Autopilot 내부 상태 관리용 |
argoCD는 원래 하나의 Application이 하나의 git 경로를 바라보고, 그 안에 있는 매니페스트를 클러스터에 배포하는 구조
ArgoCD application을 모아서 관리하는 패턴을 app of apps패턴
ArgoCD Application이 또 다른 ArgoCD Application들을 만들어주는 구조
“앱들의 앱” → App of Apps

새롭게 구축한 쿠버네티스 클러스터에 필요한 쿠버네티스 리소스를 빠르게 배포하는 것을 cluster bootstrapping
동일한 app of apps패턴을 여러 클러스터에 배포하면 동일한 쿠버네티스 인프라가 구축
apps/)export GIT_TOKEN=*<자신의 Git Token>*
export GIT_REPO=*<자신의 Repo>*
**argocd-autopilot project create dev
argocd-autopilot project create prd**

(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# kubectl get appprojects.argoproj.io -n argocd
NAME AGE
default 47h
dev 2m55s
prd 2m55s


(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd-autopilot app create hello-world1 --app github.com/argoproj-labs/argocd-autopilot/examples/demo-app/ -p dev --type kustomize
INFO cloning git repository: https://github.com/hp0724/autopilot.git
Enumerating objects: 19, done.
Counting objects: 100% (19/19), done.
Compressing objects: 100% (16/16), done.
Total 19 (delta 3), reused 17 (delta 1), pack-reused 0 (from 0)
INFO using revision: "", installation path: "/"
INFO committing changes to gitops repo...
INFO installed application: hello-world1
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd-autopilot app create hello-world2 --app github.com/argoproj-labs/argocd-autopilot/examples/demo-app/ -p prd --type kustomize
INFO cloning git repository: https://github.com/hp0724/autopilot.git
Enumerating objects: 26, done.
Counting objects: 100% (26/26), done.
Compressing objects: 100% (22/22), done.
Total 26 (delta 4), reused 23 (delta 1), pack-reused 0 (from 0)
INFO using revision: "", installation path: "/"
INFO committing changes to gitops repo...
INFO installed application: hello-world2
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# argocd-autopilot app delete hello-world2 -p prd
INFO cloning git repository: https://github.com/hp0724/autopilot.git
Enumerating objects: 30, done.
Counting objects: 100% (30/30), done.
Compressing objects: 100% (25/25), done.
Total 30 (delta 5), reused 26 (delta 1), pack-reused 0 (from 0)
INFO using revision: "", installation path: "/"
INFO committing changes to gitops repo...
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~# kubectl get applications.argoproj.io -n argocd -owide
NAME SYNC STATUS HEALTH STATUS REVISION PROJECT
argo-cd Synced Healthy 6319514589a7780dcd9a23e67e8a87c036bdaa61 default
autopilot-bootstrap Synced Healthy c247b6c5390725392e794824ba20d941843cbc8a default
cluster-resources-in-cluster Synced Healthy 6319514589a7780dcd9a23e67e8a87c036bdaa61 default
dev-hello-world1 Synced Healthy 6319514589a7780dcd9a23e67e8a87c036bdaa61 dev
root Synced Healthy 6319514589a7780dcd9a23e67e8a87c036bdaa61 default
k8s 클러스터에 변경 내용을 적용해 애플리케이션을 target 상태로 만드는 단계

| Phase | 실행 시점 | 주요 역할 | 예시 Hook |
|---|---|---|---|
| PreSync | 리소스를 실제로 적용하기 직전 | 사전 작업 수행 (예: 백업, 점검, 알림 등) | Job, ConfigMap, Script |
| Sync | Git의 선언된 상태를 클러스터에 반영하는 단계 | Deployment, Service 등 리소스를 생성/업데이트 | 실제 Kubernetes 리소스 적용 |
| PostSync | 리소스 적용이 끝난 직후 | 검증, 테스트, 후처리 등 수행 | Job, Pod, Script |


| 단계(Phase) | 조건(Trigger) | 설명 | 결과 |
|---|---|---|---|
| PreSync | Sync 시작 전 | 리소스를 실제로 적용하기 전에 실행되는 단계. 주로 백업, 점검, 준비 작업 등에 사용됨. | 성공 시 → Sync 단계로 진행 |
| Sync | PreSync 성공 후 | Git에 정의된 쿠버네티스 리소스를 실제 클러스터에 적용하는 핵심 단계. | 성공 시 → PostSync로 진행실패 시 → SyncFail로 이동 |
| PostSync | Sync 성공 후 | 리소스 배포가 완료된 후 실행되는 후처리 단계. 테스트, 알림, 정리 작업 등에 사용됨. | 완료 시 Sync 종료 |
| SyncFail | Sync 실패 시 | Sync 과정 중 오류가 발생했을 때 실행되는 복구/알림 단계. | 오류 처리 및 로그 기록 수행 |
리소스 hook은 k8s 매니페스트에 적용된다.
리소스 hook은 k8s 매니페스트에 적용된다.
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
annotations:
**argocd.argoproj.io/hook: PreSync**
argocd-example-apps/pre-post-sync at master · argoproj/argocd-example-apps
apiVersion: batch/v1
kind: Job
metadata:
name: before
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: sleep
image: alpine:latest
command: ["sleep", "10"]
restartPolicy: Never
backoffLimit: 0
argocd.argoproj.io/hook: PreSync → Argo CD가 앱을 sync하기 전에 이 Job을 실행합니다. (즉, 리소스 배포 전에 미리 실행되는 작업)argocd.argoproj.io/hook-delete-policy: HookSucceeded → Job이 성공하면 자동으로 삭제됩니다. 실패 시엔 로그를 남기기 위해 남습니다.apiVersion: batch/v1
kind: Job
metadata:
name: after
annotations:
argocd.argoproj.io/hook: PostSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: sleep
image: alpine:latest
command: ["sleep", "10"]
restartPolicy: Never
backoffLimit: 0
PostSync → Argo CD가 앱의 모든 리소스를 성공적으로 배포한 이후 실행됩니다.HookSucceeded로 지정했으므로 Job이 성공하면 자동 삭제됩니다.spec은 PreSync Job과 동일하게 10초 대기.namePrefix: pre-post-sync-
bases:
- ../kustomize-guestbook
resources:
- pre-sync-job.yaml
- post-sync-job.yaml
guestbook 배포 흐름에 PreSync/ PostSync 훅 Job을 삽입하는 Kustomize 오버레이
Argo CD는 다음 순서에 따라 리소스를 변경
sync-waves/manifests.yaml
---
apiVersion: batch/v1
kind: Job
metadata:
generateName: upgrade-sql-schema
annotations:
argocd.argoproj.io/hook: PreSync
spec:
template:
spec:
containers:
- name: upgrade-sql-schema
image: alpine:latest
command: ["sleep", "5"]
restartPolicy: Never
---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: backend
spec:
replicas: 1
selector:
matchLabels:
tier: backend
template:
metadata:
labels:
tier: backend
spec:
containers:
- name: main
image: nginx:latest
---
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
selector:
tier: backend
ports:
- protocol: TCP
port: 8080
targetPort: 8080
---
apiVersion: batch/v1
kind: Job
metadata:
name: maint-page-up
annotations:
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
argocd.argoproj.io/sync-wave: "1"
spec:
template:
spec:
containers:
- name: page-up
image: alpine:latest
command: ["sleep", "2"]
restartPolicy: Never
backoffLimit: 0
---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
annotations:
argocd.argoproj.io/sync-wave: "2"
spec:
replicas: 1
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: main
image: nginx:latest
---
apiVersion: v1
kind: Service
metadata:
name: frontend
annotations:
argocd.argoproj.io/sync-wave: "2"
spec:
selector:
tier: frontend
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: batch/v1
kind: Job
metadata:
name: maint-page-down
annotations:
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
argocd.argoproj.io/sync-wave: "3"
spec:
template:
spec:
containers:
- name: page-down
image: alpine:latest
command: ["sleep", "2"]
restartPolicy: Never
apiVersion: argoproj.io/v1alpha1
kind: **AppProject**
metadata:
name: default
spec:
syncWindows:
- kind: **allow # 허용**
schedule: '10 1 * * *' # cron 형식 지원
duration: 1h # 얼마동안
applications: # application or namespace or cluster
- '*-prod' # 이름이 -prod로 끝나는 모든 애플리케이션
manualSync: true
- kind: **deny # 차단**
schedule: '0 22 * * *'
timeZone: "Europe/Amsterdam"
duration: 1h
namespaces:
- default
- kind: allow
schedule: '0 23 * * *'
duration: 1h
clusters:
- in-cluster
- cluster1
| 필드 | 설명 |
|---|---|
| kind | allow 또는 deny (해당 시간대에 배포를 허용할지, 금지할지) |
| schedule | cron-like 표현식으로 요일/시간 지정 가능 (Mon-Fri 09:00-18:00 등) |
| duration | 윈도우 지속 시간 (예: 2h, 24h) |
| applications | 해당 규칙을 적용할 Application 목록 (*이면 전체) |


kind delete cluster --name myk8s
# kind k8s 배포
kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- containerPort: 30002
hostPort: 30002
- containerPort: 30003
hostPort: 30003
- role: worker
- role: worker
- role: worker
EOF
# kube-ops-view
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=NodePort,service.main.ports.http.nodePort=30001 --set env.TZ="Asia/Seoul" --namespace kube-system
# kube-ops-view 접속 URL 확인 (1.5 , 2 배율)
open "http://127.0.0.1:30001/#scale=1.5"
open "http://127.0.0.1:30001/#scale=2"

mkdir resources
# 매니페스트 파일 작성 및 배포
cat << EOF > resources/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: argocd
EOF
**kubectl apply -f resources/namespace.yaml**
cd resources
wget https://raw.githubusercontent.com/argoproj/argo-cd/refs/heads/master/manifests/**ha**/install.yaml
**kubectl apply -f resources/install.yaml -n argocd**
# 확인
watch -d kubectl get pod -n argocd
kubectl port-forward svc/argocd-server -n argocd 8080:80
#
kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d ; echo
*UOn2CEkg0c4RCfQU*
open https://127.0.0.1:8080 # 프로덕션의 경우 TLS인증서가 적용된 로드밸랜서 서비스로 오픈하자
# 원격 리포지터리에 커밋하고 푸시한다.
git add . && git commit -m "Deploy Argo CD " && git push -u origin main
****
(⎈|kind-myk8s:N/A) root@DESKTOP-8S932ET:~/resources# kubectl get pods -n argocd
NAME READY STATUS RESTARTS AGE
argocd-application-controller-0 1/1 Running 0 2m6s
argocd-applicationset-controller-694b4774cd-pg4h9 1/1 Running 0 2m7s
argocd-dex-server-66585dc685-rnqsc 1/1 Running 0 2m7s
argocd-notifications-controller-7c584f65cc-x827l 1/1 Running 0 2m7s
argocd-redis-ha-haproxy-7487b954d9-8g6td 1/1 Running 0 2m7s
argocd-redis-ha-haproxy-7487b954d9-jc5bm 1/1 Running 0 2m7s
argocd-redis-ha-haproxy-7487b954d9-pxcg8 1/1 Running 0 2m7s
argocd-redis-ha-server-0 0/3 Init:0/1 0 2m6s
argocd-repo-server-74b54f7cb-46829 1/1 Running 0 2m7s
argocd-repo-server-74b54f7cb-jcd25 1/1 Running 0 2m7s
argocd-server-8b767f58c-gb4kf 1/1 Running 0 2m7s
argocd-server-8b767f58c-lld6w 1/1 Running 0 2m6s
# svc 연결
kubectl port-forward svc/argocd-server -n argocd 8080:80
#
kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d ; echo
*UOn2CEkg0c4RCfQU*
open https://127.0.0.1:8080 # 프로덕션의 경우 TLS인증서가 적용된 로드밸랜서 서비스로 오픈하자
# 원격 리포지터리에 커밋하고 푸시한다.
git add . && git commit -m "Deploy Argo CD " && git push -u origin main


git add . && git commit -m "Delete Network Policy Resource" && git push -u origin main


argocd는 기본적으로 무상태 구조
중요한 데이터는 k8s object로 저장되고, etcd가 있으니깐 pod 하나가 죽어도 전체 설정이 날아가지는 않는다.
그럼에도 HA를 통해서 여러 개의 pod를 띄우면 장애나 배포 시에도 끊기지 않고 서비스 유지가 가능
git clone하고, helm, kustomize, plugin으로 매니페스트를 만들어주는 친구
--parallelismlimit로 동시 작업 수를 제한하라./tmp에 클론하기 때문에 디스크 부족 나면 PVC 붙여라.Git에서 만들어진 매니페스트와 실제 클러스터 상태를 비교해서 “이 앱을 동기화해야 하나?”를 결정하는 핵심 컨트롤러.
컨트롤러는 Kubernetes 리소스를 watch해서 자체 캐시를 유지하므로, 규모가 커질수록 이 부분 튜닝이 중요하다
사용자가 접속하는 서버라 여러 개 띄우면 좋습니다
| 구분 | 모니터링 (Monitoring) | 관측 가능성 (Observability) |
|---|---|---|
| 목적 | 상태 감시, 이상 탐지 | 문제 원인 분석, 내부 이해 |
| 질문 예시 | “문제가 생겼는가?” | “왜 문제가 생겼는가?” |
| 데이터 형태 | Metrics 중심 | Logs + Metrics + Traces |
| 도구 예시 | Prometheus, Grafana | ELK Stack, Jaeger, OpenTelemetry |
| 접근 방식 | 사전 정의된 지표 관찰 | 시스템 내부 상태를 추론 가능하게 설계 |
| 요소 | 설명 |
|---|---|
| Logs | 시스템 내 세부 이벤트 기록 (예: 에러 메시지, 요청 처리 로그) |
| Metrics | 성능 지표 (예: CPU 사용률, 응답 시간, 에러율) |
| Traces | 요청이 여러 서비스 간을 이동할 때 전체 경로 추적 |
| 방식 | 장점 | 단점 |
|---|---|---|
| Push | - 대상 시스템의 제어 가능- 빠른 데이터 전송- 비동기적 수집 | - 네트워크 부하 증가- 시스템 과부하 가능성- 수집 실패 위험 |
| Pull | - 중앙 집중식 관리- 대규모 시스템에 적합- 누락된 데이터 처리 용이 | - 모니터링 시스템의 부하 증가- 응답 지연 발생- 비효율적인 네트워크 사용 |