요새는 쿠버네티스 배포 도구 중에서 ArgoCD를 많이 사용하는 것 같다.

ArgoCD를 사용하면 GitOps 전략을 잘 활용할 수 있다. Git 레포지토리를 사용해서 일관성, 보안, 자동화를 이점으로 선언적으로(Declarative) 배포(CD)를 진행하는 것이다.

Git에 매니페스트나 환경 파일 등을 저장하고 관리하게 된다.

Argo 프로젝트에는 ArgoCD, Argo Rollouts, Argo Events, Argo Workflows가 있다.

Home

  • ArgoCD: 쿠버네티스 매니페스트를 Git 레포에 저장해서 자동 배포를 수행하는 GitOps 도구
  • Argo Rollouts: Canary나 Blue/Green과 같은 배포 전략 지원
  • Argo Events: 이벤트 기반 종속성을 관리하며, 트리거를 설정해 다른 프로젝트 도구 실행 가능
  • Argo Workflows: 워크플로우 생성 및 관리

ArgoCD

Untitled

Argo CD - Declarative GitOps CD for Kubernetes

ArgoCD의 아키텍처를 보면 생성된 POD의 역할을 알 수 있다.

  • API Server: Web UI 대시보드로 API 서버이다.
  • Repository Server: Git과 연결해서 Git의 변경점을 체크한다.
  • Application Controller: k8s 리소스를 모니터링하고 Git 레포와 비교한다. 감지되면 OutOfSync 표시가 뜬다.
  • Redis: k8s api와 git 요청을 줄이기 위한 캐싱
  • Notification: 이벤트 알림, 트리거
  • Dex: 외부 인증 관리
  • ApplicationSet Controller: 멀티 클러스터를 위한 App 패키징 관리

설치

아르고시디 설치는 헬름으로 진행하겠다.

ALB Controller를 통해 도메인을 설정해 배포한다.

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
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 6.7.11 -f argocd-values.yaml --namespace argocd

Untitled 1

내 도메인주소로 들어가서 admin/초기암호를 입력하면 아래와 같은 화면을 볼 수 있다.

(초기암호는 secret에서 확인할 수 있다. kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo 사용)

Untitled 2

이 Web UI는 ArgoCD의 api server에 접속한 화면이다. (POD명은 argocd-server)

애플리케이션 기본 생성

이제 애플리케이션 하나를 생성해 본다.

  1. General

    Auto-create namespace를 선택하면 해당하는 네임스페이스가 없어도 자동으로 생성해 준다.

    PRUNE PROPAGATION POLICY에서 foreground는 deployment와 같은 부모 자원을 먼저 삭제한다는 것이다.

    Untitled

  2. 대상 설정

    Source에는 Git 레포를 설정하고

    Destination에는 k8s 주소 및 네임스페이스를 설정한다.

    Untitled

이제 생성된 꼴뚜기 하나 실행시켜 보겠다!

Untitled

SYNC 버튼을 누른다.

그럼 배포된 화면이 나오고 실제 리소스도 생성되었다.

Untitled 6

Untitled 7

리소스 Sync 확인

배포하고 Deployment를 클릭해 보면 LIVE MANIFEST(쿠버네티스 정보)와 DESIRED MANIFEST(Git 정보)를 볼 수 있다.

LIVE MANIFESTApplication Controller가 모니터링하는 k8s 리소스이고, DESIRED MANIFESTRepository Server가 모니터링하는 Git 리소스이다.

Untitled 8

LIVE MENIFEST를 변경하면 혹은 Git에서 변경하면 어떤 일이 생기는지 테스트해 보겠다.

  • LIVE MENIFEST에서 변경

    DIFF 없음

    Untitled 9

    Untitled 10

  • k8s에서 직접 수정

    DIFF 없음

    Untitled 11

    Untitled 12

  • Git에서 수정

    수정하고 나서 REFRESH를 눌러주면 OutOfSync를 확인할 수 있다.

    Untitled 13

    이번에 DIFF를 확인해 보면 변경점이 생겼다.

    Untitled 14

    이제 SYNC 버튼을 눌러 git과 k8s 간의 동기화를 진행해 주자!

    Untitled 15

    Untitled 16

LIVE MENIFEST 혹은 k8s에서 직접 수정 시에는 DIFF가 발생하지 않았는데 git에서 수정하니 DIFF가 바로 보였다.

이는 변경 기준은 Git으로부터 발생한다는 점을 알 수 있었고

이게 바로 GitOps 구나, 이래서 Git에서 매니페스트를 관리하고 히스토리를 보존한다는 것이구나를 느꼈다.

ArgoCD CLI

ArgoCD는 UI로도 할 수 있지만 CLI도 가능하다.

젠킨스에서 진행하려면 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

Untitled 17

ArgoCD에 로그인한다.

UI에서 로그인한 정보로 입력해 주자

Untitled 18

클러스터 정보도 설정해 주어야 한다.

kubectl config get-contexts -o name
admin@myeks.ap-northeast-2.eksctl.io
argocd cluster add admin@myeks.ap-northeast-2.eksctl.io

클러스터의 네임스페이스도 지정해 주고

kubectl config set-context --current --namespace=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

Untitled 19

Untitled 20

생성된 것을 확인했으면 Sync를 진행하자

argocd app sync guestbook
argocd app get guestbook

Untitled 21

바로 동기화가 완료되었다.

삭제도 간단하게 argocd app delete guestbook로 진행하면 된다.

Argo Rollouts

Rollouts은 Canary 배포와 Blue/Green 배포 전략을 사용할 수 있다.

기본 쿠버네티스에서 제공하는 배포 전략은 Recreate와 Rolling Update가 있고 더 나아가 labels와 replicas를 적절히 사용하면 두 배포 전략을 사용할 수 있다.

하지만 Argo가 배포 전략을 사용하는 데에 있어 더 편리성을 제공해 주는 것 같다.

설치

우선 헬름차트로 생성할 때 ALB Controller 사용을 위한 values 파일을 만들고

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

가끔 가다가 ALB 통해 배포가 안될 때 보면 cert 값이 제대로 안들어가 있었다. 꼭 확인해 주자!

네임스페이스를 생성하고 헬름인스톨을 진행한다.

kubectl create ns argo-rollouts
helm install argo-rollouts argo/argo-rollouts --version 2.35.1 -f argorollouts-values.yaml --namespace argo-rollouts

Untitled 22

Untitled 23

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

배포 테스트

카나리 배포 전략을 사용해서 점진적으로 배포할 것이다.

카나리 배포 코드의 경우 spec.strategy에 배포 세부 설정을 할 수 있다.

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

가중치를 일부 주고 pause로 대기 시간을 준다. 점진적으로 신규 버전으로 배포가 가능하다.

rollout은 cli로 진행해 보겠다.

우선 기본 테스트 POD를 배포한다.

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

Untitled 24

Untitled 25

이미지 태그 값에 yellow 버전으로 지정하고 rollout을 진행한다.

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

그러면 조금씩 가중치 퍼센티지를 늘려서 점진적으로 배포할 수 있다. 이 때 pause 값으로 아무것도 지정하지 않아서 멈춰있다.

Untitled 26

Untitled 27

promote로 멈춰 있는 배포를 이어서 진행할 수 있다.

kubectl argo rollouts promote rollouts-demo

Untitled 28

Untitled 29

기본 설정대로 전부 신규 파드로 배포 성공했다.

중간에 시간 초 없는 pause로 테스트 버전 서버 올리고 이상있으면 바로 롤백하는 것이 개발 테스트할 때 편리해 보였다.

그래서 red 버전을 올렸다가 kubectl argo rollouts abort rollouts-demo로 abort를 진행했는데 revision 5가 생기면서 올라온 POD가 다운되었고

Untitled 30

kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow로 현재 버전을 yellow로 원복하니 revision이 6가 되면서 원복되었다!

Untitled 31

확실히 단순 롤링업데이트 보다는 더 고급지고 편리한 배포 전략을 사용할 수 있었다.

Categories:

Updated:

Leave a comment