DevOps & Infra/Kubernetes

[K8S/ArgoCD] ArgoCD로 애플리케이션 배포

턴태 2023. 11. 6. 01:40

1️⃣ ArgoCD란?

ArgoCD에 관한 공식적인 설명은 다음과 같다.

 

Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.

 

한 마디로 쿠버네티스에 사용되는 선언적인 GitOps CD 툴이라는 의미다.

 

GitOps는 Git을 활용하여 DevOps를 Git 환경으로 수행하는 것을 의미한다. 예를 들어 GitOps 파이프라인들은 다음과 같은 것들이 있다.

 

출처: Microsoft Azure (https://learn.microsoft.com/ko-kr/azure/architecture/example-scenario/gitops-aks/gitops-blueprint-aks#scenario-2-use-gitops-with-flux-github-and-aks-to-implement-cicd)

 

출처: AWS Blog (https://aws.amazon.com/ko/blogs/containers/gitops-model-for-provisioning-and-bootstrapping-amazon-eks-clusters-using-crossplane-and-argo-cd/)

 

출처: ArgoCD Docs (https://argo-cd.readthedocs.io/en/stable/#architecture)

 

구성을 보면 대부분 개발 -> 레포지터리 반영 -> CI(테스트, 빌드 등) -> CD(이미지 빌드 및 전달, 애플리케이션 배포)의 과정을 거친다.

 

여기서 ArgoCD가 Kubernetes에 변경 사항을 업데이트하고 배포하는 과정을 담당하는 도구로 동작하는 것으로 이해했다. 

 

2️⃣ 로컬 환경에서 ArgoCD 사용

물론 모든 배포 파이프라인을 구축하는 것도 좋지만, ArgoCD가 CD 단계에서 어떻게 동작하는지 확인하고자 아래와 같은 구조로 아키텍처를 모의로 구성했다.

 

개발자한 애플리케이션 코드를 원격 레포지터리에 반영하고, 이를 ArgoCD가 상태를 비교하고 동기화하여 상태를 맞춘다. 배포된 애플리케이션도 마찬가지로 동기화함으로써 변경사항을 반영한다.

 

실습을 위한 도구들은 Minikube + GitHub + Docker Hub + ArgoCD로 정하고 사용했다.

 

3️⃣ ArgoCD 설치

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

 

argocd 네임스페이스를 생성한 다음 해당 네임스페이스에 매니페스트를 사용하여 오브젝트들을 구축한다.

 

customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created
serviceaccount/argocd-application-controller created
serviceaccount/argocd-applicationset-controller created
serviceaccount/argocd-dex-server created
serviceaccount/argocd-notifications-controller created
serviceaccount/argocd-redis created
serviceaccount/argocd-repo-server created
serviceaccount/argocd-server created
role.rbac.authorization.k8s.io/argocd-application-controller created
role.rbac.authorization.k8s.io/argocd-applicationset-controller created
role.rbac.authorization.k8s.io/argocd-dex-server created
role.rbac.authorization.k8s.io/argocd-notifications-controller created
role.rbac.authorization.k8s.io/argocd-server created
clusterrole.rbac.authorization.k8s.io/argocd-application-controller created
clusterrole.rbac.authorization.k8s.io/argocd-server created
rolebinding.rbac.authorization.k8s.io/argocd-application-controller created
rolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created
rolebinding.rbac.authorization.k8s.io/argocd-dex-server created
rolebinding.rbac.authorization.k8s.io/argocd-notifications-controller created
rolebinding.rbac.authorization.k8s.io/argocd-server created
clusterrolebinding.rbac.authorization.k8s.io/argocd-application-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-server created
configmap/argocd-cm created
configmap/argocd-cmd-params-cm created
configmap/argocd-gpg-keys-cm created
configmap/argocd-notifications-cm created
configmap/argocd-rbac-cm created
configmap/argocd-ssh-known-hosts-cm created
configmap/argocd-tls-certs-cm created
secret/argocd-notifications-secret created
secret/argocd-secret created
service/argocd-applicationset-controller created
service/argocd-dex-server created
service/argocd-metrics created
service/argocd-notifications-controller-metrics created
service/argocd-redis created
service/argocd-repo-server created
service/argocd-server created
service/argocd-server-metrics created
deployment.apps/argocd-applicationset-controller created
deployment.apps/argocd-dex-server created
deployment.apps/argocd-notifications-controller created
deployment.apps/argocd-redis created
deployment.apps/argocd-repo-server created
deployment.apps/argocd-server created
statefulset.apps/argocd-application-controller created
networkpolicy.networking.k8s.io/argocd-application-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-applicationset-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-dex-server-network-policy created
networkpolicy.networking.k8s.io/argocd-notifications-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-redis-network-policy created
networkpolicy.networking.k8s.io/argocd-repo-server-network-policy created
networkpolicy.networking.k8s.io/argocd-server-network-policy created

 

롤, 롤바인딩, 스테이트풀셋, 시크릿, 컨피그맵 등 다양한 오브젝트가 생성되는 것을 확인할 수 있다.

 

여기서, argocd 네임스페이스를 참조하는 ClusterRoleBinding이 설치되므로, argocd 네임스페이스가 아닌 다른 네임스페이스에 설치하고자 한다면, 이 내용을 반영해줘야 한다.

 

4️⃣ 서비스 노출

이렇게 오브젝트를 생성하면 서비스까지 모두 생성이 되지만, 서비스로 접속이 어렵다.

NAME                                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/argocd-applicationset-controller          ClusterIP   10.101.192.92   <none>        7000/TCP,8080/TCP            46s
service/argocd-dex-server                         ClusterIP   10.111.86.239   <none>        5556/TCP,5557/TCP,5558/TCP   46s
service/argocd-metrics                            ClusterIP   10.99.167.119   <none>        8082/TCP                     46s
service/argocd-notifications-controller-metrics   ClusterIP   10.104.244.86   <none>        9001/TCP                     46s
service/argocd-redis                              ClusterIP   10.96.216.77    <none>        6379/TCP                     45s
service/argocd-repo-server                        ClusterIP   10.107.15.101   <none>        8081/TCP,8084/TCP            45s
service/argocd-server                             ClusterIP   10.101.31.228   <none>        80/TCP,443/TCP               45s
service/argocd-server-metrics                     ClusterIP   10.104.25.41    <none>        8083/TCP                     45s

 

kubectl get으로 현재 argocd 네임스페이스에 존재하는 서비스를 확인하면 EXTERNAL-IP를 확인할 수 없다. 그렇기 때문에 이를 위해 EXTERNAL-IP를 지정해주거나 터널링을 통해 컨테이너로 접근해야 할 것이다.

 

이를 위해서 ArgoCD에서는 총 세 가지 방법을 제안하는데, Service Type을 LoadBalancer로 적용하는 방법, Ingress 컨트롤러를 사용하는 방법, port-forwarding 방법이 있다. 여기에 minikube를 사용하기 때문에 minikube tunneling을 사용하는 방법도 있다. 만약 vm driver를 docker로 사용한다면 port-forwarding, minikube tunneling 방법이 가장 적합할 것 같다.

 

1. LoadBalancer 타입으로 변경

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

 

기본적으로 Cluster IP로 되어있는 서비스 타입을 LoadBalancer로 적용하여 EXTERNAL-IP를 등록한다.

 

vm driver가 Docker라면 도커 네트워크 특성 상 내부 컨테이너로 포워딩을 해줘야 하므로 EXTERNAL-IP가 등록이 되더라도 접근이 불가하다. 따라서, 위에서 기재한 두 가지 방법을 사용하는 것이 좋을 것이다.

 

2. Ingress 컨트롤러 설정

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

 

Ingress Configuration - Argo CD - Declarative GitOps CD for Kubernetes

Ingress Configuration Argo CD API server runs both a gRPC server (used by the CLI), as well as a HTTP/HTTPS server (used by the UI). Both protocols are exposed by the argocd-server service object on the following ports: 443 - gRPC/HTTPS 80 - HTTP (redirect

argo-cd.readthedocs.io

사용할 수 있는 방법이 다양하므로 위 링크에서 확인하여 설정할 수 있다.

 

3. port-forwarding

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

 

로컬에서 8080 포트로 요청하면 minikube argocd 네임스페이스의 443 포트 내부 서비스로 접근할 수 있다.

 

4. minikube tunneling

minikube service argocd-server -n argocd

 

기본적으로 default namespace를 참조하므로 직접 네임스페이스를 지정해준다.

 

5️⃣ ArgoCD 접속

CLI 사용

https://github.com/argoproj/argo-cd/tree/v2.8.6 해당 레포지터리에서 설치할 수 있다.

 

GitHub - argoproj/argo-cd: Declarative Continuous Deployment for Kubernetes

Declarative Continuous Deployment for Kubernetes. Contribute to argoproj/argo-cd development by creating an account on GitHub.

github.com

 

MAC 환경에서는 homebrew로도 설치할 수 있다.

brew install argocd

 

초기에 admin 계정이 생성이 되고, 이 admin 계정에 접속하기 위해선 비밀번호가 필요하다. 초기 비밀번호는 아래 명령어로 확인할 수 있다.

argocd admin initial-password -n argocd


비밀번호를 변경했다면 반드시 argocd-initial-admin-secret를 삭제해줘야 한다. 새 관리자 비밀번호를 다시 생성해야 하는 경우 Argo CD에서 요청 시 다시 생성한다.

비밀번호 업데이트는 다음과 같은 명령어를 사용하면 된다.

argocd account update-password

 

이제 cli 환경에서 argocd에 로그인할 수 있다.

argocd login localhost:8080

 

UI 사용

 

UI 환경에서 배포하고자 한다면, Localhost:지정한 포트로 접속하여 접근할 수도 있다.

 

비밀번호는 secret 오브젝트에서 확인할 수 있다.

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

 

base64로 인코딩 되어 있으므로 디코딩이 필요하다.

base64 -d
인코딩된 비밀번호

 

혹은 아래 명령어로 한 번에 확인할 수 있다.

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

 

6️⃣ 애플리케이션 생성

로그인이 됐으면 application을 생성/배포한다.

 

먼저 argoCD 공식문서의 예시로 배포를 해볼 수 있다.

 

argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default

 

argocd에서 사용할 이름을 명시하고, 레포지터리를 지정한다. 이때, 옵션들은 다음과 같다.

  • repo: 배포할 애플리케이션 레포지터리
  • path: 레포지터리 내에 쿠버네티스 오브젝트 파일이 존재하는 디렉터리 -> 파일로 지정이 되지 않으므로 따로 디렉터리를 만들어 격리하는 것이 좋다.
  • dest-server: 쿠버네티스의 API 서버 주소다. https://kubernetes.default.svc 로 지정한다. 혹은 클러스터 내 이름을 사용한다.
  • dest-namespace: 배포할 디플로이먼트의 네임스페이스

 

아래와 같이 메시지가 뜨면 성공이다.

application 'guestbook' created

 

혹은 UI 창에서 NEW APP을 누르고, 위 CLI의 옵션을 넣어서 사용해도 된다.

 

애플리케이션을 생성하면 최초로 아래와 같은 상태를 확인할 수 있다.

 

CLI로 확인하는 방법은 다음과 같다.

argocd app get guestbook

Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://localhost:8080/applications/guestbook
Repo:               https://github.com/argoproj/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        Synced to  (53e28ff)
Health Status:      Healthy

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

 

이미 쿠버네티스에 배포하여 Sync Status가 Synced로 나오는데, OutOfSync로 뜨는 게 정상이다. 애플리케이션이 아직 배포되지 않았고, 쿠버네티스 리소스들이 생성되지 않았으므로, 초기에는 Sync Status가 OutOfSync로 뜬다.

 

이제 아래 명령어로 애플리케이션을 배포할 수 있다.

argocd app sync guestbook

 

repository에서 매니페스트를 찾고, kubectl apply를 대신 수행하여 리소스를 생성하고 쿠버네티스가 컨테이너를 관리할 수 있도록 해준다.

 

혹은 UI 창에서 Sync 버튼을 누른 후 SYNCHRONIZE를 누르면 된다.

 

최종적으로 아래와 같은 상태로 변경된다.

 

UI의 좋은 점은 전체 구조가 어떻게 되어있는지 한 눈에 파악할 수 있다는 것이다. 애플리케이션을 누르면 아래와 같이 구조를 한 눈에 보여준다.

 

서비스와 디플로이먼트가 존재하고, 서비스는 각각 엔드포인트, 엔드포인트 슬라이스가 있으며 디플로이먼트는 레플리카셋과 그 안에 파드가 존재한다.

정리하며

직접 ArgoCD를 사용하면서 느낀점은 Jenkins나 CircleCI 등 CI 도구의 후처리를 위해 잘 어울릴 것 같다는 생각이 들었다. Jenkins와 같은 도구를 통해 이미지를 빌드하여 원격 레지스트리에 푸시한 다음, 이를 ArgoCD가 감지하여 자동으로 배포를 하면 유기적인 구조를 가질 수 있기 때문이다.

 

그래서 ArgoCD를 사용하는 파이프라인을 보면 대부분 다음과 같이 구성돼 있었다. 정리해서 그린 다이어그램이다.

 

 

전체 파이프라인을 한 번 싹 구성하고 정리해보는 것도 재밌을 것 같다. 그래서 다음에는 바로 전체 파이프라인을 구성해보는 시간을 가져볼까 한다.

 

참고

https://learn.microsoft.com/ko-kr/azure/architecture/example-scenario/gitops-aks/gitops-blueprint-aks#scenario-2-use-gitops-with-flux-github-and-aks-to-implement-cicd

 

Azure Kubernetes Service용 GitOps - Azure Example Scenarios

GitOps 원칙을 사용하여 AKS(Azure Kubernetes Services) 클러스터를 운영하고 관리하는 방법을 알아봅니다. 솔루션은 Flux v2 및 Argo CD를 사용합니다.

learn.microsoft.com

https://aws.amazon.com/ko/blogs/containers/gitops-model-for-provisioning-and-bootstrapping-amazon-eks-clusters-using-crossplane-and-argo-cd/

 

GitOps model for provisioning and bootstrapping Amazon EKS clusters using Crossplane and Argo CD | Amazon Web Services

Customers are increasingly using multiple Kubernetes clusters to manage their application delivery to different environments.  Managed services like Amazon Elastic Kubernetes Service (Amazon EKS) help customers offload the onerous task of managing the Kub

aws.amazon.com

https://argo-cd.readthedocs.io/en/stable/#architecture

 

Argo CD - Declarative GitOps CD for Kubernetes

Overview What Is Argo CD? Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. Why Argo CD? Application definitions, configurations, and environments should be declarative and version controlled. Application deployment and lifecycle ma

argo-cd.readthedocs.io

https://aws.amazon.com/ko/devops/continuous-delivery/

 

지속적 전달이란 무엇입니까? - Amazon Web Services

지속적 전달은 전체 소프트웨어 릴리스 프로세스를 자동화합니다. 수정 버전이 커밋될 때마다, 업데이트를 빌드 및 테스트한 후, 스테이징하는 자동화된 흐름이 트리거됩니다. 라이브 프로덕션

aws.amazon.com

https://thingsflow.com/blog/143

 

thingsflow

Creator economy with AI tech

thingsflow.com