[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,381 @@
|
||||
---
|
||||
id: devops-argocd-apps-deep
|
||||
title: ArgoCD Applications — App-of-Apps / ApplicationSet
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [devops, argocd, gitops, vibe-coding]
|
||||
tech_stack: { language: "YAML", applicable_to: ["DevOps"] }
|
||||
applied_in: []
|
||||
aliases: [ArgoCD, Application, ApplicationSet, App-of-Apps, GitOps, declarative deploy]
|
||||
---
|
||||
|
||||
# ArgoCD Applications Deep
|
||||
|
||||
> K8s GitOps 의 표준. **Application + ApplicationSet + App-of-Apps**. Declarative, drift detect, rollback.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- Git = source of truth.
|
||||
- ArgoCD 가 sync to cluster.
|
||||
- Drift detect + reconcile.
|
||||
- Multi-cluster + multi-tenant.
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### Application
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: my-app
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://github.com/me/my-app
|
||||
targetRevision: HEAD
|
||||
path: kubernetes
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: production
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
```
|
||||
|
||||
→ Git path 의 manifest 가 cluster.
|
||||
|
||||
### Sync wave (order)
|
||||
```yaml
|
||||
metadata:
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: '-1' # 먼저
|
||||
```
|
||||
|
||||
→ "Database 먼저, app 다음" 식.
|
||||
|
||||
### Hook (pre/post sync)
|
||||
```yaml
|
||||
metadata:
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/hook-delete-policy: HookSucceeded
|
||||
```
|
||||
|
||||
→ DB migration 가 sync 전.
|
||||
|
||||
### App-of-Apps
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: root
|
||||
spec:
|
||||
source:
|
||||
path: apps/ # 매 file 가 Application
|
||||
destination: { ... }
|
||||
```
|
||||
|
||||
```yaml
|
||||
# apps/users.yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: users-service
|
||||
spec: ...
|
||||
|
||||
# apps/orders.yaml
|
||||
...
|
||||
```
|
||||
|
||||
→ 1 root Application 가 모든 다른 Application 관리.
|
||||
|
||||
### ApplicationSet (generator)
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: ApplicationSet
|
||||
metadata:
|
||||
name: per-cluster
|
||||
spec:
|
||||
generators:
|
||||
- clusters: {} # 매 cluster 의 Application
|
||||
template:
|
||||
metadata:
|
||||
name: '{{name}}-app'
|
||||
spec:
|
||||
source:
|
||||
repoURL: ...
|
||||
path: 'manifests/{{name}}'
|
||||
destination:
|
||||
server: '{{server}}'
|
||||
```
|
||||
|
||||
→ 매 cluster / branch / file 가 자동 Application.
|
||||
|
||||
### Generator types
|
||||
```
|
||||
- List: explicit list.
|
||||
- Cluster: matrix (모든 cluster).
|
||||
- Git directory: 매 dir = Application.
|
||||
- Git file: 매 file.
|
||||
- Pull request: 매 PR 가 preview env.
|
||||
- Matrix: combine.
|
||||
- Merge: combine + override.
|
||||
```
|
||||
|
||||
### PR preview environment
|
||||
```yaml
|
||||
generators:
|
||||
- pullRequest:
|
||||
github:
|
||||
owner: me
|
||||
repo: my-app
|
||||
labels: ['preview']
|
||||
template:
|
||||
metadata:
|
||||
name: 'preview-{{number}}'
|
||||
spec:
|
||||
source:
|
||||
targetRevision: '{{branch}}'
|
||||
path: kubernetes
|
||||
destination:
|
||||
namespace: 'preview-{{number}}'
|
||||
```
|
||||
|
||||
→ 매 PR 의 own preview namespace.
|
||||
|
||||
### Multi-cluster
|
||||
```yaml
|
||||
generators:
|
||||
- clusters:
|
||||
selector:
|
||||
matchLabels:
|
||||
environment: production
|
||||
template:
|
||||
spec:
|
||||
destination:
|
||||
server: '{{server}}'
|
||||
```
|
||||
|
||||
→ 매 prod cluster 에 자동 deploy.
|
||||
|
||||
### Sync options
|
||||
```yaml
|
||||
syncPolicy:
|
||||
automated: { prune: true, selfHeal: true }
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
- ApplyOutOfSyncOnly=true
|
||||
- RespectIgnoreDifferences=true
|
||||
```
|
||||
|
||||
### Ignore differences
|
||||
```yaml
|
||||
ignoreDifferences:
|
||||
- group: apps
|
||||
kind: Deployment
|
||||
jsonPointers:
|
||||
- /spec/replicas # HPA 가 manage
|
||||
```
|
||||
|
||||
→ Replica drift 무시.
|
||||
|
||||
### Health check
|
||||
```yaml
|
||||
# Custom resource
|
||||
metadata:
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Or custom health Lua script
|
||||
data:
|
||||
resource.customizations: |
|
||||
redis.io/Redis:
|
||||
health.lua: |
|
||||
if obj.status ~= nil then
|
||||
if obj.status.phase == 'Ready' then
|
||||
return { status = 'Healthy' }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Helm + ArgoCD
|
||||
```yaml
|
||||
spec:
|
||||
source:
|
||||
repoURL: https://charts.example.com
|
||||
chart: my-chart
|
||||
targetRevision: 1.2.3
|
||||
helm:
|
||||
values: |
|
||||
replicaCount: 3
|
||||
image: ...
|
||||
```
|
||||
|
||||
### Kustomize + ArgoCD
|
||||
```yaml
|
||||
spec:
|
||||
source:
|
||||
path: overlays/production
|
||||
kustomize:
|
||||
images:
|
||||
- my-app:v1.2.3
|
||||
```
|
||||
|
||||
### Notification
|
||||
```yaml
|
||||
# argocd-notifications-cm
|
||||
data:
|
||||
service.slack: |
|
||||
token: $slack-token
|
||||
|
||||
template.app-deployed: |
|
||||
message: 'App {{.app.metadata.name}} deployed.'
|
||||
|
||||
trigger.on-deployed: |
|
||||
when: app.status.operationState.phase == 'Succeeded'
|
||||
send: [app-deployed]
|
||||
|
||||
subscriptions: |
|
||||
- recipients: [slack:deployments]
|
||||
triggers: [on-deployed]
|
||||
```
|
||||
|
||||
### RBAC
|
||||
```yaml
|
||||
data:
|
||||
policy.csv: |
|
||||
p, role:dev, applications, sync, default/*, allow
|
||||
p, role:dev, applications, get, default/*, allow
|
||||
g, dev-team, role:dev
|
||||
```
|
||||
|
||||
→ Team 별 access.
|
||||
|
||||
### Project (multi-tenant)
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: AppProject
|
||||
metadata:
|
||||
name: my-team
|
||||
spec:
|
||||
sourceRepos:
|
||||
- https://github.com/me/team-repo
|
||||
destinations:
|
||||
- namespace: 'team-*'
|
||||
server: '*'
|
||||
clusterResourceWhitelist:
|
||||
- group: '*'
|
||||
kind: '*'
|
||||
```
|
||||
|
||||
### vs Flux
|
||||
```
|
||||
ArgoCD: UI 친화, 큰 ecosystem.
|
||||
Flux: simple, GitOps Toolkit.
|
||||
|
||||
→ ArgoCD 가 더 popular.
|
||||
```
|
||||
|
||||
### vs Argo Rollouts (다름)
|
||||
```
|
||||
ArgoCD: app deploy.
|
||||
Argo Rollouts: progressive delivery (canary, blue-green).
|
||||
|
||||
→ 둘 다 같이 사용.
|
||||
```
|
||||
|
||||
→ [[DevOps_Argo_Rollouts]].
|
||||
|
||||
### Production patterns
|
||||
```
|
||||
1. Git monorepo 의 매 app folder.
|
||||
2. ApplicationSet 가 자동 Application 생성.
|
||||
3. PR preview 가 매 feature.
|
||||
4. Notification 가 Slack.
|
||||
5. Project 별 RBAC.
|
||||
6. Argo Rollouts 가 progressive deploy.
|
||||
```
|
||||
|
||||
### Disaster recovery
|
||||
```
|
||||
ArgoCD 자체 가 down:
|
||||
- Cluster 의 manifest 유지 (기존 deploy).
|
||||
- 새 deploy 안 됨.
|
||||
- Restore from backup (etcd).
|
||||
|
||||
→ ArgoCD 가 second cluster 의 backup.
|
||||
```
|
||||
|
||||
### Cost
|
||||
```
|
||||
ArgoCD: 무료 (open source).
|
||||
Cluster compute: ArgoCD 가 작은 (작은 deployment).
|
||||
|
||||
→ Self-host 가 cheap.
|
||||
```
|
||||
|
||||
### Real-world
|
||||
- **Intuit** (creator).
|
||||
- **Adobe**: 큰 user.
|
||||
- **Red Hat OpenShift**: native integration.
|
||||
- **Tetrate / SAP**: 큰 deployment.
|
||||
|
||||
### 함정
|
||||
```
|
||||
- Auto-sync 가 모든 변경 즉시: 위험.
|
||||
- No project / RBAC: 매 user 가 모든.
|
||||
- Manifest drift (manual kubectl): self-heal 가 fight.
|
||||
- Big repo (10k+ Application): 느린.
|
||||
- Helm value secret in git: 안 됨 (External Secrets).
|
||||
```
|
||||
|
||||
### Best practice
|
||||
```
|
||||
1. App-of-Apps 또는 ApplicationSet (DRY).
|
||||
2. Self-heal + auto-sync (production).
|
||||
3. Pre-sync hook 의 migration.
|
||||
4. Notification (Slack).
|
||||
5. RBAC + Project.
|
||||
6. Argo Rollouts 가 progressive.
|
||||
7. Secret management (External Secrets / Sealed Secrets).
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| 작업 | 추천 |
|
||||
|---|---|
|
||||
| K8s GitOps | ArgoCD |
|
||||
| Simple GitOps | Flux |
|
||||
| Multi-cluster | ApplicationSet |
|
||||
| Preview env | PR generator |
|
||||
| Helm | Helm + ArgoCD |
|
||||
| Kustomize | Kustomize + ArgoCD |
|
||||
| Progressive deploy | Argo Rollouts |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Manual kubectl**: drift.
|
||||
- **No project**: shared cluster + 매 user.
|
||||
- **Big mono Application**: slow sync.
|
||||
- **Secret in git**: leak.
|
||||
- **No notification**: silent failure.
|
||||
- **No backup**: lost.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- ArgoCD = K8s GitOps standard.
|
||||
- ApplicationSet 가 multi-cluster / multi-app.
|
||||
- App-of-Apps 가 hierarchy.
|
||||
- Argo Rollouts 와 함께 progressive.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[DevOps_ArgoCD_GitOps]]
|
||||
- [[DevOps_Argo_Rollouts]]
|
||||
- [[DevOps_K8s_Operators]]
|
||||
Reference in New Issue
Block a user