Ssoon

Argo CD in Practice – 2) Argo CD 시작하기 본문

CICD Study [1기]

Argo CD in Practice – 2) Argo CD 시작하기

구구달스 2025. 10. 19. 15:18

 

🚀 Getting Started with Argo CD

  • Argo CD는 Kubernetes 기반의 GitOps Continuous Delivery 도구입니다.

🧩 What is Argo CD?

  • 애플리케이션 개발 환경은 일반적으로 development, test, staging, production으로 나뉘며, Kubernetes에서는 이를 namespace나 별도의 cluster로 분리해 운영합니다.
  • 하지만 이 방식에는 한 가지 큰 문제점이 있습니다. 시간이 지나면서 각 환경의 설정이 조금씩 달라지는 Configuration Drift가 발생합니다. 즉, 개발 환경의 최신 설정이 운영 환경에 자동으로 반영되지 않아 수동 관리가 필요해집니다.
  • 이를 해결하기 위해 Helm, Kustomize, Jsonnet 같은 툴을 사용해보지만, 여전히 여러 버전을 관리하고 추적하는 것은 쉽지 않습니다. 👉 이런 문제를 깔끔하게 해결하는 접근법이 바로 GitOps입니다.
  • GitOps에서는 모든 인프라와 애플리케이션 설정을 Git 저장소에 보관하고, 이 Git 저장소를 단일 Source of Truth로 사용합니다. 변경사항은 Pull Request를 통해 검토되며, Git에 반영된 설정이 자동으로 cluster에 적용됩니다.

"Argo CD는 이 GitOps 철학을 완벽하게 구현하는 도구입니다."


⚙️ Core Concepts and Vocabulary

  • Argo CD의 핵심은 reconciliation loop입니다. 즉, Git에 정의된 desired state(목표 상태) 와 cluster의 live state(실제 상태) 를 지속적으로 비교하고, 차이가 발생하면 자동으로 일치시키는 과정입니다.

🔄 Argo CD Reconciliation Loop

Git Repository ──> (Helm Template) ──> Manifest ──> Kubernetes Cluster
       ↑                                               │
       └─────────────────── Compare & Sync ────────────┘
  • Argo CD는 helm install이 아닌 kubectl apply를 사용합니다.
    이는 Argo CD가 특정 템플릿 툴에 종속되지 않고, 단순히 Git에 선언된 상태를 cluster에 적용하는 컨트롤러이기 때문입니다.

"Reconciliation은 Argo CD의 핵심 동작 원리로, Git의 상태를 항상 cluster에 반영하는 과정입니다."


📚 Argo CD Vocabulary

용어 설명

Application 하나의 애플리케이션을 구성하는 Kubernetes 리소스 집합
Application Source Type Helm, Kustomize, Jsonnet 등 manifest 생성 도구
Target State Git에 정의된 원하는 상태
Live State 현재 cluster에 배포된 실제 상태
Sync Status Live State가 Target State와 일치하는지 여부
Sync Operation Target State로 동기화하는 실제 과정
Health Status 애플리케이션이 정상 동작 중인지 여부

"Application은 Argo CD에서 관리 단위이며, Sync는 GitOps의 핵심 프로세스입니다."


🏗️ Argo CD Architecture

  • Argo CD는 Kubernetes Controller 형태로 동작합니다. 즉, cluster의 상태를 감시하고, 필요 시 변경을 적용하여 Desired State를 유지합니다.

🧠 Core Components

1️⃣ API Server

  • Argo CD의 중심 API 인터페이스
  • Web UI, CLI, CI/CD, Argo Events 등과 상호작용
  • 주요 기능:
    • Application 관리 및 상태 보고
    • Git Repo 및 Cluster 관리
    • Authentication & SSO 지원
    • RBAC 권한 정책 관리

2️⃣ Repository Server

  • Git Repository의 local cache 유지
  • 요청 시 Kubernetes manifest를 생성 (Helm, Kustomize 등 템플릿 기반)
  • 주요 입력값:
    • Repo URL
    • Git Revision
    • Application Path
    • Helm Values 등

3️⃣ Application Controller

  • Live State ↔ Target State 비교 및 자동 동기화
  • Drift 발생 시 상태를 복원
  • Lifecycle Hooks 실행 (PreSync, PostSync 등)

"Application Controller는 Argo CD의 두뇌이며, Git과 Kubernetes 사이를 연결하는 핵심 엔진입니다."


🗺️ Architectural Overview

[Git Repository] → [Repository Server] → [API Server] → [Application Controller] → [Kubernetes Cluster]
                             ↑                                                │
                             └─────────────── CLI / UI / Webhook ─────────────┘

Argo CD의 Sync Trigger 방식

  • UI에서 수동으로 Sync
  • CLI (argocd app sync myapp)
  • Git Webhook (GitHub, GitLab, Bitbucket 등)

"Argo CD는 Git 변경을 감지해 자동 또는 수동으로 Sync를 수행하며, 완전한 GitOps 워크플로우를 구현합니다."


🧱 Argo CD Core Objects

Argo CD는 Kubernetes의 CRD(Custom Resource Definition) 로 확장되어 동작합니다.

🧩 Application (CRD)

  • Argo CD는 실제 쿠버네티스 클러스터에 배포하려는 애플리케이션의 인스턴스를 Application 이라는 CRD로 구현
    • metadata.name: guestbook
      Argo CD UI에서 표시될 애플리케이션 이름입니다.
    • spec.project: default
      default 프로젝트에 속한 애플리케이션으로 등록됩니다. 만약 dev, prd, applications 등의 프로젝트를 사용하고 싶다면 이 값을 변경해야 합니다.
    • source.repoURL
      애플리케이션 소스가 위치한 Git 리포지토리입니다. 여기서는 Argo CD 공식 예제 리포지토리를 사용하고 있습니다.
    • source.path: guestbook
      리포지토리 내에서 guestbook 디렉토리를 기준으로 K8s 매니페스트를 찾습니다.
    • destination.server
      현재 클러스터의 API 서버 주소입니다.
    • destination.namespace: guestbook
      애플리케이션이 배포될 네임스페이스입니다. 이 있습니다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: guestbook

🧩 AppProject (CRD)

  • 애플리케이션처럼 앱 프로젝트 CRD는 태그 지정과 같이 관련 있는 애플리케이션을 논리적으로 그룹화
  • 실무에서는 애플리케이션과 유틸리티 서비스가 분리
    • sourceRepos: ['*']
      • 모든 Git 리포지토리에서 소스를 허용합니다.
      • 보안상 민감한 환경에서는 특정 리포지토리만 허용하는 것이 좋습니다.
    • destinations:
      • guestbook 네임스페이스와 https://kubernetes.default.svc 서버로 배포를 허용합니다.
      • 이는 현재 클러스터 내의 기본 API 서버를 의미합니다.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: applications
  namespace: argocd
spec:
  sourceRepos:
    - '*'
  destinations:
    - namespace: guestbook
      server: https://kubernetes.default.svc

🔐 Repository Credentials (Secret)

  • 실제 운영에서는 프라이빗 리포지터리를 사용하기 때문에 Argo CD가 해당 리포지터리에 접근하기 위해서는 접근 가능한 자격 증명이 필요
  • Argo CD가 해당 리포지터리에 접근하기 위해서는 접근 가능한 자격 증명이 필요
  • Argo CD는 이를 쿠버네티스 시크릿과 컨피그맵을 사용해 해결
  • 따라서 ‘argocd.argoproj.io/secret-type: repository ’같은 특정 쿠버네티스 레이블을 포함해 쿠버네티스 시크릿 리소스를 생성
    • metadata.name: Argo CD에서 이 리포지토리를 식별할 때 사용하는 이름입니다.
    • labels.argocd.argoproj.io/secret-type: repository: 이 Secret이 Git 리포지토리 인증 정보임을 나타냅니다.
    • stringData.url: 등록할 Git 리포지토리의 주소입니다.
    • stringData.sshPrivateKey: 해당 리포지토리에 접근하기 위한 SSH 개인 키입니다.
apiVersion: v1
kind: Secret
metadata:
  name: private-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  url: https://github.com/private/repo.git
  sshPrivateKey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----

🔐 Cluster Credentials (Secret)

  • Argo CD가 여러 클러스터를 관리하고 Argo CD가 이미 실행 중인 클러스터에 포함되지 않은 경우 다른 쿠버네티스 클러스터에 대한 액세스 권한을 얻어야 한다.
  • 리포지터리 자격 증명과 클러스터 자격 증명의 차이점은 시크릿 유형이 다르기 때문에 쿠버네티스 레이블이 다르다는 것
    • labels.argocd.argoproj.io/secret-type: cluster: 이 Secret이 클러스터 등록용임을 나타냅니다.
    • stringData.server: 등록할 외부 클러스터의 API 서버 주소입니다.
    • stringData.config:
      • bearerToken: 해당 클러스터에 접근하기 위한 인증 토큰 (여기서는 비어 있음)
      • tlsClientConfig.insecure: false로 설정되어 있어 TLS 인증서를 검증합니다. 만약 자체 서명 인증서를 사용하는 경우 true로 설정하거나 caData를 추가해야 합니다.
apiVersion: v1
kind: Secret
metadata:
  name: mycluster-secret
  labels:
    argocd.argoproj.io/secret-type: cluster
stringData:
  server: https://mycluster.com
  config: |
    {
      "bearerToken": "",
      "tlsClientConfig": {"insecure": false}
    }

"Argo CD의 모든 구성 요소는 Kubernetes 리소스로 정의되어 완전한 선언적 관리가 가능합니다."


  Argo CD 설치 by Helm

  • 네임스페이스 생성 &  Argo CD Helm 설치 설정 파일 생성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ kubectl create ns argocd
cat <<EOF > argocd-values.yaml
server:
  service:
    type: NodePort
    nodePortHttps: 30002
  extraArgs:
    - --insecure  # HTTPS 대신 HTTP 사용
EOF
namespace/argocd create
  • Helm 리포지토리 추가 & Argo CD 설치
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ helm repo add argo https://argoproj.github.io/argo-helm
"argo" has been added to your repositories
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ helm install argocd argo/argo-cd --version 9.0.5 -f argocd-values.yaml --namespace argocd
NAME: argocd
LAST DEPLOYED: Sat Nov  8 14:39:34 2025
NAMESPACE: argocd
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
In order to access the server UI you have the following options:

1. kubectl port-forward service/argocd-server -n argocd 8080:443

    and then open the browser on http://localhost:8080 and accept the certificate

2. enable ingress in the values file `server.ingress.enabled` and either
      - Add the annotation for ssl passthrough: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-1-ssl-passthrough
      - Set the `configs.params."server.insecure"` in the values file and terminate SSL at your ingress: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-2-multiple-ingress-objects-and-hosts


After reaching the UI the first time you can login with username: admin and the random password generated during the installation. You can find the password by running:

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

(You should delete the initial secret afterwards as suggested by the Getting Started Guide: https://argo-cd.readthedocs.io/en/stable/getting_started/#4-login-using-the-cli)
  • Krew 설치 & rolesum 플러그인 설치

 

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ (
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)
++ mktemp -d
+ cd /tmp/tmp.YKLjsYB5tE
++ uname
++ tr '[:upper:]' '[:lower:]'
+ OS=linux
++ uname -m
++ sed -e s/x86_64/amd64/ -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/'
+ ARCH=amd64
+ KREW=krew-linux_amd64
+ curl -fsSLO https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-linux_amd64.tar.gz
+ tar zxvf krew-linux_amd64.tar.gz
./._LICENSE
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.com.apple.provenance'
./LICENSE
./._krew-linux_amd64
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.com.apple.provenance'
./krew-linux_amd64
+ ./krew-linux_amd64 install krew
Adding "default" plugin index from https://github.com/kubernetes-sigs/krew-index.git.
Updated the local copy of plugin index.
Installing plugin: krew
Installed plugin: krew
\
 | Use this plugin:
 |      kubectl krew
 | Documentation:
 |      https://krew.sigs.k8s.io/
 | Caveats:
 | \
 |  | krew is now installed! To start using kubectl plugins, you need to add
 |  | krew's installation directory to your PATH:
 |  |
 |  |   * macOS/Linux:
 |  |     - Add the following to your ~/.bashrc or ~/.zshrc:
 |  |         export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
 |  |     - Restart your shell.
 |  |
 |  |   * Windows: Add %USERPROFILE%\.krew\bin to your PATH environment variable
 |  |
 |  | To list krew commands and to get help, run:
 |  |   $ kubectl krew
 |  | For a full list of available plugins, run:
 |  |   $ kubectl krew search
 |  |
 |  | You can find documentation at
 |  |   https://krew.sigs.k8s.io/docs/user-guide/quickstart/.
 | /
/
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ echo 'export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc # Or source ~/.zshrc, depending on your shell
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl krew version
OPTION            VALUE
GitTag            v0.4.5
GitCommit         e7e5b61
IndexURI          https://github.com/kubernetes-sigs/krew-index.git
BasePath          /home/ssoon/.krew
IndexPath         /home/ssoon/.krew/index/default
InstallPath       /home/ssoon/.krew/store
BinPath           /home/ssoon/.krew/bin
DetectedPlatform  linux/amd64
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl krew install rolesum
Updated the local copy of plugin index.
Installing plugin: rolesum
Installed plugin: rolesum
\
 | Use this plugin:
 |      kubectl rolesum
 | Documentation:
 |      https://github.com/Ladicle/kubectl-rolesum
/
WARNING: You installed plugin "rolesum" from the krew-index plugin repository.
   These plugins are not audited for security by the Krew maintainers.
   Run them at your own risk.

🔐 서비스 계정: argocd-server (네임스페이스: argocd)

📦 관련된 권한 바인딩:

  1. RoleBinding (RB): argocd/argocd-server
    • 네임스페이스 내에서만 적용되는 권한
    • 주요 리소스에 대해 거의 모든 권한 (Get, List, Watch, Create, Update, Patch, Delete) 보유
    • 리소스:
      • applications.argoproj.io
      • applicationsets.argoproj.io
      • appprojects.argoproj.io
      • configmaps
      • secrets
      • events (읽기만 가능)
  2. ClusterRoleBinding (CRB): /argocd-server
    • 클러스터 전체에 적용되는 권한
    • 일부 리소스에 대해 제한된 권한 보유
    • 리소스:
      • .*: 모든 리소스에 대해 Get, Patch, Delete 가능
      • applications.argoproj.io, applicationsets.argoproj.io: 읽기 및 일부 쓰기 권한
      • pods, pods/log: Get만 가능
      • jobs.batch, workflows.argoproj.io: Create만 가능
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl rolesum -n argocd argocd-server
ServiceAccount: argocd/argocd-server
Secrets:

Policies:
• [RB] argocd/argocd-server ⟶  [R] argocd/argocd-server
  Resource                     Name  Exclude  Verbs  G L W C U P D DC
  applications.argoproj.io     [*]     [-]     [-]   ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✖
  applicationsets.argoproj.io  [*]     [-]     [-]   ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✖
  appprojects.argoproj.io      [*]     [-]     [-]   ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✖
  configmaps                   [*]     [-]     [-]   ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✖
  events                       [*]     [-]     [-]   ✖ ✔ ✖ ✔ ✖ ✖ ✖ ✖
  secrets                      [*]     [-]     [-]   ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✖


• [CRB] */argocd-server ⟶  [CR] */argocd-server
  Resource                     Name  Exclude  Verbs  G L W C U P D DC
  *.*                          [*]     [-]     [-]   ✔ ✖ ✖ ✖ ✖ ✔ ✔ ✖
  applications.argoproj.io     [*]     [-]     [-]   ✔ ✔ ✔ ✖ ✔ ✖ ✖ ✖
  applicationsets.argoproj.io  [*]     [-]     [-]   ✔ ✔ ✔ ✖ ✔ ✖ ✖ ✖
  events                       [*]     [-]     [-]   ✖ ✔ ✖ ✔ ✖ ✖ ✖ ✖
  jobs.batch                   [*]     [-]     [-]   ✖ ✖ ✖ ✔ ✖ ✖ ✖ ✖
  pods                         [*]     [-]     [-]   ✔ ✖ ✖ ✖ ✖ ✖ ✖ ✖
  pods/log                     [*]     [-]     [-]   ✔ ✖ ✖ ✖ ✖ ✖ ✖ ✖
  workflows.argoproj.io        [*]     [-]     [-]   ✖ ✖ ✖ ✔ ✖ ✖ ✖ ✖
  • 최초 접속 암호 확인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
FUOW796bstRc7TXt
  • Argo CD 웹 접속


 

🌐 첫 애플리케이션 실행

  • Argo CD 애플리케이션을 Kubernetes 리소스로 직접 정의하여 kubectl apply로 생성
  • Helm CLI를 쓰는 대신 YAML로 선언적으로 관리
    • Helm 차트 기반 애플리케이션: helm-guestbook 경로의 Helm 차트를 사용
    • 자동 동기화 활성화:
      • enabled: true: 변경 사항 자동 반영
      • prune: true: Git에 없는 리소스 자동 삭제
      • selfHeal: true: 리소스가 변경되면 자동 복구
    • 네임스페이스 자동 생성: CreateNamespace=true
    • Git 리포지토리에서 HEAD 기준으로 배포
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ 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
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/guestbook created

 

  • 서비스 타입 변경: ClusterIP → NodePort : 변경되지 않는다
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ kubectl get svc -n guestbook
NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
guestbook-helm-guestbook   ClusterIP   10.96.54.206   <none>        80/TCP    72s
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ kubectl patch svc -n guestbook guestbook-helm-guestbook -p '{"spec":{"type":"NodePort","ports":[{"port":80,"targetPort":80,"nodePort":30003}]}}'
service/guestbook-helm-guestbook patched
  • Self Heal Disable
    •  Argo CD는 리소스가 클러스터에서 변경되더라도 자동으로 복구하지 않습니다.

 

  • nodeport 변경 시도 : 변경된다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ kubectl get svc -n guestbook
NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
guestbook-helm-guestbook   ClusterIP   10.96.54.206   <none>        80/TCP    4m44s
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ 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) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ kubectl get svc -n guestbook
NAME                       TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
guestbook-helm-guestbook   NodePort   10.96.54.206   <none>        80:30003/TCP   4m50s
  • App 삭제
kubectl delete applications -n argocd guestbook

🌐 Argo CLI 설치

  • Argo CD CLI 최신 버전 설치
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ VERSION=$(curl -L -s https://raw.githubusercontent.com/argoproj/argo-cd/stable/VERSION)
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/download/v$VERSION/argocd-linux-amd64
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
[sudo] password for ssoon:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ rm argocd-linux-amd64
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd version --client
argocd: v3.2.0+66b2f30
  BuildDate: 2025-11-04T15:21:01Z
  GitCommit: 66b2f302d91a42cc151808da0eec0846bbe1062c
  GitTreeState: clean
  GoVersion: go1.25.0
  Compiler: gc
  Platform: linux/amd64
  • argocd 서버 (http) 로그인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd login 127.0.0.1:30002 --plaintext
Username: admin
Password:
'admin:login' logged in successfully
Context '127.0.0.1:30002' updated

🌐Argo CLI로 애플리케이션 배포

 

  • Argo CD를 통해 Helm 기반 애플리케이션을 생성
    • guestbook: 생성할 Argo CD 애플리케이션 이름
    • --repo: Git 리포지토리 URL (애플리케이션 소스)
    • --path: 리포지토리 내 Helm 차트 경로
    • --dest-server: 애플리케이션을 배포할 Kubernetes API 서버 주소
    • --dest-namespace: 애플리케이션이 배포될 네임스페이스 (guestbook)
    • --values values.yaml: Helm 차트에 적용할 사용자 정의 값 파일
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path helm-guestbook \
  --dest-server https://kubernetes.default.svc --dest-namespace guestbook --values values.yaml
application 'guestbook' created
  • guestbook 애플리케이션이 OutOfSync 상태이며, Health는 Missing으로 표시
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd app list
NAME              CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                 PATH            TARGET
argocd/guestbook  https://kubernetes.default.svc  guestbook  default  OutOfSync  Missing  Manual      <none>      https://github.com/argoproj/argocd-example-apps.git  helm-guestbook

  •  argocd app sync : guestbook 애플리케이션이 성공적으로 동기화되었고, 리소스들이 생성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd app sync argocd/guestbook
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME        STATUS    HEALTH        HOOK  MESSAGE
2025-11-08T15:06:12+09:00            Service   guestbook  guestbook-helm-guestbook  OutOfSync  Missing  
2025-11-08T15:06:12+09:00   apps  Deployment   guestbook  guestbook-helm-guestbook  OutOfSync  Missing  
2025-11-08T15:06:12+09:00            Service   guestbook  guestbook-helm-guestbook  OutOfSync  Missing              service/guestbook-helm-guestbook created
2025-11-08T15:06:12+09:00   apps  Deployment   guestbook  guestbook-helm-guestbook  OutOfSync  Missing              deployment.apps/guestbook-helm-guestbook created
2025-11-08T15:06:12+09:00   apps  Deployment   guestbook  guestbook-helm-guestbook    Synced  Progressing              deployment.apps/guestbook-helm-guestbook created
2025-11-08T15:06:12+09:00            Service   guestbook  guestbook-helm-guestbook    Synced  Healthy                  service/guestbook-helm-guestbook created

Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          guestbook
URL:                https://argocd.example.com/applications/argocd/guestbook
Source:
- Repo:             https://github.com/argoproj/argocd-example-apps.git
  Target:
  Path:             helm-guestbook
  Helm Values:      values.yaml
SyncWindow:         Sync Allowed
Sync Policy:        Manual
Sync Status:        Synced to  (0d521c6)
Health Status:      Progressing

Operation:          Sync
Sync Revision:      0d521c6e049889134f3122eb32d7ed342f43ca0d
Phase:              Succeeded
Start:              2025-11-08 15:06:12 +0900 KST
Finished:           2025-11-08 15:06:12 +0900 KST
Duration:           0s
Message:            successfully synced (all tasks run)

GROUP  KIND        NAMESPACE  NAME                      STATUS  HEALTH       HOOK  MESSAGE
       Service     guestbook  guestbook-helm-guestbook  Synced  Healthy            service/guestbook-helm-guestbook created
apps   Deployment  guestbook  guestbook-helm-guestbook  Synced  Progressing        deployment.apps/guestbook-helm-guestbook created

  • 다음 실습을 위해 리소스 삭제
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ helm uninstall -n argocd argocd && kubectl delete ns argocd
These resources were kept due to the resource policy:
[CustomResourceDefinition] applications.argoproj.io
[CustomResourceDefinition] applicationsets.argoproj.io
[CustomResourceDefinition] appprojects.argoproj.io

release "argocd" uninstalled
namespace "argocd" deleted

"Helm chart를 이용한 declarative Application 정의는 GitOps의 가장 기본적인 예시입니다."


🧭 Argo CD Autopilot

  • Argo CD Autopilot은 Argo CD의 GitOps 설정을 자동화하는 툴입니다.
  • Argo CD가 스스로를 GitOps 방식으로 관리하도록 구성합니다.

🔧 주요 기능

  • Argo CD 설치 및 self-management 구조 생성
  • Git Repository 구조 자동 구성
  • 여러 환경(dev/stage/prod) 관리
  • Disaster Recovery 및 failover 지원
  • 향후 Secret 암호화 지원 예정

"Argo CD Autopilot은 Argo CD의 bootstrap부터 환경 관리까지 자동화합니다."

💻 argocd-autopilot CLI 설치

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ VERSION=$(curl --silent "https://api.github.com/repos/argoproj-labs/argocd-autopilot/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ curl -L --output - https://github.com/argoproj-labs/argocd-autopilot/releases/download/"$VERSION"/argocd-autopilot-linux-amd64.tar.gz | tar zx
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 71.5M  100 71.5M    0     0  19.4M      0  0:00:03  0:00:03 --:--:-- 22.4M
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ mv ./argocd-autopilot-* /usr/local/bin/argocd-autopilot
mv: cannot move './argocd-autopilot-linux-amd64' to '/usr/local/bin/argocd-autopilot': Permission denied
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ sudo mv ./argocd-autopilot-* /usr/local/bin/argocd-autopilot
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd-autopilot version
v0.4.20

🧩 Git 레포지토리 (GitOps 환경으로 사용할 레포지토리) & Git Token 준비

  • Git 레포지토리 생성 : Private

  • Git Personal access tokens 생성 : scope(repo 체크)

  • 매니페스트를 푸시하고 깃 리포지터리 안에 필요한 구조를 생성
  • Argo CD Autopilot을 통해 GitOps 환경이 성공적으로 부트스트랩
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ export GIT_TOKEN=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
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ export GIT_REPO=https://github.com/kschoi728/autopliot.git
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd-autopilot repo bootstrap
INFO cloning repo: https://github.com/kschoi728/autopliot.git
INFO empty repository, initializing a new one with specified remote
WARNING --provider not specified, assuming provider from url: github
INFO using revision: "", installation path: ""
INFO using context: "kind-myk8s", namespace: "argocd"
INFO applying bootstrap manifests to cluster...
namespace/argocd created
...
waiting for argo-cd to be ready.
...
INFO pushing bootstrap manifests to repo
Resolving deltas: 100% (1/1), done.
INFO applying argo-cd bootstrap application
I1108 15:19:31.505150   20978 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: hVFuxxqjRbKg3q2w
INFO run:

    kubectl port-forward -n argocd svc/argocd-server 8080:80
  • kubectl port-forward 명령이 정상적으로 실행되어 Argo CD 서버에 로컬 포트 8080을 통해 접근
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl port-forward -n argocd svc/argocd-server 8080:80
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
  • 웹 접속


✅ Project 생성, Application 추가

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd-autopilot project create dev
INFO cloning git repository: https://github.com/kschoi728/autopliot.git
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Compressing objects: 100% (13/13), done.
Total 17 (delta 1), reused 17 (delta 1), pack-reused 0 (from 0)
INFO using revision: "", installation path: "/"
INFO pushing new project manifest to repo
INFO project created: 'dev'
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd-autopilot project create prd
INFO cloning git repository: https://github.com/kschoi728/autopliot.git
Enumerating objects: 18, done.
Counting objects: 100% (18/18), done.
Compressing objects: 100% (15/15), done.
Total 18 (delta 2), reused 17 (delta 1), pack-reused 0 (from 0)
INFO using revision: "", installation path: "/"
INFO pushing new project manifest to repo
INFO project created: 'prd'
  • dev, prd, 그리고 기본 default 프로젝트가 모두 정상적으로 생성된 상태입니다. argocd-autopilot 명령어를 통해 GitOps 방식으로 프로젝트가 잘 반영
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ kubectl get appprojects.argoproj.io -n argocd
NAME      AGE
default   10m
dev       35s
prd       35s

 

  • Application 추가 (hello-world1, hello-world2)
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ 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/kschoi728/autopliot.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) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ 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/kschoi728/autopliot.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

  • Application 삭제 (hello-world2)
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ argocd-autopilot app delete hello-world2 -p prd
INFO cloning git repository: https://github.com/kschoi728/autopliot.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) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch02$ kind delete cluster --name myk8s
Deleting cluster "myk8s" ...
Deleted nodes: ["myk8s-control-plane"]

🔁 Synchronization Principles

  • Argo CD의 Sync Phase는 다음 단계로 구성됩니다.

🪄 Resource Hooks

Hook Type 설명

PreSync Sync 전에 실행 (예: DB Migration)
Sync 실제 배포 단계
PostSync 배포 완료 후 테스트 및 알림
SyncFail 실패 시 정리 작업 수행
apiVersion: batch/v1
kind: Job
metadata:
  annotations:
    argocd.argoproj.io/hook: PreSync

"Resource Hooks를 통해 배포 전/후 동작을 자유롭게 제어할 수 있습니다."


🌊 Sync Waves

  • Sync 과정에서 리소스 배포 순서를 제어할 수 있습니다.
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "5"
  • Sync 순서는 다음 순서로 정해집니다.
  1. Phase (PreSync → Sync → PostSync)
  2. Wave (낮은 값부터)
  3. Kubernetes Kind
  4. Resource Name

"Sync Waves를 이용하면 복잡한 배포 순서를 논리적으로 제어할 수 있습니다."


📌 핵심 요약

  • Argo CD는 Kubernetes를 위한 GitOps 기반 CD 도구이다.
  • Git Repository를 단일 Source of Truth로 삼고 cluster 상태를 자동 동기화한다.
  • 주요 구성요소는 API Server, Repository Server, Application Controller이다.
  • 모든 설정은 Kubernetes CRD로 선언적으로 관리된다.
  • Helm을 통해 Argo CD를 쉽게 설치하고, CLI/UI로 관리 가능하다.
  • Autopilot을 사용하면 Argo CD를 GitOps 방식으로 스스로 관리할 수 있다.
  • Resource HooksSync Waves로 정교한 배포 순서 제어가 가능하다.

"Argo CD는 GitOps를 실현하는 가장 직관적이고 강력한 도구로, DevOps 자동화의 핵심이다."


Comments