[k8s] argoCD 배포 총 정리

2025. 11. 9. 16:32·공부/DevOps
728x90

ArgoCD란?

오늘은 k8s를 통해 서비스를 운영할 때 자동 배포 도구로 많이 사용하는 ArgoCD를 사용해보려고 합니다.
 
ArgoCD란 k8s를 위한 선언적 GitOps 지속적 배포 도구입니다.
 
Git 저장소에 정의된 애플리케이션 상태를 그대로 반영하는 것이 ArgoCD입니다.
 
실행 중인 애플리케이션을 지속적으로 모니터링하고 현재 상태와 Git에 저장된 상태를 비교하며 상태를 동기화 합니다.
 
ArgoCD의 아키텍처는 다음과 같습니다.
 
 

https://www.inflearn.com/blogs/6373?srsltid=AfmBOor1BcPxnTVJx3A_vyjFP4lf4b5MgRJKPpgeYnUKHOk8AkzMeBa5

각 컴포넌트의 역할은 다음과 같습니다.

Server API Server 및 dashboard
Repo Server Git의 yaml 파일을 바탕으로 yaml manifest 생성
Application Controller k8s 리소스 모니터링 및 변경 사항 발생 시 Git의 내용을 k8s에 반영
Notification ArgoCD에서 발생하는 이벤트를 외부로 트리거
Redis Github와 kube--apiserver와의 통신에 캐시로 사용
ApplicationSet Controller 멀티 클러스터를 위한 App 패키징 관리
dex 외부 인증 관리

 
ArgoCD는 대부분 statelss 방식입니다.
 
모든 데이터는 k8s object로 저장되고 k8s object는 k8s의 etcd에 저장됩니다.
 
redis에 데이터를 저장하기는 하지만 redis는 캐싱 용도이기 때문에 손실되더라도 큰 상관이 없습니다.
 
ArgoCD는 k8s 전용 배포 툴이고 Git과 연동되기 때문에 설치하기 위해 k8s cluster가 구축되어 있어야 하고 Git 저장소가 존재해야 합니다.

ArgoCD 배포 1 - NodePort 방식

ArgoCD를 설치하는 방법은 굉장히 단순합니다.
 
k8s cluster에서 아래 명령어를 입력하면 됩니다. yaml 파일에 ArgoCD에 필요한 모든 Object가 작성되어 있습니다.

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml


 

 
다음 명령어를 통해 component들이 잘 배포되었나 확인합니다.
 

kubectl get po -n argocd -o wide

 
위에서 보았듯이 이 중 arcocd-server가 dashboard 역할을 하고 있습니다.
 
이 argocd-server에 접근하려면 가장 단순하게는 NodePort Service를 사용해서 포트를 뚫으면 됩니다.
 
linux 기준으로 다음 명령어를 입력하면 <node ip :30080>으로 접근할 수 있습니다.

kubectl patch svc argocd-server -n argocd --type='json' -p='[{"op": "replace", "path": "/spec/type", "value": "NodePort"}, {"op": "replace", "path": "/spec/ports/0/nodePort", "value": 30080}]'

 
다음 명령어로 argocd-server Service 타입이 NodePort로 변경되었는지 확인합니다.

kubectl get svc -n argocd -o wide

 

이제 <Node IP : Node Port>를 통해 argoCD dashboard에 접근할 수 있습니다.

 

초기 admin 비밀번호는 다음 명령어로 알아낼 수 있습니다.

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

 
dashboard에 로그인 하여 비밀번호를 변경합니다.

ArgoCD 배포 2 - Ingress방식

이번에는 NodePort 방식을 사용하지 않고 k8s object인 Ingress를 사용해보겠습니다.

 

NodePort 방식을 사용하게 되면 argoCd가 배포되어 있는 Node의 주소와 뚫려있는 포트 번호를 알아야 합니다.
 
Ingress를 활용하면 요청을 Ingress Controller로 보내고 Ingress Controller가 트래픽을 라우팅하게 할 수 있습니다.

https://kubernetes.io/ko/docs/concepts/services-networking/ingress/

 
Ingress를 활용하면 단일 IP 주소로 모든 요청을 받을 수 있고 Node의 IP와 Port 정보를 외부에 노출하지 않기 때문에 보안 상 좋습니다.
 
여기서 Ingress는 k8s object이고 Ingress Controller는 Ingress에 정의한 규칙을 기반으로 라우팅을 수행하는 주체입니다.
 

1. nginx-ingress-controller 배포

ingress를 적용하기 전에 ingress controller를 배포해야 하는데 다음 명령어를 통해 Nginx Ingress Controller를 배포해보겠습니다.

curl -O https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.14.0/deploy/static/provider/cloud/deploy.yaml
kubectl apply -f ./deploy.yaml

 

버전 정보를 바꾸고 싶다면 url의 버전 정보를 바꾸면 되는데 아래 주소에서 최신 버전 정보를 확인할 수 있습니다.

https://github.com/kubernetes/ingress-nginx

2. NodePort Service로 변경

그런데 위 nginx ingress controller는 기본적으로 Service Object들이 LoadBalancer type으로 세팅되어 있습니다.

 

저는 준비된 Load Balancer가 없기 때문에 NodePort 타입으로 바꿔보겠습니다.

 

patch 명령어로 바로 바꿀 수도 있지만 저는 원본 파일을 유지하고 원본에서 어떠한 부분만 변경이 되었는지 확인하고 싶기 때문에 override.yaml 파일을 다음과 같이 따로 만들어보겠습니다.

 

<override.yaml>

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.14.0
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  externalTrafficPolicy: Local
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
    nodePort: 30080
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
    nodePort: 30443
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: NodePort

 

ingress-nginx-controller Service만 NodePort 타입으로 바꾸고 port 번호를 고정해주었습니다.

 

이 override.yaml도 apply 명령어로 적용해줍니다.

 

다음 명령어로 잘 배포되었는지 확인합니다.

kubectl get all -n ingress-nginx
NAME                                           READY   STATUS    RESTARTS   AGE
pod/ingress-nginx-controller-cc68b44bd-j8d5s   1/1     Running   0          13m

NAME                                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.104.39.83    <none>        80:30080/TCP,443:30443/TCP   13m
service/ingress-nginx-controller-admission   ClusterIP   10.110.50.119   <none>        443/TCP                      13m

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   0/1     1            0           13m

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-cc68b44bd   1         1         0       13m

 

3. argocd ingress 생성

ingress 적용하기 전의 기본 세팅을 마무리 했습니다. 이제 argoCD로 트래픽을 향하게 하기 위한 ingress object를 다음과 같이 정의합니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              number: 443

 

위 설정 파일의 뜻은 다음과 같습니다.

  • ingress는 argocd name space에 생성한다.
  • nginx라는 ingress controller에게 ingress를 적용한다.
  • ingress controller가 pod와 통신할 때 프로토콜은 https를 사용한다.
  • "example.com/"로 요청이 들어왔을 때 argocd-service라는 이름의 service의 443 포트로 트래픽을 전달한다.

4. Local DNS 설정

위에서 host에 example.com이 있는데 실제 도메인을 가지고 있지 않기 때문에 local pc의 hosts 파일을 수정해서 로컬 DNS를 정의해보겠습니다.

 

저는 nginx ingress controller pod가 띄워진 노드의 주소가 192.168.35.52이기 때문에 다음과 같이 정의하겠습니다.

...
192.168.35.52 example.com
...

 

5. argoCD 접속

전체적인 흐름은 다음과 같습니다.

 

이제 https://example.com:30443으로  접속해보면 다음과 같은 페이지를 확인할 수 있습니다.

 

물론 공인된 인증서가 없기 때문에 고급 -> example.com(안전하지 않음)을 직접 클릭해야 합니다.

이제 다음과 같이 argoCD dashboard에 접근할 수 있습니다.

 

참고로 지금은 prefix가 "/"로 정의되어 있는데 "/argocd"로 변경할 경우 문제가 발생할 수 있습니다.

 

바로 argoCD dashboard Frontend의 API 요청 때문입니다.

 

우선 처음에 /argocd로 요청을 보내면 argocd-server Service로 요청이 전달이 되고 dashboard의 html 파일을 받고 여기서 추가적인 정적 파일들을 요청하게 됩니다.

 

그런데 이 때 정적 파일들을 요청할 때는 "/argocd"가 아닌 "/" 경로로 요청을 보내게 됩니다.

 

당연히 prefix를 "/argocd"로 정의하면 "/"로 들어오는 요청은 argocd에게 도달하지 못 합니다.

 

그래서 "/argocd"로 prefix를 정의하고 접속해보면 아래와 같이 정적 파일들을 찾지 못 합니다.

 

404 에러가 뜬 요청을 확인해보면 아래와 같이 "/argocd" prefix가 없는 모습을 확인할 수 있습니다.

https://example.com:30443/assets/fonts.css

 

이 문제를 해결하기 위해서는 rootpath 옵션을 통해 root path 자체를 "/argocd"로 바꿔줘야 합니다.

 

이 방법은 아래에서 알아보겠습니다.

ArgoCD 배포 3 - Helm 방식

지금까지 살펴본 두 가지 방식은 모두 아래 주소에 존재하는 k8s manifest를 사용했습니다.

https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

해당 파일을 살펴보면 하나의 파일 안에 모든 k8s object들이 정의되어 있는 모습을 확인할 수 있습니다.

 

이 파일 하나를 사용하고 override 하는 방식으로 argocd를 사용해도 되지만 이번에는 helm을 통해 패키지 관리를 해보겠습니다.

helm이란?

helm은 k8s 애플리케이션 패키지 관리 도구입니다.

 

그리고 k8s 애플리케이션의 다양한 Object들을 쉽게 배포하기 위해 패키징을 한 것이 바로 helm chart입니다.

 

helm charts는 k8s 리소스와 관련된 set이 정의된 파일의 모음으로 다음과 같은 디렉토리 안에 파일들이 존재합니다.

wordpress/
  Chart.yaml          # 차트에 대한 정보를 가진 YAML 파일
  LICENSE             # 옵션: 차트의 라이센스 정보를 가진 텍스트 파일
  README.md           # 옵션: README 파일
  values.yaml         # 차트에 대한 기본 환경설정 값들
  values.schema.json  # 옵션: values.yaml 파일의 구조를 제약하는 JSON 파일
  charts/             # 이 차트에 종속된 차트들을 포함하는 디렉터리
  crds/               # 커스텀 자원에 대한 정의
  templates/          # values와 결합될 때, 유효한 쿠버네티스 manifest 파일들이 생성될 템플릿들의 디렉터리
  templates/NOTES.txt # 옵션: 간단한 사용법을 포함하는 텍스트 파일

 

 

APT와 같은 패키지 관리 도구를 사용해서 linux package를 설치하거나 npm과 같은 패키지 관리 도구를 사용해서 node package를 설치하는 것처럼 helm이라는 패키지 관리 도구를 사용해서 k8s object package를 설치하는 것이라고 볼 수 있습니다.

 

helm-chart를 사용할 때 장점은 기존 template을 기반으로 value만 수정을 해가면서 쉽게 애플리케이션을 배포할 수 있다는 점입니다.

 

위에서 사용했던 argoCd manifest 파일은 하나의 YAML 파일로 이루어져 있었고 커스터마이징을 위해 코드를 분석할 시간이 필요합니다.

 

즉, manifest 내부에 대한 이해가 필요합니다.

 

그런데 argoCD helm-chart의 경우 이미 template이 존재하기 때문에 template의 세세한 설정을 몰라도 values만 변경하여 쉽게 원하는 설정을 적용할 수 있습니다.

 

helm 설치

이 helm을 사용해서 Nexus repository와 Harbor registry를 배포할 것이기 때문에 먼저 helm을 설치합니다.
 
아래 공식 문서에서 helm을 설치하는 다양한 방식을 확인할 수 있습니다.
https://helm.sh/ko/docs/intro/install

 

헬름 설치하기 | Helm

헬름 설치하고 작동하는 방법 배우기.

helm.sh

 
저는 ubuntu를 사용하기 때문에 APT를 통해 설치하겠습니다.

sudo apt-get install curl gpg apt-transport-https --yes
curl -fsSL https://packages.buildkite.com/helm-linux/helm-debian/gpgkey | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/helm.gpg] https://packages.buildkite.com/helm-linux/helm-debian/any/ any main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

 

argoCD helm-chart로 배포

그러면 이제 helm-chart를 통해 argoCD를 배포해봅시다. 그 전에 nginx ingress controller를 제외하고 이전에 배포했던 argocd 리소스를 모두 정리합니다.

 

helm repo는 아래 helm repo를 사용할 예정입니다.

https://argoproj.github.io/argo-helm/

 

Argo Helm Charts

ArgoProj Helm Charts

argoproj.github.io

 

 

먼저 repository를 등록해봅시다.

helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

 

그리고 다음과 같이 커스터마이징을 할 수 있는 values.yaml을 다운받습니다.

helm show values argo/argo-cd > values.yaml

 

values.yaml을 확인해보면 알겠지만 각 옵션마다 자세한 설명이 주석으로 달려있습니다.

 

이 파일을 수정해도 좋지만 4,000줄이 넘고 이 많은 옵션 중 필요한 것만 골라서 사용하기 위해 values.yaml을 따로 다운받지는 않겠습니다.

 

대신 values.yaml에서 필요한 항목을 골라서 override-values.yaml을 다음과 같이 정의하겠습니다.

 

< override-values.yaml>

server:
  extraArgs:
    - --rootpath
    - /argocd
  ingress:
    enabled: true
    hostname: example.com
    annotations:
      nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    ingressClassName: nginx
    paths:
      - "/argocd"

 

여기서 rootpath를 지정하면 위에서 발생했던 404 Not Found 문제를 해결할 수 있습니다.

 

이제 다음과 같은 명령어를 통해 helm-chart로 배포를 하고 저희가 정의한 override 파일을 적용합니다.

helm install argocd argo/argo-cd -n argocd -f ./override-values.yaml

 

이제  https://example.com:30443/argocd경로로 dashboard에 접근이 가능하면 성공입니다.

 

 

MetalLB를 활용하여 LoadBalancer Service 배포

Nginx Ingress Controller의 Service는 기본적으로 LoadBalancer type입니다.

 

하지만 on premise 환경에서는 LoadBalancer type의 Service에게 IP를 할당할 수 없어서 위에서 실습을 진행할 때는 NodePort 타입으로 변경하여 사용했습니다.

 

그런데 MetalLB를 활용하면 on premise 환경에서도 LoadBalancer 타입의 Service에게 ip를 할당할 수 있습니다.

 

먼저 kube-proxy의 config map을 수정합니다.

kubectl edit configmap -n kube-system kube-proxy

 

data.config.conf.ipvs.strictARP 값을 true로 바꿔줍니다.

 

아니면 다음 명령어를 사용해도 좋습니다.

kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system

 

다음 명령어로 metalLB를 적용합니다. 원한다면 버전 정보는 바꾸시길 바랍니다.

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml

 

다음으로 다음과 같은 Object를 정의하고 적용합니다.

 

여기서 IPAdressPool의 spec.addresses는 cluster node ip의 subnet과 동일한 대역에서 선택해야 합니다.

 

제 master node의 CIDR은 192.168.35.73/24이기 때문에 이 대역 내에서 결정했습니다.

---
apiVersion: metallb.io/v1beta1 
kind: IPAddressPool
metadata:
  name: ip-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.35.77-192.168.35.77
  autoAssign: true

--- 

apiVersion: metallb.io/v1beta1 
kind: L2Advertisement 
metadata:
  name: l2-network
  namespace: metallb-system
spec:
  ipAddressPools:
    - ip-pool

 

다음 명령어를 통해 servic object를 확인했을 때 external ip가 부여되었다면 성공입니다.

kubectl get svc -n ingress-nginx

출처

https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/
https://argo-cd.readthedocs.io/en/stable/getting_started/

https://developnote-blog.tistory.com/171

728x90

'공부 > DevOps' 카테고리의 다른 글

[DevOps] Jenkins 분산 빌드 아키텍처와 kubernetes  (0) 2025.11.16
[ArgoCD] Helm-Charts를 통해 Harbor를 GitOps 방식으로 배포  (0) 2025.11.10
'공부/DevOps' 카테고리의 다른 글
  • [DevOps] Jenkins 분산 빌드 아키텍처와 kubernetes
  • [ArgoCD] Helm-Charts를 통해 Harbor를 GitOps 방식으로 배포
웅대
웅대
알고리즘과 백엔드를 중심으로 열심히 공부 중입니다! 같이 소통하며 공부해요!
    250x250
  • 웅대
    웅대 개발 블로그
    웅대
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 백준 알고리즘
        • dp
        • 문자열
        • 정렬
        • 스택
        • 브루트 포스
        • 이진 탐색
        • 정리
        • 우선순위 큐
        • 자료구조
        • 그래프
        • 기타
        • 그리디
      • 컴퓨터 언어
        • Kotlin
        • Python
        • C#
      • 공부
        • Database
        • Android Studio
        • Algorithm
        • 컴퓨터 구조론
        • Spring
        • lombok
        • AWS
        • Network
        • OS
        • Git & GitHub
        • AI
        • Computer Vision
        • 보안
        • Nginx
        • 프론트
        • express
        • GCP
        • grokking concurrency
        • DevOps
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    embedding
    스택
    openvidu 배포
    RNN
    bfs
    binary search
    code tree
    Merge
    ChatPromptTemplate
    ci/cd
    codetree
    스프링 OAuth2
    푸쉬 알람
    다익스트라
    파이썬
    nn.RNN
    parametric search
    Vector Store
    influxDB CLI
    AWS Lambda
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
웅대
[k8s] argoCD 배포 총 정리
상단으로

티스토리툴바