Gitlab CI์ ์๋ GitOps๋ฅผ ์ฌ์ฉํ์ฌ Kubernetes์์ Canary ๋ฐฐํฌ๋ฅผ ๊ตฌํํ๊ณ ์ฌ์ฉํฉ๋๋ค.
์ด ์๋ฆฌ์ฆ์ ๊ธฐ์ฌ:
- (์ด ๊ธฐ์ฌ)
ArgoCI๋ฅผ ์ฌ์ฉํ ์นด๋๋ฆฌ์ ๋ฐฐํฌ - Istio๋ฅผ ์ฌ์ฉํ ์นด๋๋ฆฌ์ ๋ฐฐํฌ
- Jenkins-X Istio Flagger๋ฅผ ์ฌ์ฉํ ์นด๋๋ฆฌ์ ๋ฐฐํฌ
GitOps๋ฅผ ํตํด Canary ๋ฐฐํฌ๋ฅผ ์๋์ผ๋ก ์ํํ๊ณ ๊ธฐ๋ณธ Kubernetes ๋ฆฌ์์ค๋ฅผ ์์ฑ/์์ ํ๊ฒ ์ต๋๋ค. ์ด ๊ธฐ์ฌ๋ ์ฃผ๋ก ์๊ฐ์ฉ์ผ๋ก ์์ฑ๋์์ต๋๋ค. ๋ค์ ๊ธฐ์ฌ์์ ๊ณ ๋ คํ ๋ณด๋ค ํจ๊ณผ์ ์ธ ์๋ํ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ์ Kubernetes Canary์์ ๋ฐฐํฌ๊ฐ ์๋ํ๋ ๋ฐฉ์์ ๋ํด ์ค๋ช ํฉ๋๋ค.
์นด๋๋ฆฌ์ ๋ฐฐํฌ
์นด๋๋ฆฌ์ ์ ๋ต์ ์ฌ์ฉํ๋ฉด ๋จผ์ ์ผ๋ถ ์ฌ์ฉ์์๊ฒ๋ง ์ ๋ฐ์ดํธ๊ฐ ์ ์ฉ๋ฉ๋๋ค. ๋ชจ๋ํฐ๋ง, ๋ก๊ทธ ๋ฐ์ดํฐ, ์๋ ํ ์คํธ ๋๋ ๊ธฐํ ํผ๋๋ฐฑ ์ฑ๋์ ํตํด ๋ฆด๋ฆฌ์ค๋ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ๋ฆด๋ฆฌ์ค๋๊ธฐ ์ ์ ํ ์คํธ๋ฉ๋๋ค.
Kubernetes ๋ฐฐํฌ(๋กค๋ง ์ ๋ฐ์ดํธ)
Kubernetes ๋ฐฐํฌ์ ๊ธฐ๋ณธ ์ ๋ต์ ๋กค๋ง ์ ๋ฐ์ดํธ์ด๋ฉฐ, ์ฌ๊ธฐ์ ํน์ ์์ Pod๊ฐ ์ ๋ฒ์ ์ ์ด๋ฏธ์ง๋ก ์์๋ฉ๋๋ค. ๋ฌธ์ ์์ด ์์ฑ๋ ๊ฒฝ์ฐ ์ด์ ๋ฒ์ ์ ์ด๋ฏธ์ง๊ฐ ํฌํจ๋ ํฌ๋๊ฐ ์ข ๋ฃ๋๊ณ ์ ํฌ๋๊ฐ ๋ณ๋ ฌ๋ก ์์ฑ๋ฉ๋๋ค.
GitOps
์ด ์์์๋ ๋ค์๊ณผ ๊ฐ์ ์ด์ ๋ก GitOps๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- Git์ ๋จ์ผ ์ ๋ณด ์์ค๋ก ์ฌ์ฉ
- ๋น๋ ๋ฐ ๋ฐฐํฌ์ Git Operations๋ฅผ ์ฌ์ฉํฉ๋๋ค(git tag/merge ์ด์ธ์ ๋ช ๋ น์ ํ์ํ์ง ์์ต๋๋ค).
์
๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์ฉ ๋ฆฌํฌ์งํ ๋ฆฌ ํ๋์ ์ธํ๋ผ์ฉ ๋ฆฌํฌ์งํ ๋ฆฌ ํ๋๋ฅผ ๊ฐ๋ ๊ฒ์ ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ์ฅ์
์ด๋ ์๋ต์ JSON์ผ๋ก ๋ฐํํ๋ ๋งค์ฐ ๊ฐ๋จํ Python+Flask API์ ๋๋ค. GitlabCI๋ฅผ ํตํด ํจํค์ง๋ฅผ ๋น๋ํ๊ณ ๊ฒฐ๊ณผ๋ฅผ Gitlab ๋ ์ง์คํธ๋ฆฌ์ ํธ์ํ๊ฒ ์ต๋๋ค. ๋ ์ง์คํธ๋ฆฌ์๋ ๋ ๊ฐ์ง ๋ฆด๋ฆฌ์ค ๋ฒ์ ์ด ์์ต๋๋ค.
wuestkamp/k8s-deployment-example-app:v1
wuestkamp/k8s-deployment-example-app:v2
์ด๋ค ์ฌ์ด์ ์ ์ผํ ์ฐจ์ด์ ์ ๋ฐํ๋ JSON ํ์ผ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋๋ค. ์ฐ๋ฆฌ๋ ์ด๋ค ๋ฒ์ ๊ณผ ํต์ ํ๊ณ ์๋์ง ๊ฐ๋ฅํ ํ ์ฝ๊ฒ ์๊ฐํํ๊ธฐ ์ํด ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉํฉ๋๋ค.
์ธํ๋ผ ์ ์ฅ์
์ด ์๋ฌด์์๋ GitlabCI๋ฅผ ํตํด Kubernetes์ ๋ฐฐํฌํฉ๋๋ค. .gitlab-ci.yml
๋ค์๊ณผ ๊ฐ์ต๋๋ค :
image: traherom/kustomize-docker
before_script:
- printenv
- kubectl version
stages:
- deploy
deploy test:
stage: deploy
before_script:
- echo $KUBECONFIG
script:
- kubectl get all
- kubectl apply -f i/k8s
only:
- master
์ง์ ์คํํ๋ ค๋ฉด ํด๋ฌ์คํฐ๊ฐ ํ์ํ๋ฉฐ Gcloud๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b
gcloud compute firewall-rules create incoming-80 --allow tcp:80
ํฌํฌํด์ผ ํด KUBECONFIG
์ก์ธ์ค๋ฅผ ์ํ ๊ตฌ์ฑ์ด ํฌํจ๋ GitlabCI์์ kubectl
ํด๋ฌ์คํฐ์.
ํด๋ฌ์คํฐ(Gcloud)์ ๋ํ ์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด๋ฅผ ์ป๋ ๋ฐฉ๋ฒ์ ์ฝ์ด๋ณด์ธ์.
์ธํ๋ผ Yaml
์ธํ๋ผ ์ ์ฅ์์๋ ๋ค์๊ณผ ๊ฐ์ ์๋น์ค๊ฐ ์์ต๋๋ค.
apiVersion: v1
kind: Service
metadata:
labels:
id: app
name: app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
id: app
type: LoadBalancer
๊ทธ๋ฆฌ๊ณ ๋ฐฐํฌ deploy.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
selector:
matchLabels:
id: app
type: main
template:
metadata:
labels:
id: app
type: main
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
name: app
resources:
limits:
cpu: 100m
memory: 100Mi
๊ทธ๋ฆฌ๊ณ ๋ ๋ค๋ฅธ ๋ฐฐํฌ deploy-canary.yaml
:
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 0
selector:
matchLabels:
id: app
type: canary
template:
metadata:
labels:
id: app
type: canary
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
name: app
resources:
limits:
cpu: 100m
memory: 100Mi
app-deploy์๋ ์์ง ๋ณต์ ๋ณธ์ด ์ ์๋์ด ์์ง ์์ต๋๋ค.
์ด๊ธฐ ๋ฐฐํฌ ์ํ
์ด๊ธฐ ๋ฐฐํฌ๋ฅผ ์์ํ๋ ค๋ฉด ๋ง์คํฐ ๋ถ๊ธฐ์์ GitlabCI ํ์ดํ๋ผ์ธ์ ์๋์ผ๋ก ์์ํ ์ ์์ต๋๋ค. ์ดํ kubectl
๋ค์์ ์ถ๋ ฅํด์ผ ํฉ๋๋ค:
์ฐ๋ฆฌ๊ฐ ๋ณธ๋ค. app
10๊ฐ์ ๋ณต์ ๋ณธ์ผ๋ก ๋ฐฐํฌํ๊ณ 0์ผ๋ก app-canary๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋ค์์ ํตํด ์ก์ธ์คํ ์ ์๋ LoadBalancer๋ ์์ต๋๋ค. curl
์ธ๋ถ IP๋ฅผ ํตํด:
while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done
ํ ์คํธ ์ ํ๋ฆฌ์ผ์ด์ ์ด "v1"๋ง ๋ฐํํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
์นด๋๋ฆฌ์ ๋ฐฐํฌ ์คํ
1๋จ๊ณ: ์ผ๋ถ ์ฌ์ฉ์๋ฅผ ์ํ ์ ๋ฒ์ ์ถ์
๋ฐฐํฌ-canary.yaml ํ์ผ๊ณผ ์ ๋ฒ์ ์ด๋ฏธ์ง์์ ๋ณต์ ๋ณธ ์๋ฅผ 1๋ก ์ค์ ํ์ต๋๋ค.
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1
selector:
matchLabels:
id: app
type: canary
template:
metadata:
labels:
id: app
type: canary
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
name: app
resources:
limits:
cpu: 100m
memory: 100Mi
ํ์ผ์์ deploy.yaml
๋ณต์ ๋ณธ ์๋ฅผ 9๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
kind: Deployment
metadata:
name: app
spec:
replicas: 9
selector:
matchLabels:
id: app
...
GitlabCI๋ฅผ ํตํด ๋ฐฐํฌ๊ฐ ์์๋ ์ ์ฅ์์ ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ ํธ์ํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํฉ๋๋ค.
๋ ๋ฐฐํฌ ๋ชจ๋์ ์ฑ ์ ํ๊ธฐ๊ฐ ์์ผ๋ฏ๋ก ์ฐ๋ฆฌ ์๋น์ค๋ ๋ ๋ฐฐํฌ๋ฅผ ๋ชจ๋ ๊ฐ๋ฆฌํต๋๋ค. Kubernetes์ ๊ธฐ๋ณธ ๋ฌด์์ํ๋ก ์ธํด ์์ฒญ์ ~10%์ ๋ํด ์๋ก ๋ค๋ฅธ ์๋ต์ด ํ์๋ฉ๋๋ค.
์ฐ๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์ (Git์์ Single Source Of Truth๋ก ๊ฐ์ ธ์จ GitOps)์ ํ์ฌ ์ํ๋ ๊ฐ ๋ฒ์ ๋ง๋ค ํ๋์ฉ ํ์ฑ ๋ณต์ ๋ณธ์ด ์๋ ๋ ๊ฐ์ ๋ฐฐํฌ๊ฐ ์๋ค๋ ๊ฒ์ ๋๋ค.
์ฝ 10%์ ์ฌ์ฉ์๊ฐ ์ ๋ฒ์ ์ ์ต์ํด์ง๊ณ ์๋์น ์๊ฒ ํ ์คํธํฉ๋๋ค. ์ด์ ๋ฌธ์ ๋ฅผ ์ฐพ๊ธฐ ์ํด ๋ก๊ทธ์ ๋ชจ๋ํฐ๋ง ๋ฐ์ดํฐ์ ์ค๋ฅ๋ฅผ ํ์ธํด์ผ ํ ๋์ ๋๋ค.
2๋จ๊ณ: ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ์ ๋ฒ์ ์ถ์
์ฐ๋ฆฌ๋ ๋ชจ๋ ๊ฒ์ด ์ ์งํ๋์๋ค๊ณ ํ๋จํ์ผ๋ฉฐ ์ด์ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ์ ๋ฒ์ ์ ์ถ์ํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ์ํด ๊ฐ๋จํ ์
๋ฐ์ดํธํฉ๋๋ค. deploy.yaml
์ ๋ฒ์ ์ ์ด๋ฏธ์ง๋ฅผ ์ค์นํ๊ณ ๋ณต์ ๋ณธ ์๋ 10์
๋๋ค. deploy-canary.yaml
๋ณต์ ๋ณธ ์๋ฅผ ๋ค์ 0์ผ๋ก ์ค์ ํ์ต๋๋ค. ๋ฐฐํฌ ํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ต๋ ํฉ๊ณ
๋์๊ฒ๋ ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋ฐฐํฌ๋ฅผ ์๋์ผ๋ก ์คํํ๋ฉด k8s๋ฅผ ์ฌ์ฉํ์ฌ ์ผ๋ง๋ ์ฝ๊ฒ ๊ตฌ์ฑํ ์ ์๋์ง ์ดํดํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. Kubernetes๋ฅผ ์ฌ์ฉํ๋ฉด API๋ฅผ ํตํด ๋ชจ๋ ๊ฒ์ ์ ๋ฐ์ดํธํ ์ ์์ผ๋ฏ๋ก ์ด๋ฌํ ๋จ๊ณ๋ ์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์๋ํ๋ ์ ์์ต๋๋ค.
๊ตฌํํด์ผ ํ ๋ ๋ค๋ฅธ ์ฌํญ์ ์ ๋ฒ์ ์๋ง ์ก์ธ์คํ ์ ์๋ ํ ์คํฐ ์ง์ ์ (LoadBalancer ๋๋ Ingress๋ฅผ ํตํด)์ ๋๋ค. ์๋ ๊ฒ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํฅํ ๊ธฐ์ฌ์์๋ ์ฐ๋ฆฌ๊ฐ ์ํํ ๋๋ถ๋ถ์ ์์ ์ ๊ตฌํํ๋ ๋ค๋ฅธ ์๋ํ ์๋ฃจ์ ์ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค.
๋ธ๋ก๊ทธ์์ ๋ค๋ฅธ ๊ธฐ์ฌ๋ ์ฝ์ด๋ณด์ธ์.
์น์ธ์ด ์๋ ClickHouse์์ ์น์ธ์ด ์๋ ClickHouse๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ ๊ฒฐ๊ณผ๋ ๋ฌด์์ ๋๊น? Nginx์ฉ ๋์ ๋ชจ๋ ๋น๋ nxs-build-tools ์ ๋ฐ์ดํธ - deb ๋ฐ rpm ํจํค์ง ๊ตฌ์ถ ๋ณด์กฐ์ Hashicorp Consul์ Kubernetes ์ธ์ฆ ์๊ฐ Csync2 ์ ํธ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ ๋ ์ง๋ฉดํด์ผ ํ๋ ๋ฌธ์ Redmine์ฉ ํ ๋ ๊ทธ๋จ ๋ด. ์์ ๊ณผ ๋ค๋ฅธ ์ฌ๋์ ์ถ์ ๋จ์ํํ๋ ๋ฐฉ๋ฒ
์ถ์ฒ : habr.com