[AEKS2] 7주차 - EKS CI/CD: ArgoCD
요새는 쿠버네티스 배포 도구 중에서 ArgoCD를 많이 사용하는 것 같다.
ArgoCD를 사용하면 GitOps 전략을 잘 활용할 수 있다. Git 레포지토리를 사용해서 일관성, 보안, 자동화를 이점으로 선언적으로(Declarative) 배포(CD)를 진행하는 것이다.
Git에 매니페스트나 환경 파일 등을 저장하고 관리하게 된다.
Argo 프로젝트에는 ArgoCD, Argo Rollouts, Argo Events, Argo Workflows가 있다.
- ArgoCD: 쿠버네티스 매니페스트를 Git 레포에 저장해서 자동 배포를 수행하는 GitOps 도구
- Argo Rollouts: Canary나 Blue/Green과 같은 배포 전략 지원
- Argo Events: 이벤트 기반 종속성을 관리하며, 트리거를 설정해 다른 프로젝트 도구 실행 가능
- Argo Workflows: 워크플로우 생성 및 관리
ArgoCD
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
내 도메인주소로 들어가서 admin/초기암호를 입력하면 아래와 같은 화면을 볼 수 있다.
(초기암호는 secret에서 확인할 수 있다. kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
사용)
이 Web UI는 ArgoCD의 api server에 접속한 화면이다. (POD명은 argocd-server)
애플리케이션 기본 생성
이제 애플리케이션 하나를 생성해 본다.
-
General
Auto-create namespace를 선택하면 해당하는 네임스페이스가 없어도 자동으로 생성해 준다.
PRUNE PROPAGATION POLICY에서 foreground는 deployment와 같은 부모 자원을 먼저 삭제한다는 것이다.
-
대상 설정
Source에는 Git 레포를 설정하고
Destination에는 k8s 주소 및 네임스페이스를 설정한다.
이제 생성된 꼴뚜기 하나 실행시켜 보겠다!
SYNC
버튼을 누른다.
그럼 배포된 화면이 나오고 실제 리소스도 생성되었다.
리소스 Sync 확인
배포하고 Deployment를 클릭해 보면 LIVE MANIFEST
(쿠버네티스 정보)와 DESIRED MANIFEST
(Git 정보)를 볼 수 있다.
LIVE MANIFEST
는 Application Controller가 모니터링하는 k8s 리소스이고, DESIRED MANIFEST
는 Repository Server가 모니터링하는 Git 리소스이다.
LIVE MENIFEST를 변경하면 혹은 Git에서 변경하면 어떤 일이 생기는지 테스트해 보겠다.
-
LIVE MENIFEST에서 변경
DIFF 없음
-
k8s에서 직접 수정
DIFF 없음
-
Git에서 수정
수정하고 나서 REFRESH를 눌러주면 OutOfSync를 확인할 수 있다.
이번에 DIFF를 확인해 보면 변경점이 생겼다.
이제 SYNC 버튼을 눌러 git과 k8s 간의 동기화를 진행해 주자!
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
ArgoCD에 로그인한다.
UI에서 로그인한 정보로 입력해 주자
클러스터 정보도 설정해 주어야 한다.
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
생성된 것을 확인했으면 Sync를 진행하자
argocd app sync guestbook
argocd app get guestbook
바로 동기화가 완료되었다.
삭제도 간단하게 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
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
이미지 태그 값에 yellow 버전으로 지정하고 rollout을 진행한다.
kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow
그러면 조금씩 가중치 퍼센티지를 늘려서 점진적으로 배포할 수 있다. 이 때 pause 값으로 아무것도 지정하지 않아서 멈춰있다.
promote로 멈춰 있는 배포를 이어서 진행할 수 있다.
kubectl argo rollouts promote rollouts-demo
기본 설정대로 전부 신규 파드로 배포 성공했다.
중간에 시간 초 없는 pause로 테스트 버전 서버 올리고 이상있으면 바로 롤백하는 것이 개발 테스트할 때 편리해 보였다.
그래서 red 버전을 올렸다가 kubectl argo rollouts abort rollouts-demo
로 abort를 진행했는데 revision 5가 생기면서 올라온 POD가 다운되었고
kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow
로 현재 버전을 yellow로 원복하니 revision이 6가 되면서 원복되었다!
확실히 단순 롤링업데이트 보다는 더 고급지고 편리한 배포 전략을 사용할 수 있었다.
Leave a comment