Ssoon
Argo CD in Practice – 3) Argo CD 운영 : 재해 복구 계획 수립 본문
🧭 Argo CD Disaster Recovery(재해 복구) 계획하기
- Argo CD는 데이터베이스를 직접 사용하지 않습니다.
- Redis는 캐시 용도로만 사용되므로 “stateless”에 가깝게 보이지만, 실제로는 Argo CD의 상태(state)가 Kubernetes 리소스 안에 저장되어 있습니다.
💾 Argo CD의 상태(State)란?
- Argo CD는 다음과 같은 정보를 Kubernetes 리소스로 저장합니다.
- Application 정의 정보 (Git repo, destination cluster 등)
- Kubernetes cluster 접근 정보 (Connection details – Secrets)
- Private Git repo / Helm repo 접근 설정
- Argo CD의 모든 동작 환경은 Kubernetes 내부 리소스에 의해 유지됩니다. 따라서 클러스터가 삭제되거나 Namespace가 사라지면, 이 상태들도 함께 사라질 수 있습니다.
"Argo CD는 DB를 사용하지 않지만, 모든 상태 정보는 Kubernetes 리소스 안에 존재합니다."
⚠️ 재해(Disaster)의 예시
- 재해는 다양한 이유로 발생할 수 있습니다:
- 인적 실수로 Kubernetes cluster 또는 argocd namespace 삭제
- Cloud provider 장애로 인한 클러스터 손실
- 클러스터 마이그레이션 (예: kubeadm → Cloud managed Kubernetes)
- 이런 상황에서는 Argo CD의 설정, 애플리케이션 정의, 클러스터 연결 정보 등을 빠르게 복원(restore) 하는 것이 중요합니다.
"Disaster Recovery는 단순 복구가 아닌, Argo CD 상태를 신속히 복원하는 전략입니다."
🧱 GitOps라고 해도 복구가 필요한 이유
- “GitOps니까 Git repo만 있으면 다시 만들 수 있지 않을까?” 라고 생각할 수 있지만, 완전히 맞지는 않습니다.
- Cluster 등록 정보는 CLI 명령으로 추가하므로 Git에 저장되지 않습니다.
- Git repo에서 재생성하려면 수천 개의 Application, 수백 개의 Cluster를
다시 적용해야 할 수도 있습니다.
- 이런 이유로 Git repo 기반 복원보다 백업 기반 복원이 훨씬 빠르고 효율적입니다.
"GitOps는 모든 설정을 코드로 관리하지만, 일부 operational state는 Git에 포함되지 않습니다."
🧰 Argo CD CLI
- Argo CD는 Disaster Recovery를 위해 CLI 도구에 admin 서브커맨드를 제공합니다.
- 이 명령어를 이용해 Argo CD의 모든 상태를 백업(export) 하거나 기존 백업에서 복원(import) 할 수 있습니다.
"Argo CD CLI는 백업과 복원 작업의 핵심 도구입니다."
💿 백업 생성하기
- argocd 서버 (http) 로그인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app/resources$ ARGOPW=D1x443hRSzRw8wbj
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app/resources$ argocd login localhost:8080 --username admin --password $ARGOPW --insecure
'admin:login' logged in successfully
Context 'localhost:8080' updated
- 백업 생성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app/resources$ argocd admin export -n argocd > backup.yaml
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app/resources$ cat backup.yaml | head
apiVersion: v1
data:
resource.customizations.ignoreResourceUpdates.ConfigMap: |
jqPathExpressions:
# Ignore the cluster-autoscaler status
- '.metadata.annotations."cluster-autoscaler.kubernetes.io/last-updated"'
# Ignore the annotation of the legacy Leases election
- '.metadata.annotations."control-plane.alpha.kubernetes.io/leader"'
resource.customizations.ignoreResourceUpdates.Endpoints: |
jsonPointers:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app/resources$ cat backup.yaml | wc -l
1323
"Argo CD 백업은 모든 상태 정보를 YAML로 내보내는 단일 파일입니다."
☁️ 백업 파일 저장 전략
- 실제 운영 환경에서는 백업 파일을 반드시 안전하게 관리해야 합니다.
- Cloud Storage (AWS S3, Azure Blob, Google Cloud Storage 등)에 저장
- 암호화(Encryption) 적용
- 접근 제어(Access Policy) 설정
- 이 파일에는 Kubernetes cluster 인증 정보 등 민감한 데이터가 포함되어 있으므로 보안 관리가 매우 중요합니다.
"백업 파일은 암호화 및 접근 제어가 필수인 민감 자산입니다."
🔁 다른 클러스터에 복원하기
- 새로운 클러스터에 Argo CD를 설치한 뒤, 이전 클러스터의 상태를 그대로 복원할 수 있습니다.
- 기존 클러스터 와 함께 다른 클러스터 생성 안됨
Creating cluster "myk8s2" ...
✓ Ensuring node image (kindest/node:v1.34.0) 🖼
✗ Preparing nodes 📦 📦
Deleted nodes: ["myk8s2-worker" "myk8s2-control-plane"]
ERROR: failed to create cluster: could not find a log line that matches "Reached target .*Multi-User System.*|detected cgroup v1"
- 기존 클러스터 삭제
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app/resources$ kind delete cluster --name myk8s
Deleting cluster "myk8s" ...
Deleted nodes: ["myk8s-worker2" "myk8s-worker" "myk8s-control-plane" "myk8s-worker3"]
- 다른 클러스터 생성
(⎈|N/A:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app/resources$ kind create cluster --name myk8s2 --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 31000
hostPort: 31000
- containerPort: 31001
hostPort: 31001
- containerPort: 31002
hostPort: 31002
- containerPort: 31003
hostPort: 31003
- role: worker
- role: worker
- role: worker
EOF
Creating cluster "myk8s2" ...
✓ Ensuring node image (kindest/node:v1.32.8) 🖼
✓ Preparing nodes 📦 📦 📦 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
✓ Joining worker nodes 🚜
Set kubectl context to "kind-myk8s2"
You can now use your cluster with:
kubectl cluster-info --context kind-myk8s2
Thanks for using kind! 😊
- 새 클러스터에 argo ha 설치
(⎈|kind-myk8s2:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ k8s2 apply -f resources/namespace.yaml
namespace/argocd created
(⎈|kind-myk8s2:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ k8s2 apply -f resources/install.yaml -n argocd
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created
...
- 로컬 머신의 http://localhost:8081 주소를 통해 Argo CD 웹 UI에 접근
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl port-forward svc/argocd-server -n argocd 8081:80 --context kind-myk8s2
Forwarding from 127.0.0.1:8081 -> 8080
Forwarding from [::1]:8081 -> 8080
- Argo CD 초기 관리자 비밀번호
(⎈|kind-myk8s2:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ k8s2 get secret -n argocd argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d ; echo
mfvdvNzs8ErDlcFe

- Argo UI → Git 추가

- 다른 클러스터에 argocd 서버 (http) 로그인
(⎈|kind-myk8s2:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ ARGOPW2=mfvdvNzs8ErDlcFe
(⎈|kind-myk8s2:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ argocd login localhost:8081 --username admin --password $ARGOPW2 --insecure
'admin:login' logged in successfully
Context 'localhost:8081' updated
- 다른 클러스터에서 복원하기
(⎈|kind-myk8s2:N/A) ssoon@DESKTOP-72C919S:~/my-sample-app$ argocd admin import -n argocd - < backup.yaml
import process started argocd
/ConfigMap argocd-cm in namespace argocd updated
/ConfigMap argocd-rbac-cm in namespace argocd updated
/ConfigMap argocd-ssh-known-hosts-cm in namespace argocd updated
/ConfigMap argocd-tls-certs-cm in namespace argocd updated
/Secret argocd-secret in namespace argocd updated
argoproj.io/Application argocd in namespace argocd created
Import process completed successfully in namespace argocd at 2025-11-08T17:38:27+09:00, duration: 99.63155ms
- admin 계정의 암호도 기존 k8s 정보로 변경됨!

"복원 시 CRD와 기본 설치 구성은 먼저 준비되어야 하며, 그 후에 백업을 import 합니다."
🔄 복구 자동화 및 운영 팁
- 정기적으로 백업 명령을 자동화(CronJob 등)
- 백업 파일을 여러 지역(Region)에 분산 저장
- 복원 테스트(restore drill)를 정기적으로 수행
- 운영 중 언제든 복구할 수 있도록 Runbook을 문서화하고,야간(2:00 A.M.)이나 근무 시간(2:00 P.M.) 어느 때라도 동일한 절차로 수행 가능해야 합니다.
"Disaster Recovery의 핵심은 자동화된 백업과 정기적인 복원 테스트입니다."
📌 핵심 요약
단계 주요 내용 핵심 포인트
| State 관리 | Kubernetes 리소스에 저장 (Secrets, Applications 등) | DB는 없지만 완전한 Stateless는 아님 |
| CLI 설치 | argocd admin 명령으로 백업/복원 지원 | 운영 자동화에 필수 도구 |
| Backup | argocd admin export | YAML 파일로 전체 상태 저장 |
| 보안 관리 | Cloud 저장소 + 암호화 + 접근 제어 | 민감 정보 보호 필수 |
| Restore | argocd admin import | CRD 및 기본 설치 후 복원 수행 |
| 운영 팁 | 자동화, 정기 테스트, Runbook 문서화 | 예측 가능한 복구 프로세스 확보 |
"Argo CD Disaster Recovery는 데이터 보호와 신속한 복원을 위한 운영의 기본 전략이며, GitOps 환경의 안정성을 보장합니다."
Figure: Disaster Recovery Flow
[Argo CD Cluster A] → argocd admin export → [S3/Cloud Backup] ↓ argocd admin import → [Argo CD Cluster B]
'CICD Study [1기]' 카테고리의 다른 글
| 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 |
| Argo CD in Practice – 1) GitOps와 쿠버네티스 (0) | 2025.10.19 |
Comments