이번 주차는 Gitops와 관련된 내용(Gitlab과 ArgoCD,Harbor 툴 사용법)을 스터디 했다. gitops 관련 정보는 다양하게 있는데 우선 gitops란 CD에 초점을 두고 있다. 애플리케이션 배포와 운영에 관련된 모든 요소를 코드화 하여 Git에서 관리(Ops) 하는것이 핵심이며 기본 개념 자체도 IaC로부터 파생되었다.
따라서 선언형모델과 SSOT(단일 공급원)이 매우 중요하다
- 선언형 모델?
- 과거 레거시 한 방식은 원격의 워치에 접속(ssh) 하여 명령어를 실행해 배포하였는데 단순한 만큼 예외상황 관리나 서버 대수가 많아지면 많아질수록 관리에 리소스가 점점 높아진다. 따라서 k8s의 yaml 형식이나 terraform hcl 코드처럼 선언하여 상태를 싱크하는 형태로 진화해 나갔다.
- SSOT?
- 같은 데이터가 여러 곳에 있는경우 이것은 충돌로 이루어 지며 선언형과 싱크되고 있는 원격지의 상태가 깨질수 있다(비정합성) 따라서, 배포의 원천은 한곳으로 통일하여 관리하는것을 중점으로 둔다.
자 그러면 일단 ArgoCD나 Git의 기본적인 부분은 넘어가고 좀더 어드벤스드하게 Argo Rollout을 좀 테스트 해보고자 한다.
Why Argo Rollout?
우선 k8s에서 Blue/Green이나 Canary 배포나 메트릭기반의 자동화된 promo는 기본적은 ArgoCD에서 구성하기 쉽지 않다. 그것을 도와주는 컨트롤러가 Rollout 컨트롤러이다. 또한 각종 Service Mesh나 Ingress Controller와 통합 되어 있어 트래픽이 매끄럽게 제어되기에 유연하게 배포가 가능하다.(참고로 AWS App Mesh도 적용 가능하다.)
그리고 각종 메트릭 지표를 통해 자동으로 promo할수 있게 설정이 가능하기 때문에 사람이 할 일을 최소화 할 수 있다.
Work flow?
위처럼 Argo Rollout은 RS를 버저닝 하면서 배포된다. 따라서 안정적으로 버저닝되며 Analysis과 통합되어 자동으로 RS를 조정하고 버전을 변경한다.
나는 우선 https://github.com/argoproj/rollouts-demo 이 데모 어플리케이션을 통해 배포를 테스트 해볼거다.
Rollout Install
먼저 오퍼레이터를 설치해줘야 한다.
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
다음은 argo rollout promo를 위한 cli를 설치할 것이다.(dashboard를 보는법도 여기서 배워보겠다)
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-darwin-amd64
chmod +x ./kubectl-argo-rollouts-darwin-amd64
sudo mv ./kubectl-argo-rollouts-darwin-amd64 /usr/local/bin/kubectl-argo-rollouts
$ k argo rollouts version
kubectl-argo-rollouts: v1.3.2+f780534
BuildDate: 2022-12-15T16:06:35Z
GitCommit: f780534ebd66a4047c813ddd7841be93b122c3e6
GitTreeState: clean
GoVersion: go1.18.9
Compiler: gc
Platform: darwin/amd64
Sample 배포
https://argoproj.github.io/argo-rollouts/getting-started/alb/
이 친구를 활용할거다. 다만 나는 k8s v1.25를 사용하고 있기 때문에 ingress를 아래처럼 고쳐줘야 한다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rollouts-demo-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
spec:
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: rollouts-demo-root
port:
name: use-annotation
자 잘 돌고 있다면 이제 배포를 한번 해보겠다.
CLI로 해보기
$ kubectl argo rollouts get rollout rollouts-demo
Name: rollouts-demo
Namespace: default
Status: ✔ Healthy
Strategy: Canary
Step: 2/2
SetWeight: 100
ActualWeight: 100
Images: argoproj/rollouts-demo:blue (stable)
Replicas:
Desired: 1
Current: 1
Updated: 1
Ready: 1
Available: 1
NAME KIND STATUS AGE INFO
⟳ rollouts-demo Rollout ✔ Healthy 9m18s
└──# revision:1
└──⧉ rollouts-demo-687d76d795 ReplicaSet ✔ Healthy 6m18s stable
└──□ rollouts-demo-687d76d795-cwtx8 Pod ✔ Running 6m18s ready:1/1
위처럼 명령어를 입력하면 rollouts-demo라는 부분에 버전과 현재 rs그리고 pod정보를 알 수 있다. 배포는 canary 형태로 해볼거다.
$kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow
$ kubectl argo rollouts get rollout rollouts-demo
Name: rollouts-demo
Namespace: default
Status: ॥ Paused
Message: CanaryPauseStep
Strategy: Canary
Step: 1/2
SetWeight: 5
ActualWeight: 5
Images: argoproj/rollouts-demo:blue (stable)
argoproj/rollouts-demo:yellow (canary)
Replicas:
Desired: 1
Current: 2
Updated: 1
Ready: 2
Available: 2
NAME KIND STATUS AGE INFO
⟳ rollouts-demo Rollout ॥ Paused 12m
├──# revision:2
│ └──⧉ rollouts-demo-6cf78c66c5 ReplicaSet ✔ Healthy 6s canary
│ └──□ rollouts-demo-6cf78c66c5-lw7fh Pod ✔ Running 6s ready:1/1
└──# revision:1
└──⧉ rollouts-demo-687d76d795 ReplicaSet ✔ Healthy 9m8s stable
└──□ rollouts-demo-687d76d795-cwtx8 Pod ✔ Running 9m8s ready:1/1
위처럼 KIND에 Rollout이라고 배포가 되었다. SetWeight를 5로 주었다. canary로 배포되기 때문에 가중치가 변경되었을 것이다. alb의 규칙이 정상적으로 변경되었는지 확인해보자
정상적으로 싱크되며 라우팅되고 있다.
배포도 잘 된게 확인된다. 이제 promo해보겠다
$ kubectl argo rollouts promote rollouts-demo
$ kubectl argo rollouts get rollout rollouts-demo
Name: rollouts-demo
Namespace: default
Status: ✔ Healthy
Strategy: Canary
Step: 2/2
SetWeight: 100
ActualWeight: 100
Images: argoproj/rollouts-demo:blue
argoproj/rollouts-demo:yellow (stable)
Replicas:
Desired: 1
Current: 2
Updated: 1
Ready: 2
Available: 2
NAME KIND STATUS AGE INFO
⟳ rollouts-demo Rollout ✔ Healthy 16m
├──# revision:2
│ └──⧉ rollouts-demo-6cf78c66c5 ReplicaSet ✔ Healthy 4m34s stable
│ └──□ rollouts-demo-6cf78c66c5-lw7fh Pod ✔ Running 4m34s ready:1/1
└──# revision:1
└──⧉ rollouts-demo-687d76d795 ReplicaSet ✔ Healthy 13m delay:20s
└──□ rollouts-demo-687d76d795-cwtx8 Pod ✔ Running 13m ready:1/1
위처럼 promote 명령어를 통해 변경이 가능하다.
ALB의 트래픽도 정상적으로 변경 되었고 환경도 완전이 넘어갔다. 다만 이게 가중치도 5%인데 한방에 넘어가는게 조금 불편하다. 위험하지 않을까?
그건 이 부분에 자세하게 나와있다.
https://argoproj.github.io/argo-rollouts/features/canary/
위 Docs를 참고해서 일부 설정을 변경해 보겠다.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
spec:
replicas: 10
strategy:
canary:
...
steps:
- setWeight: 25
- pause: {}
- setWeight: 50
- pause: {duration: 30s}
- setWeight: 75
- pause: {duration: 30s}
...
위처럼 Rollout에 steps 을 변경해 주었다. 그리고 좀더 가시적으로 보기 위해 replicas를 높혔다. 다음 위와 같은 순서로 배포해보자
$ kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:blue
$ kubectl argo rollouts get rollout rollouts-demo
Name: rollouts-demo
Namespace: default
Status: ॥ Paused
Message: CanaryPauseStep
Strategy: Canary
Step: 3/6
SetWeight: 50
ActualWeight: 50
Images: argoproj/rollouts-demo:blue (canary)
argoproj/rollouts-demo:yellow (stable)
Replicas:
Desired: 10
Current: 15
Updated: 5
Ready: 15
Available: 15
NAME KIND STATUS AGE INFO
⟳ rollouts-demo Rollout ॥ Paused 36m
├──# revision:7
│ └──⧉ rollouts-demo-687d76d795 ReplicaSet ✔ Healthy 33m canary
│ ├──□ rollouts-demo-687d76d795-47z5m Pod ✔ Running 47s ready:1/1
│ ├──□ rollouts-demo-687d76d795-8nrjb Pod ✔ Running 47s ready:1/1
│ ├──□ rollouts-demo-687d76d795-gzdv7 Pod ✔ Running 47s ready:1/1
│ ├──□ rollouts-demo-687d76d795-htrtz Pod ✔ Running 22s ready:1/1
│ └──□ rollouts-demo-687d76d795-l7nnc Pod ✔ Running 22s ready:1/1
└──# revision:6
└──⧉ rollouts-demo-6cf78c66c5 ReplicaSet ✔ Healthy 24m stable
├──□ rollouts-demo-6cf78c66c5-7nshf Pod ✔ Running 4m9s ready:1/1
├──□ rollouts-demo-6cf78c66c5-kdqrc Pod ✔ Running 4m9s ready:1/1
├──□ rollouts-demo-6cf78c66c5-qgcgw Pod ✔ Running 4m9s ready:1/1
├──□ rollouts-demo-6cf78c66c5-btlnq Pod ✔ Running 3m53s ready:1/1
├──□ rollouts-demo-6cf78c66c5-clj9q Pod ✔ Running 3m53s ready:1/1
├──□ rollouts-demo-6cf78c66c5-dsn5k Pod ✔ Running 3m53s ready:1/1
├──□ rollouts-demo-6cf78c66c5-hjmb8 Pod ✔ Running 3m53s ready:1/1
├──□ rollouts-demo-6cf78c66c5-nsb6w Pod ✔ Running 3m53s ready:1/1
├──□ rollouts-demo-6cf78c66c5-qqrpm Pod ✔ Running 3m53s ready:1/1
└──□ rollouts-demo-6cf78c66c5-vh9ts Pod ✔ Running 3m53s ready:1/1
배포가 되었고 가중치도 75:25에서 50:50 이 된다. 10분을 주었기 때문에 10분까지 기다려야 하지만 그냥 확인했다 치고 한번더 명령어를 치겠다.
$ kubectl argo rollouts promote rollouts-demo
$ kubectl argo rollouts get rollout rollouts-demo
Name: rollouts-demo
Namespace: default
Status: ॥ Paused
Message: CanaryPauseStep
Strategy: Canary
Step: 5/6
SetWeight: 75
ActualWeight: 75
Images: argoproj/rollouts-demo:blue (canary)
argoproj/rollouts-demo:yellow (stable)
Replicas:
Desired: 10
Current: 18
Updated: 8
Ready: 18
Available: 18
NAME KIND STATUS AGE INFO
⟳ rollouts-demo Rollout ॥ Paused 37m
├──# revision:7
│ └──⧉ rollouts-demo-687d76d795 ReplicaSet ✔ Healthy 34m canary
│ ├──□ rollouts-demo-687d76d795-47z5m Pod ✔ Running 105s ready:1/1
│ ├──□ rollouts-demo-687d76d795-8nrjb Pod ✔ Running 105s ready:1/1
│ ├──□ rollouts-demo-687d76d795-gzdv7 Pod ✔ Running 105s ready:1/1
│ ├──□ rollouts-demo-687d76d795-htrtz Pod ✔ Running 80s ready:1/1
│ ├──□ rollouts-demo-687d76d795-l7nnc Pod ✔ Running 80s ready:1/1
│ ├──□ rollouts-demo-687d76d795-6skmj Pod ✔ Running 2s ready:1/1
│ ├──□ rollouts-demo-687d76d795-dcpvc Pod ✔ Running 2s ready:1/1
│ └──□ rollouts-demo-687d76d795-rlstd Pod ✔ Running 2s ready:1/1
└──# revision:6
└──⧉ rollouts-demo-6cf78c66c5 ReplicaSet ✔ Healthy 25m stable
├──□ rollouts-demo-6cf78c66c5-7nshf Pod ✔ Running 5m7s ready:1/1
├──□ rollouts-demo-6cf78c66c5-kdqrc Pod ✔ Running 5m7s ready:1/1
├──□ rollouts-demo-6cf78c66c5-qgcgw Pod ✔ Running 5m7s ready:1/1
├──□ rollouts-demo-6cf78c66c5-btlnq Pod ✔ Running 4m51s ready:1/1
├──□ rollouts-demo-6cf78c66c5-clj9q Pod ✔ Running 4m51s ready:1/1
├──□ rollouts-demo-6cf78c66c5-dsn5k Pod ✔ Running 4m51s ready:1/1
├──□ rollouts-demo-6cf78c66c5-hjmb8 Pod ✔ Running 4m51s ready:1/1
├──□ rollouts-demo-6cf78c66c5-nsb6w Pod ✔ Running 4m51s ready:1/1
├──□ rollouts-demo-6cf78c66c5-qqrpm Pod ✔ Running 4m51s ready:1/1
└──□ rollouts-demo-6cf78c66c5-vh9ts Pod ✔ Running 4m51s ready:1/1
이젠 25:75로 대부분 넘어갔다.
이런식으로 단계별로 트래픽 전환이 가능하다. 만약 정말 크리티컬하고 조금씩 전환해야 한다면 가중치를 낮추고 여러가지 전략을 적용할 수 있을것이다.
Dashboard 활용
Argo Rollout은 자체 Dashboard도 지원한다. ArgoCD에 내장된 기능으로 볼수 있지만 둘은 완전 다르게 동작하며 ArgoCD에서는 메뉴얼한 Promo가 불가능하다(라고 알고있음...) 그래서 auto promo 기능을 활용하고 AnalysisTemplate 최대한 잘 활용해서 트레픽을 넘겨야 한다.
CLI로 하나하나 하기 어렵다면 Dashboard로 먼저 접근해 보는것도 나쁘지 않다.
$ kubectl argo rollouts dashboard
INFO[0000] Argo Rollouts Dashboard is now available at http://localhost:3100/rollouts
위 명령어를 동작시키면 3100포트로 웹 서비스가 실행된다.
ArgoCD와 굉장히 유사한 Dashboard가 수행된다.
실제로 지금 테스트 하고 있는 rollout resource의 상세 정보도 볼 수 있다. 위처럼 step이 나뉘어 자동으로 돌아가고 있고 필요에 따라 이전 버전으로 빠르게 rollback도 가능하다.
이렇듯 다양한 전략을 제공하기 때문에 ArgoCD만 사용하는게 아니라 서비스 배포에 Rollout도 함께 Helm으로 패키징 하여 활용하면 보다 효율적인 DevOps 체계와 배포 전략을 가지고 갈 수 있다.
'Server Infra > Kubernetes' 카테고리의 다른 글
Container를 경량화 하기 위한 툴 (0) | 2024.08.28 |
---|---|
PKOS 2기 4주차 - Argo Rollout(feat. Prometheus) (0) | 2023.04.02 |
PKOS 2기 2주차 - k8s network(feat. EKS) (0) | 2023.03.12 |
PKOS 2기 1주차 - kops (0) | 2023.03.06 |
Chaos mesh!! (0) | 2022.11.07 |