[ Infra ]/Data Platform

[Data Platform] ArgoCD 구축 가이드 (Helm + Private Registry + Ingress 구성)

환이s 2026. 7. 6. 10:55
728x90
반응형


Intro

 

안녕하세요. 환이s입니다 👋

 

지난 글에서는 데이터 레이크하우스 플랫폼의

일곱 번째 스택으로 Superset을 Kubernetes 위에 구축하고

Trino와 연동해서 Delta Lake 데이터를 시각화하는 과정을 정리해 봤습니다.

 

이번 글에서는 여덟 번째 스택,

ArgoCDKubernetes 환경에 구축하고

플랫폼 전체를 GitOps 방식으로 관리하기 위한 기반을 구성하는 과정을 정리해보려고 합니다.

 

지금까지

Kafka → Spark → Delta Lake → Trino → Superset 까지 구축했다면,

이제 이 모든 스택을 코드로 관리하고 자동으로 배포하는 도구가 필요합니다.

 

그 역할을 담당하는 것이 바로 ArgoCD입니다.

 

이번 글에서는

  • Harbor private registry에서 이미지와 Helm Chart를 가져오는 방법
  • Helm으로 ArgoCD를 설치하는 방법
  • MetalLB + ingress-nginx + sslip.io로 Web UI에 접근하는 방법
  • Secret과 ConfigMap으로 저장소 인증, 계정, CRD health check를 구성하는 방법
  • 설치 후 검증하는 방법

까지 순서대로 확인해 보겠습니다.


1. ArgoCD 아키텍처 개요

 

본격적인 설치에 앞서,

이번 구성의 전체 아키텍처를 먼저 이해하는 것이 중요합니다.

 

[웹 접근 경로]

브라우저
  ↓
argocd.192.168.2.240.sslip.io
  ↓ (MetalLB → ingress-nginx)
argocd-server:80

 

[GitOps 동기화 경로]

ArgoCD (application-controller)
  ↓ polling (3분 간격)
Git 저장소 (Gitea)
  ↓ 변경 감지 시
클러스터 자동 동기화

 

각 컴포넌트의 역할은 아래와 같습니다.

컴포넌트 역할
MetalLB ingress-nginx에 External IP(192.168.2.240) 할당
ingress-nginx sslip.io 도메인을 ArgoCD 서버로 라우팅
Harbor Private 이미지 및 Helm Chart 레지스트리
ArgoCD Git 저장소를 기반으로 클러스터 상태를 자동 동기화

 

즉, 여기서 확인할 수 있는 핵심은

ArgoCD는 Git 저장소를 단일 진실의 원천(Single Source of Truth)으로 삼아 클러스터 상태를 코드와 항상 일치시킨다는 점입니다.


2. 설치 순서

 

이번 구축에서 사용하는 디렉토리 구조는 아래와 같습니다.

 

bootstrap/
└── 03_argocd/
    ├── helm/
    │   ├── install.sh                      # 설치 스크립트
    │   └── values.yaml                     # Helm values
    └── manifests/
        ├── 10_ingress_argocd.yaml          # Ingress 설정
        ├── 20_repo_secret.yaml             # Git 저장소 인증 Secret
        ├── 30_root_app.yaml                # platform-root Application
        ├── 35_webapps_root.yaml            # webapps-root Application
        ├── 40_argocd_cm.yaml               # ConfigMap (계정, CephCluster health check)
        ├── 50_argocd_tls_certs_cm.yaml     # Harbor TLS 인증서 신뢰 설정
        ├── 60_harbor_repo_secret.yaml      # Harbor OCI 레지스트리 인증 Secret
        └── 70_argocd_secret.yaml           # RBAC 권한 설정

 

설치 순서는 아래와 같습니다.

 

values.yaml 작성 → Helm 설치 → manifests 적용 (Ingress, Secret, ConfigMap) → 설치 후 검증


3. values.yaml 설정

 

먼저 공식 이미지를 기준으로 기본 설정을 살펴보겠습니다.

 

global:
  image:
    repository: quay.io/argoproj/argocd
    tag: v3.3.4

redis:
  image:
    repository: redis
    tag: 7

dex:
  enabled: false   # SSO 인증관련 서비스 사용여부

server:
  service:
    type: NodePort
    nodePortHttp: 30010

configs:
  params:
    server.insecure: true       # ArgoCD 서버를 HTTP 모드로 실행

 

주요 설정 포인트는 아래와 같습니다.

 

설정 설명
dex.enabled: false - LDAP/OAuth SSO를 쓰지 않는 경우 비활성화
server.insecure: true - ArgoCD 서버가 HTTP로 동작.
- TLS 없이 Ingress에서 직접 80 포트로 수신
글쓴이는 외부 인터넷이 차단된 온프레미스 환경에서
Harbor private registry를 운영하는 목적 기반으로 하고 있어,
아래와 같이 이미지 경로와 Helm Chart 레지스트리를 Harbor 기준으로 변경해서 사용하고 있습니다.
global:
  image:
    repository: harbor.local/library/argocd/argocd
    tag: v3.3.4

redis:
  image:
    repository: harbor.local/library/redis/redis
    tag: 7

dex:
  enabled: false   # SSO 인증관련 서비스 사용여부

server:
  service:
    type: NodePort
    nodePortHttp: 30010

configs:
  params:
    helm.oci.enabled: true      # OCI 형식 Helm 차트 사용
    server.insecure: true       # ArgoCD 서버를 HTTP 모드로 실행

repoServer:
  env:
    - name: HELM_EXPERIMENTAL_OCI
      value: "1"

  cm:
    url: http://argocd.192.168.2.240.sslip.io

  repositories:
    harbor-helm:
      url: harbor.local/helm-chart
      type: helm
      name: harbor

  tls:
    certificates:
      harbor.local: |
        -----BEGIN CERTIFICATE-----
        # Harbor CA 인증서 내용
        -----END CERTIFICATE-----

 

 

즉, 여기서 확인할 수 있는 핵심은

Git 저장소 인증과 Harbor OCI 레지스트리 인증values.yaml 외에 별도 Secret으로도 등록한다는 점입니다.

 

이 부분은 이후 섹션에서 하나씩 확인해 보겠습니다.


4. Helm 설치 스크립트

#!/bin/bash

set -e

NAMESPACE=argocd
CHART=oci://harbor.local/helm-chart/argo-cd
VERSION=9.4.14

echo "== namespace 생성 =="
kubectl create namespace $NAMESPACE --dry-run=client -o yaml | kubectl apply -f -

echo "== harbor login =="
helm registry login harbor.local

echo "== argocd 설치 =="
helm upgrade --install argocd $CHART \
  --version $VERSION \
  -n $NAMESPACE \
  -f values.yaml

echo "== manifests 적용 =="
kubectl apply -f ../manifests/

echo "== 완료 =="

 

스크립트 구조 설명은 아래와 같습니다.

명령어 설명
--dry-run=client -o yaml | kubectl apply -f - namespace가 이미 존재해도 에러 없이 처리
helm registry login Harbor OCI 레지스트리 인증
helm upgrade --install 없으면 설치, 있으면 업그레이드(idempotent)
kubectl apply -f ../manifests/ Secret, ConfigMap, Ingress 등 추가 리소스 일괄 적용

 

💡 참고: set -e 옵션으로 중간에 에러가 발생하면 스크립트가 즉시 종료됩니다. 설치 실패 시 어느 단계에서 멈췄는지 확인하세요.

5. Ingress 설정

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Authorization, Content-Type"
spec:
  ingressClassName: nginx
  rules:
  - host: argocd.192.168.2.240.sslip.io
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              number: 80

 

sslip.io

별도 DNS 설정 없이 IP가 포함된 도메인을 자동으로 해당 IP로 해석해주는 서비스 입니다.

💡 참고: TLS 설정이 없기 때문에 브라우저에서 주의 요함이 표시될 수 있습니다. 내부망 구성에서는 HTTP로 운영하고, 운영 환경에서는 cert-manager로 인증서를 발급하는 것을 권장합니다.

6. Git 저장도 인증 Secret 설정

 

ArgoCDGitea 저장소에 접근하기 위한 인증 정보를 Secret으로 등록합니다.

# 20_repo_secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: repo-data-platform
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
  url: http://192.168.2.8:37000/eluna/data-platform.git
  username: argocd
  password: <GITEA_ACCESS_TOKEN>

 

즉, 여기서 확인할 수 있는 핵심은

argocd.argoproj.io/secret-type: repository 라벨을 붙이면

ArgoCD가 이 Secret저장소 인증 정보로 자동 인식한다는 점입니다.


7. Helm Chart 레지스트리 인증 Secret 설정

 

공식 Helm 레지스트리(ArtifactHub 등 공인 레지스트리)를 사용하는 경우,

별도 Secret 없이 values.yamlconfigs.repositories에 직접 등록하면 됩니다.

# values.yaml - 공식 Helm 레지스트리 사용 시
configs:
  repositories:
    argo-helm:
      url: https://argoproj.github.io/argo-helm
      type: helm
      name: argo

 

인증이 필요한 private 레지스트리라면 Secret으로 등록합니다.

apiVersion: v1
kind: Secret
metadata:
  name: repo-private-helm
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: helm
  name: private-helm
  url: https://your-private-helm-repo
  username: <USERNAME>
  password: <PASSWORD>

 

글쓴이는 온프레미스 환경에서 HarborOCI 레지스트리로 사용하고 있어, 아래와 같이 OCI 전용 Secret으로 등록합니다.
# 60_harbor_repo_secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: repo-harbor-oci
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: helm
  name: harbor-oci
  url: harbor.local
  enableOCI: "true"
  username: admin
  password: <HARBOR_PASSWORD>
필드 설명
type: helm Helm 레지스트리 타입으로 등록
enableOCI: "true" OCI 프로토콜 사용 활성화
url : harbor.local Harbor 도메인 (포트 없이 도메인만)

 

즉, 여기서 확인할 수 있는 핵심은

argocd.argoproj.io/secret-type: repository 라벨을 붙이면

ArgoCD가 이 SecretHelm 레지스트리 인증 정보로 자동 인식한다는 점입니다.


8. TLS 인증서 신뢰 설정

 

Let`s Encrypt공인 CA에서 발급한 인증서를 사용하는 경우,

ArgoCD가 기본적으로 신뢰하므로 별도 설정이 필요하지 않습니다,.

 

글쓴이는 사내 self-signed CA 인증서를 사용하고 있어, ArgoCD repo-serverHarbor에 접근할 때 인증서를 신뢰하도록 아래와 같이 등록합니다.
# 50_argocd_tls_certs_cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-tls-certs-cm
  namespace: argocd
data:
  harbor.local: |
    -----BEGIN CERTIFICATE-----
    # Harbor CA 인증서 내용
    -----END CERTIFICATE-----
⚠️ 이 설정이 없으면 repo-serverHarbor에서 Helm 차트를 pull할 때 아래와 같은 TLS 인증서 검증 오류가 발생합니다.
x509: certificate signed by unknown authority

 

즉, 여기서 확인할 수 있는 핵심은

공인 인증서 환경에서는 이 설정이 불필요하지만,

self-signed 인증서를 사용하는 경우 반드시 argocd-tls-certs-cm에 CA 인증서를 등록해야 한다는 점입니다.


9.ConfigMap 설정

# 40_argocd_cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  # API 토큰 발급용 계정 생성
  accounts.monitoring: apiKey

  # Rook-Ceph CephCluster 커스텀 Health Check
  resource.customizations.health.ceph.rook.io_CephCluster: |
    hs = {}
    if obj.status ~= nil then
      local state = obj.status.state or ""
      local health = ""
      if obj.status.ceph ~= nil then
        health = obj.status.ceph.health or ""
      end
      if state == "Created" and health == "HEALTH_OK" then
        hs.status = "Healthy"
        hs.message = "Ceph cluster is healthy"
        return hs
      end
      hs.status = "Progressing"
      hs.message = "State=" .. state .. " Health=" .. health
      return hs
    end
    hs.status = "Progressing"
    hs.message = "Waiting for CephCluster status"
    return hs

 

주요 설정 포인트는 아래와 같습니다.

  • accounts.monitoring: apiKey 
    • CI/CD 파이프라인 등에서 API 토큰으로 ArgoCD를 호출할 계정
  • CephCluster health check 
    • ArgoCD는 기본적으로 CRD 리소스의 Health를 판단할 수 없습니다.
    • Lua 스크립트를 통해 Rook-Ceph의 상태를 직접 파악하도록 커스터마이징 합니다.

 

즉, 여기서 확인할 수 있는 핵심은

ArgoCD기본 리소스(Deployment,Pod 등)의 Health는 자동으로 판단하지만, CephCluster 같은 CRD는 Lua 스크립트로 직접 Health 로직을 정의해줘야 한다는 점입니다.


10. RBAC 권한 설정

# 70_argocd_secret.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    g, monitoring, role:readonly

 

monitoring 계정에 읽기 전용 권한을 부여합니다.

API 토큰을 발급받아 외부 시스템에서 ArgoCD 상태를 조회할 때 사용합니다.


11. 설치 후 검증

 

[Pod 상태 확인]

kubectl get pods -n argocd

NAME                                                READY   STATUS    RESTARTS
argocd-application-controller-0                     1/1     Running   0
argocd-applicationset-controller-xxx                1/1     Running   0
argocd-notifications-controller-xxx                 1/1     Running   0
argocd-redis-xxx                                    1/1     Running   0
argocd-repo-server-xxx                              1/1     Running   0
argocd-server-xxx                                   1/1     Running   0

 

 

[Service 확인]

kubectl get svc -n argocd

 

argocd-server가 NodePort(30010)로 노출되어 있는지 확인합니다.

 

[초기 admin 비밀번호 확인]

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

 

[Web UI 접속]

Ingress 설정 URL로 접속 후 로그인합니다.

 

  • Username: admin
  • Password: 위 명령어로 확인한 값
⚠️ 초기 비밀번호는 로그인 후 반드시 변경하세요.

 

Pod가 정상 상태가 되지 않는 경우 아래 명령어로 원인을 확인합니다.

# Pod 상태 상세 확인
kubectl describe pod <pod-name> -n argocd

# Pod 로그 확인
kubectl logs <pod-name> -n argocd

 

 

자주 발생하는 원인은 아래와 같습니다.

증상 원인 조치
Pending 상태 지속 이미지 pull 실패 Harbor 로그인 상태 및 이미지 경로 확인
CrashLoopBackOff values.yaml 설정 오류 kubectl logs로 argocd-server 로그 확인
repo-server TLS 오류 Harbor 인증서 미등록 argocd-tls-certs-cm ConfigMap 적용 여부 확인
Harbor Helm Chart pull 실패 OCI Secret 미등록 repo-harbor-oci Secret 적용 여부 확인


📝 마무리

이번 글에서는 온프레미스 Kubernetes 환경에서 ArgoCD를 구축하는 과정을 정리해 봤습니다.

 

정리하면,

  • Helm 설치 → helm upgrade --install로 idempotent 하게 설치
  • Ingress → MetalLB + ingress-nginx + sslip.io로 도메인 접근
  • Git 저장소 인증 → argocd.argoproj.io/secret-type: repository 라벨을 붙인 Secret으로 등록
  • Harbor OCI 인증 → enableOCI: "true" Secret으로 별도 등록
  • TLS 신뢰 → Harbor self-signed CA 인증서를 argocd-tls-certs-cm으로 등록
  • ConfigMap → API 계정 생성 및 CRD health check Lua 스크립트 커스터마이징
  • RBAC → argocd-rbac-cm으로 계정별 권한 설정

라고 볼 수 있습니다.

 

특히 이번 구축에서 주의해야 할 포인트는

  • Git 저장소 인증과 Harbor OCI 인증은 values.yaml이 아닌 별도 Secret으로 관리해야 함
  • Harbor self-signed 인증서는 반드시 argocd-tls-certs-cm에 등록해야 repo-server가 정상 동작
  • server.insecure: true는 TLS 없이 HTTP로 운영할 때 사용하는 설정

이 3가지였습니다.

 

다음 편에서는 App of Apps 패턴을 활용해 플랫폼 전체 앱을 GitOps로 관리하는 방법을 다뤄보겠습니다. 🙌

 

궁금한 점이나 추가로 다뤄줬으면 하는 내용이 있다면 언제든지 편하게 말씀해 주세요! 😊

728x90
반응형