[k8s] Argo Rollouts: Blue Green Deploy
์ด์ ํฌ์คํธ
https://blog.naver.com/sssang97/223134344138
Argo Rollouts์ ์ฌ์ฉํด์ Blue-Green ๋ฐฐํฌ๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ค๋ณด๊ฒ ๋ค.
์ฐ์ ์๋น์ค๊ฐ 2๊ฐ ์์ด์ผ ํ๋ค.
ํ๋๋ ํ๋ก๋์
๋ฐฐํฌ์ฉ ์๋ํฌ์ธํธ๊ณ , ํ๋๋ ์ ๋ฒ์ ์ ๋ฐฐํฌํ ๋ ํ
์คํธํ ์ฉ๋์ ์๋ํฌ์ธํธ๋ค.
apiVersion: v1
kind: Service
metadata:
name: prod-service
spec:
selector:
app: bg-server
ports:
- protocol: TCP
port: 80
type: LoadBalancerapiVersion: v1
kind: Service
metadata:
name: test-service
spec:
selector:
app: bg-server
ports:
- protocol: TCP
port: 80
type: LoadBalancer
๋๋ค ์ผ๋จ ํ๋์ ์ฑ(bg-server)๋ง ๊ฐ๋ฆฌํค๊ฒ ํด๋จ๋ค.
๊ทธ๋ฆฌ๊ณ Rollout์ ์ฌ์ฉํด์ ๋ฆฌ์์ค๋ฅผ ์ ์ํ๋ค.
Rollout๋ Deployment์ ์ ์ฌํ ํํ์ ์ปค์คํ
์ปจํธ๋กค๋ฌ๋ค.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: bg-server
spec:
replicas: 3
revisionHistoryLimit: 2
selector:
matchLabels:
app: bg-server
template:
metadata:
labels:
app: bg-server
spec:
containers:
- name: bg-server
image: myyrakle/node-server-for-test:1
imagePullPolicy: Always
ports:
- containerPort: 80
strategy:
blueGreen:
activeService: prod-service
previewService: test-service
autoPromotionEnabled: false
blueGreen ํ๋์ ๊ถ๊ธํดํ ๋งํ ๋๋ถ๋ถ์ ์ต์
์ด ๋ค์ด์๋ค.
๋ฐฉ๊ธ ์ ์ํ 2๊ฐ์ ์๋น์ค๋ฅผ ์ฐ๊ฒฐํ๊ณ autoPromotionEnabled๋ฅผ false๋ก ํ๋ค.
autoPromotionEnabled๋ ์ ๋ฒ์ ์ด ๋ฌธ์ ์์ด ๋ด์๋ blue-green ์ค์์นญ์ ์๋์ผ๋ก ํ ๊ฒ์ธ์ง์ ๋ํ ๊ฒ์ด๋ค.
์๋์ผ๋ก ํ๊ฒ ํด๋ ์ข์ง๋ง, ์ผ๋จ์ ํ ์คํธ๋ฅผ ์ํด ์๋์ผ๋ก ํ๊ฒ ํ๋ค.
์ด๋ฏธ์ง myyrakle/node-server-for-test:1๋ ๋ด๊ฐ ํ
์คํธ์ฉ์ผ๋ก ๋ง์๋ ๊ฐ๋จํ ์๋ฒ๋ค.
์ด์ ์ ๊ฑธ myyrakle/node-server-for-test:2๋ก ์ฌ๋ฆฌ๋ฉด์ ๋ฐฐํฌ๋ฅผ ์ํํด๋ณผ ๊ฒ์ด๋ค.
์ผ๋จ ์ ์ด๊ธฐ ๊ตฌ์ฑ๋๋ก ๋ฆฌ์์ค๋ค์ ๊ฒ์ํ๋ค.
๊ทธ๋ผ Rollout์ ๊ธฐ๋ฐ์ผ๋ก ๋ ํ๋ฆฌ์นด Pod๊ฐ 3๊ฐ ๋ฐ ๊ฒ์ด๊ณ

์๋น์ค๋ก ์คํ๋ ์ ๋ ๊ฒ์ด๋ค.

๋ฐฐํฌ๋ฅผ ์งํํ์ง ์๋ ์ํ์์๋ ๋๋ค ๊ฐ์ Pod ๊ทธ๋ฃน์ ๊ฐ๋ฆฌํจ๋ค.
kubectl argo rollouts list rollout

Blue-Green ๋ฐฐํฌ ์คํ
ArcoCD๋ก gitops ๊ธฐ๋ฐ์ ๊ตฌ์ฑํด๋๋ค๋ฉด, ๊ทธ๋ฅ ์ด๋ฏธ์ง ๋ฒ์ ๋ง ์์ ํ๋ฉด ๋๋ค.

๊ทธ๋ฌ๋ฉด ๊ฐ๋์ ์์ํด์

์ถ๊ฐ ํ๋๋ฅผ ๋์ฐ๊ณ


test์ฉ ์๋น์ค์ ์ ๋ฐฐํฌ ๋ฒ์ ์ด ๋ผ์ฐํ ๋ ๊ฒ์ด๋ค.

๊ทธ๋ฆฌ๊ณ Pod ํ๋ก๋น์ ๋์ด ์๋ฃ๋๋ฉด ์ ์ง ์ํ๊ฐ ๋๋ค.
๊ทผ๋ฐ ์ด๊ฑด autoPromotionEnabled๋ฅผ ๊บผ๋์ ๊ทธ๋ ๊ณ , ์ผ๋จ๋ค๋ฉด ์๋์ผ๋ก ์ค์์นญ์ ์ํํ ๊ฒ์ด๋ค.
์ง๊ธ์ ์ ๊ฑธ ์๋์ผ๋ก ์ค์์นญํด๋ณด๊ฒ ๋ค.
๋ค์๊ณผ ๊ฐ์ด CLI๋ฅผ ์ฌ์ฉํด์ ๋ณ๊ฒฝ์ ํธ๋ฆฌ๊ฑฐํ๋ฉด ๋๋ค.

๊ทธ๋ฌ๋ฉด ํ๋ก๋์ ์๋น์ค๋ ์ค์์นญ์ด ๋ ๊ฒ์ด๊ณ

๊ธฐ์กด ๋ฒ์ ๋ ๋ด๋ ค๊ฐ๊ณ

๋ฐฐํฌ๊ฐ ๋๋ ๊ฒ์ด๋ค.

๋ฌด์ค๋จ ๋ฐฐํฌ
๊ทธ๋ฐ๋ฐ ์ ๋๋ก autoPromotionEnabled๋ง ์ผ๊ธฐ์๋ ๊ตฌ์ฑ์ ๋ฌธ์ ๊ฐ ์ข ์๋ค.
๋ฐ๋ก ๋ญ ์ค์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ Pod๋ค๋ง ๋ค ๋จ๋ฉด ๋ฐ๋ก ๊ฐ์๋ฒ๋ฆฐ๋ค๋ ๊ฒ์ธ๋ฐ, Pod๊ฐ ๋จ๋ ๊ฒ๊ณผ ๊ทธ ์์์ ์ค์ ์๋ฒ๊ฐ ๋ค ๋จ๋์ง๋ ๋ณ๊ฐ์ด๊ธฐ ๋๋ฌธ์ด๋ค...
๊ฐ์ฅ ๊ฐ๋จํ๊ฒ ์ ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ autoPromotionSeconds์ผ๋ก ์ค์์นญ์ ์ํํ๊ธฐ ์ ์ ๋๊ธฐ์๊ฐ์ ๋ฃ์ด์ฃผ๋ ๊ฒ์ด๋ค.
์ง๊ธ ๋ด ์๋ฒ๊ฐ ๋จ๋ ์๊ฐ์ด ์ด์ง๊ฐํด์๋ 10์ด ์์ ๋ค ๋๋ ๊ฒ ๊ฐ๋ค. ํ๋ฉด ์ด๋ ๊ฒ 10์ด๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.

Health Check
ํ์ง๋ง ์ ๊ฒ๋ง์ผ๋ก๋ ๋ถ์กฑํ ์ ์๋ค.
์๋ก ๋ฌ ๋ฒ์ ์ด ํญ์ ์๋ฒฝํ๊ฒ ์คํ๋๋ค๋ ๋ณด์ฅ์ด ์๋๊ฐ? ๊ฐ์๊ธฐ ์ธํ
์ด ๊ผฌ์ฌ์ 500์ด ๋ฐ ์๋ ์์ง ์์๊ฐ?
์ด ๋๋ฌธ์, ๋ณดํต ์ค์์นญ์ ํ๊ธฐ ์ ์ ์ ๋ฒ์ ์ ๋ํ Health Check๋ก ๊ฒ์ฆ์ ์ํํ๋ ๊ฒ์ ๊ฝค๋ ๊ธฐ๋ณธ์ ์ธ ์์ ์ด๋ค.
์ด๋ฅผ ์ํด์๋ ๋จผ์ AnalysisTemplate์ผ๋ก ๊ฒ์ฆ์ ์ํ ์ ์๋ฅผ ๋ง๋ค์ด์ค์ผ ํ๋ค.
๋ณดํต์ ํ๋ก๋ฉํ
์ฐ์ค์ ์ฐ๊ณํด์ ์ํํ์ธ์ ํ๋ ํธ์ด๋ค.
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 5m
# NOTE: prometheus queries return results in the form of a vector.
# So it is common to access the index 0 of the returned array to obtain the value
successCondition: result[0] >= 0.95
failureLimit: 3
provider:
prometheus:
address: http://prometheus.example.com:9090
query: |
sum(irate(
istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code!~"5.*"}[5m]
)) /
sum(irate(
istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m]
))
๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฑธ ๊ฐ์ ธ๋ค๊ฐ prePromotionAnalysis์ ๋ฑ๋กํด์ฃผ๋ฉด ๋์ด๋ค.

์ฐธ์กฐ
https://argoproj.github.io/argo-rollouts/features/bluegreen/
https://argo-rollouts.readthedocs.io/en/stable/features/analysis/