
์ง๋ ๋ช ๊ฐ์๊ฐ Azure Kubernetes Service์ Amazon EKS ํ๊ฒฝ์ ์ฐจ๋ก๋ก ๊ตฌ์ถํ๋ฉฐ Kubernetes ์ ํ์ ๊ธฐ๋ฐ์ ๋ง๋ จํ๊ณ , ์ผ๋ถ ์๋น์ค๋ฅผ ์ค์ ๋ก ์ ํํ๊ธฐ๋ ํ์ต๋๋ค.
์ต๊ทผ์ ๋ณธ๊ฒฉ์ ์ผ๋ก ๊ธฐ์กด ์๋น์ค๋ค์ ์ฐจ๋ก์ฐจ๋ก Kubernetes ํ๊ฒฝ์ผ๋ก ์ด์ ํ๋๋ฐ, ๊ทธ ๊ณผ์ ์์ ๊ณ ๋ฏผํ ๊ด๋ฆฌ ๋ฐฉ์๊ณผ ๊ณผ์ ์ ์ ๋ฆฌํด ๋ณด์์ต๋๋ค.
Repository ๊ตฌ์กฐ ์ค๊ณ
Kubernetes ํ๊ฒฝ์ผ๋ก ์ ํํ๋ฉด์ ๊ฐ์ฅ ๋ง์ด ํ๋ ๊ณ ๋ฏผ์ ๋ฐฐํฌ ๊ด๋ จ ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ๊ด๋ฆฌํ ๊ฒ์ธ๊ฐ์์ต๋๋ค. ์ด์ ๋จ๊ณ์์ ํ๊ฒฝ์ ๊ตฌ์ฑํ๊ณ ์ผ๋ถ ์๋น์ค๋ฅผ ์ด์ ํ๋ฉด์๋ ๊ณ์ ๊ณ ๋ฏผํ๋ ์ฃผ์ ์์ต๋๋ค.
๊ธฐ์กด์๋ ๊ฐ ์๋น์ค Repository์ ๋ฐฐํฌ ๊ด๋ จ ํ์ผ๋ค์ด ๋ถ์ฐ๋์ด ์์๋๋ฐ, ์๋น์ค ์๊ฐ ๋ง์ง ์์๊ธฐ ๋๋ฌธ์ ํฐ ๋ฌธ์ ๋ ์์์ต๋๋ค. ํ์ง๋ง ์์ผ๋ก ์๋น์ค๋ ๊ณ์ ๋์ด๋ ๊ฑฐ๊ณ , ํ์ฌ ์ฌ์ฉํ๋ Helm Chart ๋ฑ์ ํํ๋ ๋ชจ๋ ์ ๊ฐ๊ฐ์ด๋ผ ์ผ๊ด์ฑ์ด ์์์ต๋๋ค.
์ด๋ฌํ ์ํ๋ฅผ ์ ์งํ๋ฉด ํ ๋ด์์ ์ ์ง๋ณด์๊ฐ ํ๋ค์ด์ง๊ณ , ํน์ ์๋น์ค์ ๋ฐฐํฌ ์ค์ ์ ๋ณ๊ฒฝํ๊ธฐ ์ํด ๋งค๋ฒ ๋ค๋ฅธ ๊ณณ์ ์ฐพ์๊ฐ์ผ ํ๋ ๋ถํธํจ์ด ์์์ต๋๋ค.
๋ํ, ๋ค๋ฅธ ํ์์ ๋ฐฐํฌ ๊ด๋ จ Commit์ด ๊ฐ๋ฐ ๊ด๋ จ Commit๊ณผ ์์ด๊ธฐ๋ฅผ ์ํ์ง๋ ์๋๋ค๋ ์๊ฒฌ๋ ์์์ต๋๋ค.
์ด๋ฅผ ํฌํจํ ์ฌ๋ฌ ๊ณ ๋ฏผ ๋์ ๋ถ๋ฆฌ๋๊ณ ์ค์ํ๋ Helm Chart + Argo CD ์ค์ Repository๋ฅผ ๊ตฌ์ฑํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ์ฒ์๋ถํฐ ๊ฐ๋ฅํ๋ฉด ๊ฒฌ๊ณ ํ ๊ตฌ์กฐ๋ฅผ ์ก๊ณ ์ถ์๊ณ , ๊ณ ๋ฏผ ๋์ ๋ค์๊ณผ ๊ฐ์ ํํ๋ก ์ค๊ณํ์ต๋๋ค.
saas-helm-charts/
โโโ .github/workflows/
โ โโโ update-tag.yaml
โโโ argocd/
โ โโโ applications/
โ โ โโโ myorg-single-service.yaml
โ โ โโโ oss-mlflow.yaml
โ โโโ applicationsets/
โ โโโ myorg-multi-service.yaml
โ โโโ oss-prometheus.yaml
โโโ charts/
โ โโโ myorg-single-service/
โ โโโ myorg-multi-service/
โ โ โโโ charts/
โ โ โโโ templates/
โ โ โโโ values/
โ โ โ โโโ prod-us.yaml
โ โ โ โโโ prod-ja.yaml
โ โ โ โโโ staging.yaml
โ โ โ โโโ nginx.yaml
โ โ โ โโโ azure-application-gateway.yaml
โ โ โโโ Chart.yaml
โ โโโ oss-prometheus/
โ โโโ README.md
โ โโโ values/
โ โโโ prod-us.yaml
โ โโโ prod-ja.yaml
โ โโโ ...
โโโ scripts/
โโโ update-tag.sh
โโโ ...
์ฐ์ argocd ํด๋๋ฅผ ๋๊ณ Application๊ณผ ApplicationSet์ ๊ด๋ฆฌํ๋๋ก ํ์ต๋๋ค.
์ด ๋ถ๋ถ๊น์ง ๋ณ๋์ Repository๋ก ๋ถ๋ฆฌํ๋ ๊ฒ๋ ๊ณ ๋ฏผํ์ง๋ง, ๊ท๋ชจ๊ฐ ์ปค์ก์ ๋ ๊ณ ๋ คํด๋ ๋๋ค๊ณ ์๊ฐํ์ต๋๋ค.
์ด๋ ๊ฒ ํ์ฌ ์ต์ด 2๊ฐ์ ํด๋๋ฅผ ๋ฑ๋กํ๋ฉด, ๊ทธ ๋ค๋ก๋ ์์์ Git๊ณผ ๋๊ธฐํ๋์ด ๋ฐฐํฌ๊ฐ ์ด๋ฃจ์ด์ง๊ฒ ๋ฉ๋๋ค.
Helm chart ํด๋์ ๊ฒฝ์ฐ, ํ์ฌ ์์ฒด ์๋น์ค๋ ํ์ฌ ์ด๋ฆ์ Prefix๋ก ๋ถ์ด๊ณ , ์คํ์์ค์ ๊ฒฝ์ฐ oss- Prefix๋ฅผ ๋ถ์์ต๋๋ค.
์ด๋ ๊ฒ ํ์ฌ ํด๋ ๊ตฌ์กฐ๊ฐ ๊ณผ๋ํ๊ฒ ๊น์ด์ง๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ , ํ์ฌ ์์ฒด ์๋น์ค์ ์คํ์์ค ์๋น์ค๋ฅผ ๋ช
ํํ๊ฒ ๊ตฌ๋ถํ ์ ์๋๋ก ํ์ต๋๋ค.
์คํ์์ค Helm chart์ ๊ฒฝ์ฐ ์ปค๋ฎค๋ํฐ์์ ์ง์ ๊ด๋ฆฌํ๋๋ก ํ๊ณ , ํ์ํ values ํ์ผ๊ณผ ๋ถ๊ฐํผํ๊ฒ ์ถ๊ฐํ ๋งํ ๋ฆฌ์์ค๋ง ๊ด๋ฆฌํ๋๋ก ํ์ต๋๋ค. ๋์ README๋ฅผ ๋์ด ์ด๋ค ์์ค ์ฝ๋๋ฅผ ์ฌ์ฉํ๋์ง, ์ด๋ค ์ค์ ์ ํ๋์ง ๋ฑ์ ํ์ ํ ์ ์๋๋ก ์ ๋ฆฌํด ๋์์ต๋๋ค.
Helm Chart ํ์คํ
๊ธฐ์กด์ ์์๋ก ์ฌ์ฉํ๋ Helm chart๋ค์ ๊ด๋ฆฌ๊ฐ ์ ๋์ง ์๊ณ ์์๊ณ , ๊ฐ ์๋น์ค๋ง๋ค ์๋ก ๋ค๋ฅธ ํฌ๋งท์ ์ฌ์ฉํ๊ณ ์์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ํฌ๋งท๋ ๋น์ ์ ์์๊ฐ ์์๋ก ์ ์ํ ๋ถ๋ถ์ด ๋ง์ ์ด ๊ฐ์ด ์ด๋์ ์ํฅ์ ๋ฏธ์น๋์ง๋ ํ
ํ๋ฆฟ์ ๋ฏ์ด๋ณด์ง ์์ผ๋ฉด ์ ์ ์์์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด helm create ๋ช
๋ น์ด๋ก ์์ฑ๋๋ ๊ธฐ๋ณธ ํ
ํ๋ฆฟ์ ๊ธฐ๋ฐ์ผ๋ก ํ์คํ ์์
์ ์งํํ์ต๋๋ค.
helm create myorg-service-template
์ด๋ ๊ฒ ๋ง๋ค์ด์ง ๊ธฐ๋ณธ ํ
ํ๋ฆฟ์ ๋ฐํ์ผ๋ก ์ต์ํ์ ์์ ๋ง ๊ฐํ์ฌ ์ ์ง๋ณด์์ฑ์ ํ๋ณดํ์ต๋๋ค.
์ฃผ๋ก ์ถ๊ฐํ ์์๋ deployment ๋ธ๋ก๊ณผ Azure Application Gateway ์ฐ๋์ ์ํ AzureApplicationGatewayRewrite ๋ฆฌ์์ค ๊ด๋ จ ์ค์ ์ ๋์๊ณ ,
๊ทธ ์ธ์๋ ์ถ๊ฐ์ ์ธ ํ
ํ๋ฆฟ ํ์ผ์ด ํ์ํ๋ฉด ๊ทธ์ ๋ํ ๋ธ๋ก์ ์ ์ํ๋ ์์ผ๋ก ํ์ฅํด ํ ๋ด์์ ๋ฌด๋ฆฌ ์์ด ์ด์ฉํ ์ ์๋๋ก ํ์ต๋๋ค.
์ด ์ธ์ ์ค์ , ํนํ ์ค๋ช
์์ด๋ ์์๋ณผ ์ ์๋ ์ค์ ์ ์ต๋ํ ํผํ๋ ค ๋
ธ๋ ฅํ๊ณ , ๋น์ฅ ์ฌ์ฉํ์ง ์๋ ํ
ํ๋ฆฟ๋ ์ถํ ์ฌ์ฉ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด ์ญ์ ๋ฅผ ์ง์ํ์์ต๋๋ค.
์ด๋ ๊ฒ ํ ํ๋ฆฟ์ ๋ง๋ ๋ค์๋ ์๋ก์ด ์๋น์ค๋ฅผ ์ถ๊ฐํ ๋์๋ ๊ธฐ์กด ํ ํ๋ฆฟ์ ๋ณต์ฌํ๊ณ ์ฝ๊ฐ ์์ ํ๋ ์ ๋๋ก ์ถฉ๋ถํ์ต๋๋ค. ๋ํ, SaaS ํ๊ฒฝ์ด ์๋ ๊ณณ์์ Helm chart๊ฐ ํ์ํ ๊ฒฝ์ฐ์๋ ์ฐธ๊ณ ํ ์ ์๋ ์๋ฃ๊ฐ ๋์์ต๋๋ค.
ApplicationSet ํ์ฉํ๊ธฐ
์ฌ๋ฌ ํ๊ฒฝ์ ๋ฐฐํฌ, ๋๋ ์ฌ๋ฌ ํด๋ฌ์คํฐ์ ๋ฐฐํฌํ๋ ๊ฒฝ์ฐ Argo CD์ ApplicationSet์ ์ฌ์ฉํ์์ต๋๋ค.
ํนํ ํ์ํ ๊ฒฝ์ฐ 2๊ฐ ์ด์์ values ํ์ผ์ ์กฐํฉํ๊ณ , Multi-source ๋ฐฉ์์ ์ ๊ทน ํ์ฉํ์ฌ ์ ์ฐํ ๋ฐฐํฌ๊ฐ ๊ฐ๋ฅํ๋๋ก ์ค๊ณํ์ต๋๋ค.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myorg-service-applicationset
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
# ...
generators:
- list:
elements:
- name: prod-us
project: prod-us
cluster: myorg-prd-eks
namespace: myorg-prod-us
valuesFile: prod-us.yaml
ingressClass: nginx
branch: main
envFile: path/to/env/file
template:
metadata:
name: "myorg-{{ .name }}"
spec:
project: "{{ .project }}"
destination:
name: "{{ .cluster }}"
namespace: "{{ .namespace }}"
sources:
- repoURL: https://github.com/myorg/helm-charts
targetRevision: "{{ .branch }}"
path: charts/myorg-service
helm:
releaseName: "{{ .name }}"
valueFiles:
- "values/{{ .valuesFile }}"
- "values/{{ .ingressClass }}.yaml"
fileParameters:
- name: envFile
path: "$env/{{ .envFile }}"
- repoURL: https://github.com/myorg/other-repo
targetRevision: master
ref: env
syncPolicy:
# ...
์๋ ์์ ApplicationSet ์ค์ ์ ๋๋ค.
valueFiles์ ๊ฒฝ์ฐ ์๋น์ค ๋ฐฐํฌ ํํ๋ฅผ ์๊ฐํ์ ๋ ๋ค์ 2๊ฐ์ง ์์๊ฐ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค.
- ํ๊ฒฝ ํนํ ์ค์ (
prod-us.yaml,prod-ja.yaml,staging.yaml๋ฑ) - ๋คํธ์ํฌ ํนํ ์ค์ (
nginx.yaml,azure-application-gateway.yaml๋ฑ)
๊ทธ๋ ๋ค๋ฉด ์ด ๊ฐ๊ฐ์ ์ค์ ์ ๋ฐ๋ก ์ ์ํ๊ณ , ์กฐํฉํ์ฌ ๋ฐฐํฌํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ๊ฒ ๊ฐ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
fileParameters์ ๊ฒฝ์ฐ1, ์ธ๋ถ Repository์ ํ์ผ์ ์ฐธ์กฐํ์ฌ ConfigMap์ด๋ ๋ค๋ฅธ ๋ฆฌ์์ค๋ฅผ ์์ฑํด์ผ ํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ์ต๋๋ค.
์๋น์ค ์ ํํ๊ธฐ
๋ชจ๋ ์๋น์ค๋ฅผ ํ ๋ฒ์ ์ ํํ๋ ๊ฒ์ ์ํ์ฑ์ด ๋๊ธฐ ๋๋ฌธ์, ์ ์ง์ ์ ํ์ ํตํด ํธ๋ํฝ์ ์ ํํ์ต๋๋ค.
์ด ๊ณผ์ ์์ Route 53์ ๊ฐ์ค์น ๊ธฐ๋ฐ ๋ผ์ฐํ
2์ ํตํด ํธ๋ํฝ์ ๋ถ์ฐํ๋ ๋ฐฉ์์ ์ฑํํ๊ฑฐ๋, nginx.conf ํ์ผ ๋ฑ ๋คํธ์ํฌ ์ค์ ์ด ๋ฐ๋ก ์๋ค๋ฉด ํด๋น ํ์ผ์์ ์ง์ ๋น์จ์ ์กฐ์ ํ์์ต๋๋ค.
๋คํธ์ํฌ์ ๊ด๋ จ์ด ์๋ Worker ์ข ๋ฅ์ ์๋น์ค๋ K8s ํ๊ฒฝ์ ๋ฐฐํฌํ ๋ค, ์ ์ ๋์์ด ํ์ธ๋๋ฉด Docker Compose ์์์ ์ญ์ ํ๋ ๋ฐฉ์์ผ๋ก ์ ํํ์ต๋๋ค.
๋ง์น๋ฉฐ
์ด๋ฌํ ๊ณผ์ ์ ๊ฑฐ์ณ, ์ด๋ฒ ๋ฌ ์ฃผ์ ์๋น์ค์ ํธ๋ํฝ์ด Kubernetes ํ๊ฒฝ์ผ๋ก ์ ํ๋์์ต๋๋ค ๐๐๐
์ฌํด ํ ๋ด ํฐ ๋ชฉํ์ด๊ธฐ๋ ํ๊ณ , ํนํ ๊ธฐ์กด Docker Compose ํ๊ฒฝ์ด ๋ง์ด ๋ ธํํ๋์ด ๋ฌธ์ ๋ฅผ ์ผ์ผํค๋ ๊ฒฝ์ฐ๋ ๋ง์๋๋ฐ ์ด์ ์ด๋ ์ ๋ ์ ์ฐ์ฑ๊ณผ ์์ ์ฑ์ด ์๊ธฐ์ง ์์๊น ์ถ์ต๋๋ค.
1์ฐจ ๋ชฉํ๋ ๋ฌ์ฑํ์ง๋ง, ์์ง ํด์ผ ํ ์ผ๋ค์ด ๋ง์ด ๋จ์ ์์ต๋๋ค.
- ๋ชจ๋ ๋ฆฌ์์ค๊ฐ ์ ํ๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์, ๋จ์ ๊ฒ๋ค์ ์ ๋ฆฌํด ๋๊ฐ์ผ ํฉ๋๋ค.
- Blue/Green ๋ฐฐํฌ, ์ด๋ฒคํธ ๊ธฐ๋ฐ Auto-scaling ๋ฑ ๋ ๋์ ๋ฐฐํฌ ๋ฐฉ์์ ์ ์ฉํด ๋๊ฐ์ผ ํฉ๋๋ค.
- ๋ชจ๋ํฐ๋ง ์์คํ ๋ ๊ตฌ์ถํด ๋๊ฐ๋ ค๊ณ ํฉ๋๋ค. ํ์ฌ๋ Datadog๋ฅผ ์ฌ์ฉํ๊ณ ์๋๋ฐ, ํ์ฌ ์ฐจ์์์ ์ด๋ฅผ Grafana์ ๊ฐ์ ๋ค๋ฅธ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๋ก ๋์ฒดํด ๋๊ฐ๋ ค๊ณ ํฉ๋๋ค.
๊ทธ๋๋ ์ ๊ฐ ์ฒ์ ๋ค์ด์์ ๋ ๋ชฉํ๋ก ํ๋ ์ผ์ ํ ๋จ๋ฝ์ด ๋ง๋ฌด๋ฆฌ๋ ๊ฒ ๊ฐ์ ๋ฟ๋ฏํ๋ค์.
์ด์ ๋ค์ ๋จ๊ณ๋ฅผ ์ํด ๋ ์ด์ฌํ ํด ๋๊ฐ๋ ค๊ณ ํฉ๋๋ค.