애플리케이션 빌드와 이미지 푸시는 GitHub Actions로 해결했다. 남은 건 새 이미지를 클러스터에 반영하는 일이다. 매번 kubectl apply를 손으로 치는 대신, Kubernetes manifest를 담은 Git 저장소를 기준으로 두고 ArgoCD가 그 저장소를 지켜보다가 바뀌면 클러스터를 맞추게 하고 싶었다.
우선 로컬 Minikube에서 구성해 봤다. 이 글에서는 ArgoCD 설치부터 저장소 연결과 Application 생성을 거쳐 자동 동기화 확인까지 정리한다.
실습 환경은 이렇다.
Mac Apple Silicon
로컬 Minikube
배포할 Java 애플리케이션: Kafka 테스트 앱. Deployment 4개, Service 4개 (zookeeper, kafka, kafka-ui, spring-boot-app)
개발자는 Git에 올리고, 클러스터 반영은 ArgoCD가 한다

Developer & Engineer 관점의 ArgoCD 활용 플로우차트.
클러스터에 무엇을 띄울지는 manifest 저장소가 정하고, ArgoCD는 그 상태를 따라간다. GitHub Actions는 이미지를 만들어 올리는 데서 역할이 끝나고, 클러스터를 직접 건드리지 않는다.
ArgoCD 설치와 NodePort 전환
brew install argocd
kubectl create namespace argocd # 네임스페이스 생성
# argoCD manifest 파일을 사용한 배포 방식
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# HA 구성 (노드 여러 개를 전제로 한다). 둘 중 하나만 적용한다
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/install.yaml
kubectl get pods -n argocd # 배포 확인
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}' # NodePort 설정
kubectl get service -n argocd # NodePort 확인
brew install argocd는 로컬에 CLI를 까는 명령이고, 클러스터에 ArgoCD를 올리는 건 그 아래 kubectl apply다. 단일 노드인 Minikube에는 일반 install.yaml이면 충분하다.
Minikube에서는 NodePort만으로 대시보드에 닿지 않는다
서비스를 NodePort로 바꿨는데도 브라우저에서 접속되지 않았다. Minikube에서는 ClusterIP든 NodePort든 그대로는 접근할 수 없고 터널링이 필요하다.
사용법은 minikube service <service name> -n <namespace>다.
~ » minikube service argocd-server -n argocd
|-----------|---------------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|---------------|-------------|---------------------------|
| argocd | argocd-server | http/80 | http://192.168.49.2:31866 |
| | | https/443 | http://192.168.49.2:30635 |
|-----------|---------------|-------------|---------------------------|
🏃 argocd-server 서비스의 터널을 시작하는 중
|-----------|---------------|-------------|------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|---------------|-------------|------------------------|
| argocd | argocd-server | | http://127.0.0.1:55140 |
| | | | http://127.0.0.1:55141 |
|-----------|---------------|-------------|------------------------|
[argocd argocd-server http://127.0.0.1:55140
http://127.0.0.1:55141]
❗ Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
출력의 마지막 줄이 이유를 말해 준다. macOS에서 Docker 드라이버로 띄운 Minikube 노드는 Docker 네트워크 안에 있어서, 호스트는 192.168.49.2에 직접 닿지 못한다. 그래서 minikube service가 127.0.0.1의 임의 포트로 터널을 열어 주고, 그 터미널을 열어 둔 동안만 접속된다.
초기 비밀번호 꺼내기
터널로 열린 URL에 접속하면 로그인 화면이 나온다.

ID는 기본값 admin이고, 비밀번호는 아래 명령으로 꺼낸다.
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
지켜볼 저장소부터 등록한다
여기서 연결하는 GitHub 저장소는 ArgoCD가 관찰(observe)할 대상이다. 이 저장소의 manifest 파일이 바뀌면 ArgoCD가 그 내용을 K8S 클러스터에 반영한다.



Application은 저장소 경로와 클러스터를 잇는 한 줄이다
Application을 만들 때는 대상 K8S 클러스터와 앞에서 등록한 GitHub 저장소 정보를 입력한다.

| 항목 | 설정 |
|---|---|
| Application Name | 임의 지정 |
| Project Name | 임의 지정 |
| Sync Policy | Automatic |
| SOURCE > Repository URL | 앞에서 등록한 GitHub 저장소 |
| SOURCE > Revision | ArgoCD가 모니터링할 브랜치 |
| SOURCE > Path | ArgoCD가 모니터링할 manifest 파일이 있는 폴더 경로 |
| DESTINATION > Cluster URL | 변경사항을 배포할 클러스터. Minikube에서 테스트 중이라 https://kubernetes.default.svc |
| DESTINATION > Namespace | 배포 목적지 네임스페이스 |
SOURCE의 세 칸(저장소, 브랜치, 경로)이 “무엇을"이고 DESTINATION의 두 칸이 “어디에"다. https://kubernetes.default.svc는 클러스터 안에서 자기 API 서버를 가리키는 주소라서, ArgoCD가 설치된 바로 그 Minikube 클러스터에 배포하겠다는 뜻이 된다. Sync Policy를 Automatic으로 두어야 저장소가 바뀔 때 사람이 Sync 버튼을 누르지 않아도 된다.
저장소에 있는 그대로 클러스터가 섰다


연결된 GitHub 저장소의 manifest 파일을 ArgoCD가 참조해 구성한 Kubernetes 환경이 보인다. 이 상태에서 저장소 파일이 바뀌면 클러스터도 그에 맞춰 동기화된다.
정리
빌드는 GitHub Actions, 클러스터 반영은 ArgoCD로 나눴다. 기준은 manifest 저장소다.
macOS의 Docker 드라이버 Minikube는 NodePort로 바로 닿지 않는다.
minikube service로 터널을 열어 둔다.Application은 저장소·브랜치·경로를 클러스터·네임스페이스에 잇는 설정이고, Sync Policy를 Automatic으로 둬야 자동으로 따라간다.
남은 연결 고리는 새 이미지가 나올 때 manifest 저장소의 이미지 태그를 누가 바꾸느냐다. 그 부분은 GitHub Actions 워크플로에서 다른 저장소 파일을 고치는 방식으로 이어서 정리했다.