본문 바로가기
AWS/EKS

[AEWS2] 7-2. EKS CI/CD - ArgoCD

by okms1017 2024. 4. 21.
728x90

✍ Posted by Immersive Builder  Seong

 

 

"문어발처럼 생긴 이놈은 데브옵스 세계에서 인기쟁이다. 

생긴 건 이래뵈도 깊은 깃옵스의 철학을 담고있다."

 

1. Argo Project

Argo 프로젝트는 다양한 쿠버네티스 리소스를 자동화하기 위한 도구를 개발하고 있습니다. 

대표적으로 ArgoCD, Argo Workflows, Argo Rollouts, Argo Events 제품이 있습니다. 

 

ArgoCD

ArgoCD는 쿠버네티스 어플리케이션을 지속적으로 배포하고 관리하는 도구입니다. 

GitOps 방식을 지원하고 쿠버네티스에 특화된 점이 가장 큰 특징입니다. 

 

  • GitOps 방식의 배포 : GitOps 원칙에 따라 Git 레포지토리에 저장된 어플리케이션의 상태에 변화가 생기면 클러스터에 실시간으로 동기화합니다. 
  • 선언적 배포 : 사용자는 YAML 파일을 통해 어플리케이션의 상태를 선언하고, ArgoCD가 해당 상태를 클러스터에 반영합니다. 
  • 대시보드 : 직관적인 웹 기반 대시보드를 통해 어플리케이션의 현재 상태를 시각적으로 확인하고, 배포 이력을 조회할 수 있습니다. 
  • 롤백 및 히스토리 관리 : 이전 배포로의 롤백을 지원하며, 모든 배포 이력을 추적하여 검토 및 분석할 수 있습니다. 
  • 사용자 정의 정책 : 배포에 대한 사용자 지정 정책을 정의하여 보안 및 규정 준수 요구사항을 충족할 수 있습니다. 

 

ArgoCD Architecture

Components

 

  • API Server : WEB UI Dashboard 화면을 제공하고 API 요청을 처리합니다. 
  • Repository Server : Git 원천 소스와 연결하고 배포할 YAML 파일을 생성합니다. 
  • Application Controller : Git 원천 소스와 비교하여 쿠버네티스 리소스를 모니터링합니다. 
  • Redis : 쿠버네티스 API와 Git 요청을 줄이기 위한 캐싱 역할을 합니다. 
  • Notification : 이벤트 알림 기능과 트리거 역할을 합니다. 
  • Dex : Keycloak 등과 연동하여 SSO 또는 외부 인증을 관리합니다. 
  • ApplicationSet Controller : 멀티 클러스터 환경에서 어플리케이션 패키징을 관리합니다. 

 

Source 유형

 

  • Kustomize Applications
  • Helm Charts
  • Jsonnet Files
  • Plain Directory of YAML/JSON Manifests
  • Plugin 

 

ArgoCD 설치 

 

# ArgoCD 설치
$ MyDomain=okms1017.name
$ CERT_ARN=arn:aws:acm:ap-northeast-2:7326**********

$ cat <<EOT > argocd-values.yaml
global:
  domain: argocd.$MyDomain

configs:
  params:
    server.insecure: true

controller:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

server:
  ingress:
    enabled: true
    controller: aws
    ingressClassName: alb
    hostname: "argocd.$MyDomain"
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/backend-protocol: HTTP
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":80}, {"HTTPS":443}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/ssl-redirect: '443'
    aws:
      serviceType: ClusterIP
      backendProtocolVersion: GRPC
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

repoServer:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

applicationSet:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

notifications:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true
EOT

$ kubectl create ns argocd
namespace/argocd created
$ helm repo add argo https://argoproj.github.io/argo-helm
"argo" has been added to your repositories
$ helm install argocd argo/argo-cd --version 6.7.11 -f argocd-values.yaml --namespace argocd
space argocd
NAME: argocd
LAST DEPLOYED: Sun Apr 21 02:51:46 2024
NAMESPACE: argocd
STATUS: deployed
REVISION: 1
TEST SUITE: None

# ArgoCD 설치 확인
$ kubectl get ingress,pod,svc -n argocd
NAME                                      CLASS   HOSTS                  ADDRESS   PORTS   AGE
ingress.networking.k8s.io/argocd-server   alb     argocd.okms1017.name             80      47s

NAME                                                    READY   STATUS    RESTARTS   AGE
pod/argocd-application-controller-0                     1/1     Running   0          46s
pod/argocd-applicationset-controller-85d64c6b7f-hhn8q   1/1     Running   0          46s
pod/argocd-dex-server-7746bdfd75-rtdkd                  1/1     Running   0          46s
pod/argocd-notifications-controller-64d9b554f4-q8h94    1/1     Running   0          46s
pod/argocd-redis-554fbc6587-8kws9                       1/1     Running   0          46s
pod/argocd-repo-server-765f96f455-zvs54                 1/1     Running   0          46s
pod/argocd-server-6b989df566-b6skd                      1/1     Running   0          46s

NAME                                               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
service/argocd-application-controller-metrics      ClusterIP   10.100.19.154    <none>        8082/TCP            48s
service/argocd-applicationset-controller           ClusterIP   10.100.234.247   <none>        7000/TCP            48s
service/argocd-applicationset-controller-metrics   ClusterIP   10.100.153.233   <none>        8080/TCP            48s
service/argocd-dex-server                          ClusterIP   10.100.80.65     <none>        5556/TCP,5557/TCP   48s
service/argocd-notifications-controller-metrics    ClusterIP   10.100.153.49    <none>        9001/TCP            48s
service/argocd-redis                               ClusterIP   10.100.166.108   <none>        6379/TCP            48s
service/argocd-repo-server                         ClusterIP   10.100.62.6      <none>        8081/TCP            48s
service/argocd-repo-server-metrics                 ClusterIP   10.100.67.20     <none>        8084/TCP            48s
service/argocd-server                              ClusterIP   10.100.221.93    <none>        80/TCP,443/TCP      48s
service/argocd-server-grpc                         ClusterIP   10.100.74.131    <none>        80/TCP,443/TCP      48s
service/argocd-server-metrics                      ClusterIP   10.100.14.247    <none>        8083/TCP            48s

$ kubectl get crd | grep argo
applications.argoproj.io                     2024-04-20T17:51:49Z
applicationsets.argoproj.io                  2024-04-20T17:51:49Z
appprojects.argoproj.io                      2024-04-20T17:51:49Z

# 초기비밀번호 확인 
$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
5rwZwmaflmhAPbLW

 

ArgoCD 설치 - 구성요소
ArgoCD 대시보드 - 초기화면

 

ArgoCD 배포하기 

 

  • Application Name : first-myweb
  • Project Name : default
  • SYNC POLICY : Manual
    • AUTO-CREATE NAMESPACE : 네임스페이스가 없을 때 argocd에 입력한 이름으로 자동 생성하는 옵션
    • APPLY OUT OF SYNC ONLY : 현재 동기화 상태가 아닌 리소스만 배포하는 옵션 

  • PRUNE PROPAGATION POLICY
    • foreground : 부모(소유자) 리소스를 먼저 삭제합니다. 
    • background : 자식(종속자) 리소스를 먼저 삭제합니다. 
    • orphan : 고아 리소스를 삭제합니다. * 고아 리소스 : 소유자는 삭제되었으나 종속자가 삭제되지 않은 경우.

  • SOURCE
    • Repository URL : 원천 소스의 주소 (https://github.com/okms1017/aews-cicd.git)
    • Revision : main branch
    • Path : 3/deploy

  • DESTINATION
    • Cluster URL : 배포할 클러스터의 주소 (https://kubernetes.default.svc)
    • Namespace : 'AUTO-CREATE NAMESPACE'에 적용되는 네임스페이스명 

 

Argo 어플리케이션을 생성하고 정보를 확인합니다. 

 

ArgoCD Application (first-myweb)
ArgoCD - OutOfSync
Service Summary - Desired Manifest
Service Summary - DIFF
Service Summary - Live Manifest

'SYNC' 버튼을 클릭하여 서비스/디플로이먼트 리소스를 배포해봅니다. 

 

 

디플로이먼트의 정보를 조회하면 Desired Manifest와 Live Manifest 간에 차이(Diff)가 없음을 확인할 수 있습니다. 

Live Manifest 정보가 출력됨을 통해 쿠버네티스 대상 클러스터에 리소스가 배포가 되었음을 알 수 있습니다.

 

 

그럼 Live Manifest를 수정하면 어떻게 될까요? 

쿠버네티스 클러스터에 변경분이 반영됩니다. 그러나 Git 원천 소스는 변경되지 않습니다. 

 

 

반대로 쿠버네티스 클러스터의 Manifest를 수정하였을 때에도 Live Manifest는 즉시 반영이 되지만 

Desired Manifest는 여전히 변경되지 않습니다. 

 

 

이번에는 깃허브 소스를 수정하여 어떻게 동작하는지 테스트합니다. 

 

ArgoCD의 Application Controller는 기본적으로 3분 주기로 한 번씩 Git 소스를 확인합니다. 

수동으로 'REFRESH'를 클릭하여 바로 확인해보겠습니다. 

 

소스 코드의 변경사항이 Live Manifest와 Desired Manifest에 모두 반영이 됩니다. 

하지만 클러스터 Manifest를 수정하여 추가한 Label들은 그대로 남아서 원천 소스와 대상 클러스터 간에 일관성이 깨져버렸습니다. 

 

 

ArgoCD는 클러스터 또는 Live Manifest에서 수정한 사항을 철저히 무시합니다. 

 

결론은 작업 시, 대상(K8s)이 아닌 소스(Git)에서 변경하자는 것입니다. 

이것이 GitOps의 원칙에 따르는 것입니다. 

 

실습을 마치고 리소스를 삭제합니다. 

Application을 선택하고 'DELETE' 버튼을 누르면 배포된 리소스가 깨끗하게 삭제됩니다. 

 

Application - Delete

 

Argo CLI

ArgoCD를 CLI 명령어로 구성하고 관리할 수 있는 도구입니다. 

 

Argo CLI 설치 

 

# Argo CLi 설치 
$ curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
$ sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
$ rm -f argocd-linux-amd64

# ArgoCD 버전 정보 확인 
$ argocd version
argocd: v2.10.7+b060053
  BuildDate: 2024-04-15T09:05:25Z
  GitCommit: b060053b099b4c81c1e635839a309c9c8c1863e9
  GitTreeState: clean
  GoVersion: go1.21.9
  Compiler: gc
  Platform: linux/amd64

# ArgoCD 로그인 
$ argocd login argocd.$MyDomain
Username: admin
Password: *****
'admin:login' logged in successfully

$ kubectl config get-contexts -o name
admin@myeks.ap-northeast-2.eksctl.io
$ argocd cluster add admin@myeks.ap-northeast-2.eksctl.io
WARNING: This will create a service account `argocd-manager` on the cluster referenced by context `admin@myeks.ap-northeast-2.eksctl.io` with full cluster level privileges. Do you want to continue [y/N]? 
yes
INFO[0018] ServiceAccount "argocd-manager" created in namespace "kube-system"
INFO[0018] ClusterRole "argocd-manager-role" created
INFO[0018] ClusterRoleBinding "argocd-manager-role-binding" created
INFO[0023] Created bearer token secret for ServiceAccount "argocd-manager"
Cluster 'https://BFCA17EE36E78251DEA789C2F7EAFB07.gr7.ap-northeast-2.eks.amazonaws.com' added

# ArgoCD App List 조회 
$ argocd app list
NAME                CLUSTER                         NAMESPACE  PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO                                       PATH      TARGET

 

App 생성 with Argo CLI

 

# 네임스페이스 argocd로 변경 
$ kubectl config set-context --current --namespace=argocd
Context "admin@myeks.ap-northeast-2.eksctl.io" modified.

# App(guestbook) 생성 
$ argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
application 'guestbook' created

# ArgoCD App List 조회 
$ argocd app list
NAME              CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                 PATH       TARGET
argocd/guestbook  https://kubernetes.default.svc  default    default  OutOfSync  Missing  <none>      <none>      https://github.com/argoproj/argocd-example-apps.git  guestbook

 

Application (guestbook) 생성 - OutOfSync

sync 명령어를 이용하여 Application(guestbook)을 배포합니다. 

 

# App(guestbook) 상태 정보 조회 
$ argocd app get guestbook
Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd.okms1017.name/applications/guestbook
Repo:               https://github.com/argoproj/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        OutOfSync from  (d7927a2)
Health Status:      Missing

GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH   HOOK  MESSAGE
       Service     default    guestbook-ui  OutOfSync  Missing
apps   Deployment  default    guestbook-ui  OutOfSync  Missing

# App(guestbook) 배포 
$ argocd app sync guestbook
Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd.okms1017.name/applications/guestbook
Repo:               https://github.com/argoproj/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        Synced to  (d7927a2)
Health Status:      Progressing

Operation:          Sync
Sync Revision:      d7927a27b4533926b7d86b5f249cd9ebe7625e90
Phase:              Succeeded
Start:              2024-04-21 06:25:35 +0900 KST
Finished:           2024-04-21 06:25:35 +0900 KST
Duration:           0s
Message:            successfully synced (all tasks run)

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

# 모니터링
$ watch -d kubectl get pod,svc,ep

 

 

하기 명령어로 Application 삭제도 가능합니다. 

 

# App(guestbook) 삭제 
$ argocd app delete guestbook
Are you sure you want to delete 'guestbook' and all its resources? [y/n] y
application 'guestbook' deleted

# default 네임스페이스로 변경
$ kubectl ns default
Context "admin@myeks.ap-northeast-2.eksctl.io" modified.
Active namespace is "default".

 


Argo Rollouts

Argo Rollouts는 Blue-Green, Canary, Canary Analysis 등 향상된 배포 전략을 제공하는 쿠버네티스 컨트롤러입니다. 

 

Argo Rollouts Architecture

Components

 

  • Argo Rollouts Controller
  • Rollout Resource
  • ReplicaSets for old and new version
  • Ingress/Service
  • AnalysisTemplate and AnalysisRun
  • Metric Providers
  • CLI & UI

 

배포 전략 

 

  • Blue-Green 전략 : 이전 버전(Blue)과 새로운 버전(Green)의 어플리케이션을 병렬로 실행하여 새로운 버전이 테스트를 통과하면 이전 버전의 리소스를 정리하고 새로운 버전으로 전환하는 배포 방식입니다. 

Blue-Green deployments

  • Canary 전략 : 라이브한 운영환경에서 새로운 버전의 어플리케이션을 일부 사용자에게 노출시키고 새로운 버전의 가중치를 점진적으로 늘려나가면서 전환하는 배포 방식입니다. 

Canary deployments

Argo Rollouts 설치 

 

# Argo Rollouts 설치 
$ cat <<EOT > argorollouts-values.yaml
dashboard:
  enabled: true
  ingress:
    enabled: true
    ingressClassName: alb
    hosts:
      - argorollouts.$MyDomain
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/backend-protocol: HTTP
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":80}, {"HTTPS":443}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/ssl-redirect: '443'
EOT

$ kubectl create ns argo-rollouts
namespace/argo-rollouts created
$ helm install argo-rollouts argo/argo-rollouts --version 2.35.1 -f argorollouts-values.yaml --namespace argo-rollouts
NAME: argo-rollouts
LAST DEPLOYED: Sun Apr 21 06:59:46 2024
NAMESPACE: argo-rollouts
STATUS: deployed
REVISION: 1
TEST SUITE: None

# Argo Rollouts 설치 확인
$ kubectl get all -n argo-rollouts
NAME                                           READY   STATUS    RESTARTS   AGE
pod/argo-rollouts-7647d689d6-88pkz             1/1     Running   0          28s
pod/argo-rollouts-7647d689d6-rrkz2             1/1     Running   0          28s
pod/argo-rollouts-dashboard-79d489cfc7-vpjzc   1/1     Running   0          28s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/argo-rollouts-dashboard   ClusterIP   10.100.14.203   <none>        3100/TCP   29s

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argo-rollouts             2/2     2            2           29s
deployment.apps/argo-rollouts-dashboard   1/1     1            1           29s

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/argo-rollouts-7647d689d6             2         2         2       28s
replicaset.apps/argo-rollouts-dashboard-79d489cfc7   1         1         1       28s

$ kubectl get crd | grep argo
analysisruns.argoproj.io                     2024-04-20T21:59:48Z
analysistemplates.argoproj.io                2024-04-20T21:59:47Z
applications.argoproj.io                     2024-04-20T17:51:49Z
applicationsets.argoproj.io                  2024-04-20T17:51:49Z
appprojects.argoproj.io                      2024-04-20T17:51:49Z
clusteranalysistemplates.argoproj.io         2024-04-20T21:59:47Z
experiments.argoproj.io                      2024-04-20T21:59:47Z
rollouts.argoproj.io                         2024-04-20T21:59:47Z

 

Argo Rollouts WEB UI - 초기 화면

Argo Rollouts CLI 설치 

 

# Argo Rollouts CLI 설치 

$ curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.6.4/kubectl-argo-rollouts-linux-amd64

$ chmod +x ./kubectl-argo-rollouts-linux-amd64

$ mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts

 

# 설치 확인

$ kubectl argo rollouts version

kubectl-argo-rollouts: v1.6.4+a312af9
  BuildDate: 2023-12-11T18:31:15Z
  GitCommit: a312af9f632b985ec13f64918b918c5dcd02a15e
  GitTreeState: clean
  GoVersion: go1.20.12
  Compiler: gc
  Platform: linux/amd64

 

Canary 배포하기 

 

Replica를 5개 생성하고 새로운 버전의 가중치를 20%씩 점진적으로 늘려가는 정책을 설정합니다. 

 

spec:
  replicas: 5
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {}
      - setWeight: 40
      - pause: {duration: 10}
      - setWeight: 60
      - pause: {duration: 10}
      - setWeight: 80
      - pause: {duration: 10}

 

Rollout과 Service를 배포합니다. 

 

$ kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/rollout.yaml

$ kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/service.yaml

 

배포 과정을 모니터링합니다. 

 

* CLI : " kubectl argo rollouts get rollout rollouts-demo --watch"

* UI : "https://argorollouts.okms1017.name/rollouts/rollout/default"

 

$ kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow

$ kubectl argo rollouts promote rollouts-demo

 

 

하기 명령어로 Rollout 과정을 중단할 수도 있습니다. 

 

$ kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:red

$ kubectl argo rollouts abort rollouts-demo

 

 


[출처]

1) CloudNet@, AEWS 실습 스터디

2) https://argoproj.github.io/

 

Home

Open source Kubernetes native workflows, events, CI and CD

argoproj.github.io

3) https://argo-cd.readthedocs.io/en/stable/

 

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

4) https://artifacthub.io/packages/helm/argo/argo-cd

 

argo-cd 6.7.13 · argoproj/argo

A Helm chart for Argo CD, a declarative, GitOps continuous delivery tool for Kubernetes.

artifacthub.io

5) https://argo-cd.readthedocs.io/en/stable/getting_started/

 

Getting Started - Argo CD - Declarative GitOps CD for Kubernetes

Getting Started Tip This guide assumes you have a grounding in the tools that Argo CD is based on. Please read understanding the basics to learn about these tools. Requirements Installed kubectl command-line tool. Have a kubeconfig file (default location i

argo-cd.readthedocs.io

6) https://argoproj.github.io/argo-rollouts/

 

Argo Rollouts - Kubernetes Progressive Delivery Controller

Argo Rollouts - Kubernetes Progressive Delivery Controller What is Argo Rollouts? Argo Rollouts is a Kubernetes controller and set of CRDs which provide advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and prog

argoproj.github.io

7) https://argoproj.github.io/argo-rollouts/concepts/

 

Concepts - Argo Rollouts - Kubernetes Progressive Delivery Controller

Concepts Rollout A Rollout is Kubernetes workload resource which is equivalent to a Kubernetes Deployment object. It is intended to replace a Deployment object in scenarios when more advanced deployment or progressive delivery functionality is needed. A Ro

argoproj.github.io

728x90

'AWS > EKS' 카테고리의 다른 글

[AEWS2] 8-2. Terraform으로 EKS 배포하기  (1) 2024.04.28
[AEWS2] 8-1. What is Terraform ?  (2) 2024.04.28
[AEWS2] 7-1. EKS CI/CD - Jenkins  (2) 2024.04.21
[AEWS2] 6-5. Kyverno  (0) 2024.04.13
[AEWS2] 6-4. OWASP Kubernetes Top 10  (0) 2024.04.13