AWS์—์„œ Kubernetes ํด๋ผ์šฐ๋“œ ๋น„์šฉ ์ ˆ๊ฐ

๊ธฐ์‚ฌ์˜ ๋ฒˆ์—ญ์€ ๊ณผ์ • ์‹œ์ž‘ ์ „๋‚ ์— ์ค€๋น„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. "์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๊ธฐ๋ฐ˜ ์ธํ”„๋ผ ํ”Œ๋žซํผ".

AWS์—์„œ Kubernetes ํด๋ผ์šฐ๋“œ ๋น„์šฉ ์ ˆ๊ฐ

Kubernetes๋กœ ์ž‘์—…ํ•  ๋•Œ ํด๋ผ์šฐ๋“œ ๋น„์šฉ์„ ์ ˆ์•ฝํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‹จ ํ•˜๋‚˜์˜ ์˜ฌ๋ฐ”๋ฅธ ์†”๋ฃจ์…˜์€ ์—†์ง€๋งŒ ์ด ๋ฌธ์„œ์—์„œ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๋ณด๋‹ค ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ํด๋ผ์šฐ๋“œ ์ปดํ“จํŒ… ๋น„์šฉ์„ ์ค„์ด๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ์—ฌ๋Ÿฌ ๋„๊ตฌ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” AWS์šฉ Kubernetes๋ฅผ ์—ผ๋‘์— ๋‘๊ณ  ์ด ๊ธฐ์‚ฌ๋ฅผ ์ž‘์„ฑํ–ˆ์ง€๋งŒ ๋‹ค๋ฅธ ํด๋ผ์šฐ๋“œ ์ œ๊ณต์—…์ฒด์—๋„ ๊ฑฐ์˜ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ํด๋Ÿฌ์Šคํ„ฐ์— ์ด๋ฏธ ์ž๋™ ํ™•์žฅ์ด ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค(ํด๋Ÿฌ์Šคํ„ฐ ์ž๋™ ํฌ๊ธฐ ์กฐ์ •๊ธฐ). ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐฐํฌ๋ฅผ ์ถ•์†Œํ•˜๋ฉด ์ž‘์—…์ž ๋…ธ๋“œ(EC2 ์ธ์Šคํ„ด์Šค)๋„ ๊ฐ์†Œํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋น„์šฉ์ด ์ ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์„œ์—์„œ๋Š” ๋‹ค์Œ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ

๋น ๋ฅด๊ฒŒ ๋ณ€ํ™”ํ•˜๋Š” ํ™˜๊ฒฝ์—์„œ ์ผํ•˜๋Š” ๊ฒƒ์€ ์ข‹์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ธฐ์ˆ  ์กฐ์ง์„ ์›ํ•ฉ๋‹ˆ๋‹ค ๊ฐ€์†. ๋” ๋น ๋ฅธ ์†Œํ”„ํŠธ์›จ์–ด ์ œ๊ณต์€ ๋” ๋งŽ์€ PR ๋ฐฐํฌ, ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ํ™˜๊ฒฝ, ํ”„๋กœํ† ํƒ€์ž… ๋ฐ ๋ถ„์„ ์†”๋ฃจ์…˜์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด Kubernetes์— ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ๋ฐฐํฌ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ •๋ฆฌํ•  ์‹œ๊ฐ„์ด ์žˆ๋Š” ์‚ฌ๋žŒ์€ ๋ˆ„๊ตฌ์ž…๋‹ˆ๊นŒ? ์ผ์ฃผ์ผ์ด ์ง€๋‚œ ์‹คํ—˜์„ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์„ ์žŠ์–ด๋ฒ„๋ฆฌ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์žŠ์–ด๋ฒ„๋ฆฐ ์ผ๋กœ ์ธํ•ด ํด๋ผ์šฐ๋“œ ์š”๊ธˆ์ด ์ƒ์Šนํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AWS์—์„œ Kubernetes ํด๋ผ์šฐ๋“œ ๋น„์šฉ ์ ˆ๊ฐ

(ํ—ค๋‹ ์ œ์ด์ฝฅ์Šค:
์ง€์ž:
(์ธ์šฉ๋ฌธ) ์ฝ”๋ฆฌ ํ€ธ:
์˜คํ•ด: AWS ๊ณ„์ •์€ ๋ณด์œ ํ•œ ์‚ฌ์šฉ์ž ์ˆ˜์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.
์‚ฌ์‹ค: AWS ์ ์ˆ˜๋Š” ๋ณด์œ ํ•œ ์—”์ง€๋‹ˆ์–ด ์ˆ˜์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

Ivan Kurnosov (๋Œ€๋‹ต):
์‹ค์ œ ์‚ฌ์‹ค: AWS ์ ์ˆ˜๋Š” ๋น„ํ™œ์„ฑํ™”/์‚ญ์ œํ•˜๋Š” ๊ฒƒ์„ ์žŠ์–ด๋ฒ„๋ฆฐ ํ•ญ๋ชฉ ์ˆ˜์˜ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.)

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๊ด€๋ฆฌ์ธ (kube-janitor)๋Š” ํด๋Ÿฌ์Šคํ„ฐ ์ •๋ฆฌ์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ธ ๊ตฌ์„ฑ์€ ์ „์—ญ ๋ฐ ๋กœ์ปฌ ์‚ฌ์šฉ ๋ชจ๋‘์— ์œ ์—ฐํ•ฉ๋‹ˆ๋‹ค.

  • ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด ๊ทœ์น™์€ PR/ํ…Œ์ŠคํŠธ ๋ฐฐํฌ์— ๋Œ€ํ•œ ์ตœ๋Œ€ TTL(Time-to-Live)์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด 7์ผ ํ›„์— ์ŠคํŒŒ์ดํฌ/ํ”„๋กœํ† ํƒ€์ž…์„ ์ž๋™์œผ๋กœ ์ œ๊ฑฐํ•˜๋„๋ก ๊ฐœ๋ณ„ ๋ฆฌ์†Œ์Šค์— janitor/ttl๋กœ ์ฃผ์„์„ ๋‹ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜ ๊ทœ์น™์€ YAML ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๊ฒฝ๋กœ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. --rules-file kube-janitor์—์„œ. ๋‹ค์Œ์€ ๋ชจ๋“  ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ์˜ˆ์ œ ๊ทœ์น™์ž…๋‹ˆ๋‹ค. -pr- ์ดํ‹€ ํ›„ ์ด๋ฆ„์œผ๋กœ:

- id: cleanup-resources-from-pull-requests
  resources:
    - namespaces
  jmespath: "contains(metadata.name, '-pr-')"
  ttl: 2d

๋‹ค์Œ ์˜ˆ์—์„œ๋Š” 2020๋…„์˜ ๋ชจ๋“  ์ƒˆ๋กœ์šด ๋ฐฐํฌ/StatefulSet์— ๋Œ€ํ•œ ๋ฐฐํฌ ๋ฐ StatefulSet ํฌ๋“œ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ผ๋ฒจ ์‚ฌ์šฉ์„ ๊ทœ์ œํ•˜์ง€๋งŒ ๋™์‹œ์— ์ผ์ฃผ์ผ ๋™์•ˆ ์ด ๋ผ๋ฒจ ์—†์ด ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

- id: require-application-label
  # ัƒะดะฐะปะธั‚ัŒ deployments ะธ statefulsets ะฑะตะท ะผะตั‚ะบะธ "application"
  resources:
    - deployments
    - statefulsets
  # ัะผ. http://jmespath.org/specification.html
  jmespath: "!(spec.template.metadata.labels.application) && metadata.creationTimestamp > '2020-01-01'"
  ttl: 7d

kube-janitor๋ฅผ ์‹คํ–‰ํ•˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ์—์„œ 30๋ถ„ ๋™์•ˆ ์‹œ๊ฐ„ ์ œํ•œ์ด ์žˆ๋Š” ๋ฐ๋ชจ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

kubectl run nginx-demo --image=nginx
kubectl annotate deploy nginx-demo janitor/ttl=30m

๋น„์šฉ ์ฆ๊ฐ€์˜ ๋˜ ๋‹ค๋ฅธ ์›์ธ์€ ์˜๊ตฌ ๋ณผ๋ฅจ(AWS EBS)์ž…๋‹ˆ๋‹ค. Kubernetes StatefulSet๋ฅผ ์‚ญ์ œํ•ด๋„ ํ•ด๋‹น ์˜๊ตฌ ๋ณผ๋ฅจ(PVC - PertantVolumeClaim)์€ ์‚ญ์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋˜์ง€ ์•Š์€ EBS ๋ณผ๋ฅจ์œผ๋กœ ์ธํ•ด ๋งค์›” ์ˆ˜๋ฐฑ ๋‹ฌ๋Ÿฌ์˜ ๋น„์šฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Kubernetes Janitor์—๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” PVC๋ฅผ ์ •๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ๊ทœ์น™์€ ๋ชจ๋“ˆ์— ์˜ํ•ด ๋งˆ์šดํŠธ๋˜์ง€ ์•Š๊ณ  StatefulSet ๋˜๋Š” CronJob์— ์˜ํ•ด ์ฐธ์กฐ๋˜์ง€ ์•Š๋Š” ๋ชจ๋“  PVC๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

# ัƒะดะฐะปะธั‚ัŒ ะฒัะต PVC, ะบะพั‚ะพั€ั‹ะต ะฝะต ัะผะพะฝั‚ะธั€ะพะฒะฐะฝั‹ ะธ ะฝะฐ ะบะพั‚ะพั€ั‹ะต ะฝะต ััั‹ะปะฐัŽั‚ัั StatefulSets
- id: remove-unused-pvcs
  resources:
  - persistentvolumeclaims
  jmespath: "_context.pvc_is_not_mounted && _context.pvc_is_not_referenced"
  ttl: 24h

Kubernetes Janitor๋Š” ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ณ  ํด๋ผ์šฐ๋“œ ์ปดํ“จํŒ… ๋น„์šฉ์ด ์ฒœ์ฒœํžˆ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌ ๋ฐ ๊ตฌ์„ฑ ์ง€์นจ์€ ๋‹ค์Œ์„ ๋”ฐ๋ฅด์„ธ์š”. ์ฝ์–ด๋ณด๊ธฐ kube-janitor.

๊ทผ๋ฌด ์™ธ ์‹œ๊ฐ„์—๋Š” ์Šค์ผ€์ผ๋ง์„ ์ค„์ž…๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๋ฐ ์Šคํ…Œ์ด์ง• ์‹œ์Šคํ…œ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์—…๋ฌด ์‹œ๊ฐ„ ๋™์•ˆ์—๋งŒ ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฑ์˜คํ”ผ์Šค/๊ด€๋ฆฌ ๋„๊ตฌ์™€ ๊ฐ™์€ ์ผ๋ถ€ ํ”„๋กœ๋•์…˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ ์ œํ•œ๋œ ๊ฐ€์šฉ์„ฑ๋งŒ ํ•„์š”ํ•˜๋ฉฐ ํ•˜๋ฃป๋ฐค ์‚ฌ์ด์— ๋น„ํ™œ์„ฑํ™”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋‹ค์šด์Šค์ผ€์ผ๋Ÿฌ (kube-downscaler)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž์™€ ์šด์˜์ž๊ฐ€ ๊ทผ๋ฌด ์‹œ๊ฐ„ ์™ธ ์‹œ๊ฐ„์— ์‹œ์Šคํ…œ์„ ์ถ•์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌ ๋ฐ StatefulSet๋Š” ๋ณต์ œ๋ณธ์„ XNUMX๊ฐœ๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CronJob์ด ์ผ์‹œ ์ค‘์ง€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Kubernetes Downscaler๋Š” ์ „์ฒด ํด๋Ÿฌ์Šคํ„ฐ, ํ•˜๋‚˜ ์ด์ƒ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋˜๋Š” ๊ฐœ๋ณ„ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. "์œ ํœด ์‹œ๊ฐ„" ๋˜๋Š” ๋ฐ˜๋Œ€๋กœ "๊ทผ๋ฌด ์‹œ๊ฐ„"์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐค๊ณผ ์ฃผ๋ง ๋™์•ˆ ํ™•์žฅ์„ ์ตœ๋Œ€ํ•œ ์ค„์ด๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์„ธ์š”.

image: hjacobs/kube-downscaler:20.4.3
args:
  - --interval=30
  # ะฝะต ะพั‚ะบะปัŽั‡ะฐั‚ัŒ ะบะพะผะฟะพะฝะตะฝั‚ั‹ ะธะฝั„ั€ะฐัั‚ั€ัƒะบั‚ัƒั€ั‹
  - --exclude-namespaces=kube-system,infra
  # ะฝะต ะพั‚ะบะปัŽั‡ะฐั‚ัŒ kube-downscaler, ะฐ ั‚ะฐะบะถะต ะพัั‚ะฐะฒะธั‚ัŒ Postgres Operator, ั‡ั‚ะพะฑั‹ ะธัะบะปัŽั‡ะตะฝะฝั‹ะผะธ ะ‘ะ” ะผะพะถะฝะพ ะฑั‹ะปะพ ัƒะฟั€ะฐะฒะปัั‚ัŒ
  - --exclude-deployments=kube-downscaler,postgres-operator
  - --default-uptime=Mon-Fri 08:00-20:00 Europe/Berlin
  - --include-resources=deployments,statefulsets,stacks,cronjobs
  - --deployment-time-annotation=deployment-time

๋‹ค์Œ์€ ์ฃผ๋ง์— ํด๋Ÿฌ์Šคํ„ฐ ์ž‘์—…์ž ๋…ธ๋“œ๋ฅผ ํ™•์žฅํ•˜๋Š” ๊ทธ๋ž˜ํ”„์ž…๋‹ˆ๋‹ค.

AWS์—์„œ Kubernetes ํด๋ผ์šฐ๋“œ ๋น„์šฉ ์ ˆ๊ฐ

~13๊ฐœ์—์„œ 4๊ฐœ์˜ ์ž‘์—…์ž ๋…ธ๋“œ๋กœ ์ถ•์†Œํ•˜๋ฉด ํ™•์‹คํžˆ AWS ์ฒญ๊ตฌ์„œ์— ๋ˆˆ์— ๋„๋Š” ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ํด๋Ÿฌ์Šคํ„ฐ "๋‹ค์šดํƒ€์ž„" ๋™์•ˆ ์ž‘์—…ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? downscaler/exclude: true ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํŠน์ • ๋ฐฐํฌ๋ฅผ ํ™•์žฅ์—์„œ ์˜๊ตฌ์ ์œผ๋กœ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. YYYY-MM-DD HH:MM(UTC) ํ˜•์‹์˜ ์ ˆ๋Œ€ ํƒ€์ž„์Šคํƒฌํ”„๊ฐ€ ์žˆ๋Š” downscaler/exclude-until ์ฃผ์„์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐํฌ๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ฃผ์„์ด ํฌํ•จ๋œ ํฌ๋“œ๋ฅผ ๋ฐฐํฌํ•˜์—ฌ ์ „์ฒด ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ถ•์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. downscaler/force-uptime์˜ˆ๋ฅผ ๋“ค์–ด nginx ๊ณต๋ฐฑ์„ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

kubectl run scale-up --image=nginx
kubectl annotate deploy scale-up janitor/ttl=1h # ัƒะดะฐะปะธั‚ัŒ ั€ะฐะทะฒะตั€ั‚ั‹ะฒะฐะฝะธะต ั‡ะตั€ะตะท ั‡ะฐั
kubectl annotate pod $(kubectl get pod -l run=scale-up -o jsonpath="{.items[0].metadata.name}") downscaler/force-uptime=true

์ฐธ์กฐ ์ฝ์–ด๋ณด๊ธฐ kube-downscaler, ๋ฐฐํฌ ์ง€์นจ ๋ฐ ์ถ”๊ฐ€ ์˜ต์…˜์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ฒฝ์šฐ.

์ˆ˜ํ‰ ์ž๋™ ํ™•์žฅ ์‚ฌ์šฉ

๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜/์„œ๋น„์Šค๋Š” ๋™์  ๋กœ๋”ฉ ํŒจํ„ด์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” ๋ชจ๋“ˆ์ด ์œ ํœด ์ƒํƒœ์ด๊ณ  ๋•Œ๋กœ๋Š” ์ „์ฒด ์šฉ๋Ÿ‰์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ตœ๋Œ€ ํ”ผํฌ ๋ถ€ํ•˜์— ๋Œ€์ฒ˜ํ•˜๊ธฐ ์œ„ํ•ด ์˜๊ตฌ์ ์ธ ํฌ๋“œ ์ œํ’ˆ๊ตฐ์„ ์šด์˜ํ•˜๋Š” ๊ฒƒ์€ ๊ฒฝ์ œ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Kubernetes๋Š” ๋ฆฌ์†Œ์Šค ์ „๋ฐ˜์— ๊ฑธ์ณ ์ˆ˜ํ‰ ์ž๋™ ํฌ๊ธฐ ์กฐ์ •์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜ํ‰ํ˜•PodAutoscaler (HPA). CPU ์‚ฌ์šฉ๋Ÿ‰์€ ํ™•์žฅ์— ๋Œ€ํ•œ ์ข‹์€ ์ง€ํ‘œ๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        averageUtilization: 100
        type: Utilization

Zalando๋Š” ํ™•์žฅ์„ ์œ„ํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ์ง€ํ‘œ๋ฅผ ์‰ฝ๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. Kube ์ง€ํ‘œ ์–ด๋Œ‘ํ„ฐ (kube-metrics-adapter)๋Š” Pod์˜ ์ˆ˜ํ‰ ์ž๋™ ํ™•์žฅ์„ ์œ„ํ•œ ์‚ฌ์šฉ์ž ์ง€์ • ๋ฐ ์™ธ๋ถ€ ์ง€ํ‘œ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” Kubernetes์šฉ ์ผ๋ฐ˜ ์ง€ํ‘œ ์–ด๋Œ‘ํ„ฐ์ž…๋‹ˆ๋‹ค. Prometheus ์ง€ํ‘œ, SQS ๋Œ€๊ธฐ์—ด ๋ฐ ๊ธฐํƒ€ ์„ค์ •์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ํ™•์žฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด /metrics์—์„œ JSON์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž์ฒด๊ฐ€ ๋‚˜ํƒ€๋‚ด๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ธก์ •ํ•ญ๋ชฉ์œผ๋กœ ๋ฐฐํฌ๋ฅผ ํ™•์žฅํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
  annotations:
    # metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
    metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps"
    metric-config.pods.requests-per-second.json-path/path: /metrics
    metric-config.pods.requests-per-second.json-path/port: "9090"
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: requests-per-second
      target:
        averageValue: 1k
        type: AverageValue

HPA๋ฅผ ์‚ฌ์šฉํ•œ ์ˆ˜ํ‰ ์ž๋™ ํ™•์žฅ ๊ตฌ์„ฑ์€ ์ƒํƒœ ๋น„์ €์žฅ ์„œ๋น„์Šค์˜ ํšจ์œจ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•œ ๊ธฐ๋ณธ ์ž‘์—… ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. Spotify๋Š” HPA์— ๋Œ€ํ•œ ๊ฒฝํ—˜๊ณผ ๊ถŒ์žฅ ์‚ฌํ•ญ์„ ๋‹ด์€ ํ”„๋ ˆ์  ํ…Œ์ด์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ฐ‘์ด ์•„๋‹ˆ๋ผ ๋ฐฐํฌ๋ฅผ ํ™•์žฅํ•˜์„ธ์š”.

๋ฆฌ์†Œ์Šค ์ดˆ๊ณผ ์˜ˆ์•ฝ ๊ฐ์†Œ

Kubernetes ์›Œํฌ๋กœ๋“œ๋Š” "๋ฆฌ์†Œ์Šค ์š”์ฒญ"์„ ํ†ตํ•ด CPU/๋ฉ”๋ชจ๋ฆฌ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. CPU ๋ฆฌ์†Œ์Šค๋Š” ๊ฐ€์ƒ ์ฝ”์–ด ๋˜๋Š” ๋ณด๋‹ค ์ผ๋ฐ˜์ ์œผ๋กœ "๋ฐ€๋ฆฌ์ฝ”์–ด"๋กœ ์ธก์ •๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 500m๋Š” 50% vCPU๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๋ฆฌ์†Œ์Šค๋Š” ๋ฐ”์ดํŠธ ๋‹จ์œ„๋กœ ์ธก์ •๋˜๋ฉฐ 500MB๋ฅผ ์˜๋ฏธํ•˜๋Š” 500Mi์™€ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค๋Š” ์ž‘์—…์ž ๋…ธ๋“œ์—์„œ "์ž ๊ธˆ" ์šฉ๋Ÿ‰์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, vCPU๊ฐ€ 1000๊ฐœ์ธ ๋…ธ๋“œ์—์„œ 4m CPU ์š”์ฒญ์ด ์žˆ๋Š” ํฌ๋“œ๋Š” ๋‹ค๋ฅธ ํฌ๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” vCPU๋ฅผ 3๊ฐœ๋งŒ ๋‚จ๊ฒจ๋‘ก๋‹ˆ๋‹ค. [1]

Slack(์ดˆ๊ณผ ์˜ˆ์•ฝ) ์š”์ฒญ๋œ ๋ฆฌ์†Œ์Šค์™€ ์‹ค์ œ ์‚ฌ์šฉ๋Ÿ‰์˜ ์ฐจ์ด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 2GiB์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์š”์ฒญํ•˜์ง€๋งŒ 200MiB๋งŒ ์‚ฌ์šฉํ•˜๋Š” ํฌ๋“œ์—๋Š” ~1,8GiB์˜ "์ดˆ๊ณผ" ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ดˆ๊ณผ ๋น„์šฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. 1GiB์˜ ์ค‘๋ณต ๋ฉ”๋ชจ๋ฆฌ ๋น„์šฉ์€ ๋Œ€๋žต ์›” $10 ์ •๋„๋ผ๊ณ  ์ถ”์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [2]

Kubernetes ๋ฆฌ์†Œ์Šค ๋ณด๊ณ ์„œ (kube-resource-report)๋Š” ์ดˆ๊ณผ ์ค€๋น„๊ธˆ์„ ํ‘œ์‹œํ•˜๊ณ  ์ ˆ๊ฐ ๊ฐ€๋Šฅ์„ฑ์„ ํŒ๋‹จํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

AWS์—์„œ Kubernetes ํด๋ผ์šฐ๋“œ ๋น„์šฉ ์ ˆ๊ฐ

Kubernetes ๋ฆฌ์†Œ์Šค ๋ณด๊ณ ์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ ๋ช…๋ น๋ณ„๋กœ ์ง‘๊ณ„๋œ ์ดˆ๊ณผ๋ถ„์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ž์› ์ˆ˜์š”๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ์žฅ์†Œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ HTML ๋ณด๊ณ ์„œ๋Š” ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰์— ๋Œ€ํ•œ ์Šค๋ƒ…์ƒท๋งŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ ์ ˆํ•œ ๋ฆฌ์†Œ์Šค ์š”์ฒญ์„ ๊ฒฐ์ •ํ•˜๋ ค๋ฉด ์‹œ๊ฐ„ ๊ฒฝ๊ณผ์— ๋”ฐ๋ฅธ CPU/๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์‚ดํŽด๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ "์ผ๋ฐ˜์ ์ธ" CPU ์‚ฌ์šฉ๋Ÿ‰์ด ๋งŽ์€ ์„œ๋น„์Šค์— ๋Œ€ํ•œ Grafana ์ฐจํŠธ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ํฌ๋“œ๋Š” ์š”์ฒญ๋œ 3๊ฐœ์˜ CPU ์ฝ”์–ด๋ณด๋‹ค ํ›จ์”ฌ ์ ์€ ์–‘์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

AWS์—์„œ Kubernetes ํด๋ผ์šฐ๋“œ ๋น„์šฉ ์ ˆ๊ฐ

CPU ์š”์ฒญ์„ 3000m์—์„œ ~400m๋กœ ์ค„์ด๋ฉด ๋‹ค๋ฅธ ์›Œํฌ๋กœ๋“œ๋ฅผ ์œ„ํ•œ ๋ฆฌ์†Œ์Šค๊ฐ€ ํ™•๋ณด๋˜๊ณ  ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ๋” ์ž‘์•„์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

"EC2 ์ธ์Šคํ„ด์Šค์˜ ํ‰๊ท  CPU ์‚ฌ์šฉ๋Ÿ‰์€ ํ•œ ์ž๋ฆฟ์ˆ˜ ๋ฐฑ๋ถ„์œจ ๋ฒ”์œ„์— ๋จธ๋ฌด๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค." ์ฝ”๋ฆฌ ํ€ธ์ด ์“ด๋‹ค. EC2์˜ ๊ฒฝ์šฐ ์ ์ ˆํ•œ ํฌ๊ธฐ๋ฅผ ์ถ”์ •ํ•˜๋Š” ๊ฒƒ์€ ์ž˜๋ชป๋œ ๊ฒฐ์ •์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.YAML ํŒŒ์ผ์—์„œ ์ผ๋ถ€ Kubernetes ๋ฆฌ์†Œ์Šค ์ฟผ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ๊ณ  ๋ง‰๋Œ€ํ•œ ๋น„์šฉ ์ ˆ๊ฐ ํšจ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ •๋ง๋กœ ์‚ฌ๋žŒ๋“ค์ด YAML ํŒŒ์ผ์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ์š”, ๊ธฐ๊ณ„๊ฐ€ ํ›จ์”ฌ ๋” ์ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ˆ˜์งํ˜• ํฌ๋“œ ์ž๋™ ํ™•์žฅ ์ฒ˜๋ฆฌ (VPA)๊ฐ€ ๋ฐ”๋กœ ๊ทธ ์ผ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์›Œํฌ๋กœ๋“œ์— ๋”ฐ๋ผ ๋ฆฌ์†Œ์Šค ์š”์ฒญ๊ณผ ์ œ์•ฝ ์กฐ๊ฑด์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์‹œ๊ฐ„ ๊ฒฝ๊ณผ์— ๋”ฐ๋ผ VPA๊ฐ€ ์กฐ์ •ํ•œ Prometheus CPU ์š”์ฒญ(๊ฐ€๋Š” ํŒŒ๋ž€์ƒ‰ ์„ ) ๊ทธ๋ž˜ํ”„์˜ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

AWS์—์„œ Kubernetes ํด๋ผ์šฐ๋“œ ๋น„์šฉ ์ ˆ๊ฐ

Zalando๋Š” ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ์—์„œ VPA๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ธํ”„๋ผ ๊ตฌ์„ฑ์š”์†Œ์šฉ. ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ VPA๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฏธ์—ญ์ทจ ์†์˜ ์ผ์ข… Fairwind์˜๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๊ฐ ๋ฐฐํฌ์— ๋Œ€ํ•ด VPA๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ ๋Œ€์‹œ๋ณด๋“œ์— VPA ๊ถŒ์žฅ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ CPU/๋ฉ”๋ชจ๋ฆฌ ์š”์ฒญ์„ ์„ค์ •ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

AWS์—์„œ Kubernetes ํด๋ผ์šฐ๋“œ ๋น„์šฉ ์ ˆ๊ฐ

์ž‘๊ฒŒ ์ผ์–ด์š” VPA์— ๊ด€ํ•œ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ 2019๋…„์— ๊ทธ๋ฆฌ๊ณ  ์ตœ๊ทผ์—๋Š” CNCF ์ตœ์ข… ์‚ฌ์šฉ์ž ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ VPA ๋ฌธ์ œ๋ฅผ ๋…ผ์˜ํ–ˆ์Šต๋‹ˆ๋‹ค..

EC2 ์ŠคํŒŸ ์ธ์Šคํ„ด์Šค ์‚ฌ์šฉ

๋งˆ์ง€๋ง‰์œผ๋กœ ์ŠคํŒŸ ์ธ์Šคํ„ด์Šค๋ฅผ Kubernetes ์ž‘์—…์ž ๋…ธ๋“œ๋กœ ์‚ฌ์šฉํ•˜๋ฉด AWS EC2 ๋น„์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [3]. ์ŠคํŒŸ ์ธ์Šคํ„ด์Šค๋Š” ์˜จ๋””๋งจ๋“œ ๊ฐ€๊ฒฉ์— ๋น„ํ•ด ์ตœ๋Œ€ 90% ํ• ์ธ๋œ ๊ฐ€๊ฒฉ์œผ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. EC2 ์ŠคํŒŸ์—์„œ Kubernetes๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์ข‹์€ ์กฐํ•ฉ์ž…๋‹ˆ๋‹ค. ๋” ๋†’์€ ๊ฐ€์šฉ์„ฑ์„ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค ์œ ํ˜•์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋™์ผํ•˜๊ฑฐ๋‚˜ ๋” ๋‚ฎ์€ ๊ฐ€๊ฒฉ์œผ๋กœ ๋” ํฐ ๋…ธ๋“œ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ณ  ์ฆ๊ฐ€๋œ ์šฉ๋Ÿ‰์„ ์ปจํ…Œ์ด๋„ˆํ™”๋œ Kubernetes ์›Œํฌ๋กœ๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

EC2 Spot์—์„œ Kubernetes๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. SpotInst(ํ˜„์žฌ๋Š” "Spot"์ด๋ผ๊ณ  ํ•จ. ์ด์œ ๋Š” ๋ฌป์ง€ ๋งˆ์„ธ์š”)์™€ ๊ฐ™์€ ํƒ€์‚ฌ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ASG(Spot AutoScalingGroup)๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ์€ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค ์œ ํ˜•์ด ์žˆ๋Š” "์šฉ๋Ÿ‰ ์ตœ์ ํ™”" Spot ASG์— ๋Œ€ํ•œ CloudFormation ์ฝ”๋“œ ์กฐ๊ฐ์ž…๋‹ˆ๋‹ค.

MySpotAutoScalingGroup:
 Properties:
   HealthCheckGracePeriod: 300
   HealthCheckType: EC2
   MixedInstancesPolicy:
     InstancesDistribution:
       OnDemandPercentageAboveBaseCapacity: 0
       SpotAllocationStrategy: capacity-optimized
     LaunchTemplate:
       LaunchTemplateSpecification:
         LaunchTemplateId: !Ref LaunchTemplate
         Version: !GetAtt LaunchTemplate.LatestVersionNumber
       Overrides:
         - InstanceType: "m4.2xlarge"
         - InstanceType: "m4.4xlarge"
         - InstanceType: "m5.2xlarge"
         - InstanceType: "m5.4xlarge"
         - InstanceType: "r4.2xlarge"
         - InstanceType: "r4.4xlarge"
   LaunchTemplate:
     LaunchTemplateId: !Ref LaunchTemplate
     Version: !GetAtt LaunchTemplate.LatestVersionNumber
   MinSize: 0
   MaxSize: 100
   Tags:
   - Key: k8s.io/cluster-autoscaler/node-template/label/aws.amazon.com/spot
     PropagateAtLaunch: true
     Value: "true"

Kubernetes์—์„œ Spot ์‚ฌ์šฉ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ฐธ๊ณ  ์‚ฌํ•ญ:

  • ์˜ˆ๋ฅผ ๋“ค์–ด ์ธ์Šคํ„ด์Šค๊ฐ€ ์ค‘์ง€๋  ๋•Œ ๋…ธ๋“œ๋ฅผ ๋ณ‘ํ•ฉํ•˜์—ฌ ์ŠคํŒŸ ์ข…๋ฃŒ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Zalando๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํฌํฌ ๋…ธ๋“œ ํ’€ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ฅธ ๊ณต์‹ ํด๋Ÿฌ์Šคํ„ฐ ์ž๋™ ํ™•์žฅ
  • ์ŠคํŒŸ ๋…ธ๋“œ ๊ฐ•์ œ๋กœ ํ•  ์ˆ˜ ์žˆ๋‹ค Spot์—์„œ ์‹คํ–‰ํ•  ์›Œํฌ๋กœ๋“œ์˜ "๋“ฑ๋ก"์„ ์ˆ˜๋ฝํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ์š”

์ œ์‹œ๋œ ๋„๊ตฌ ์ค‘ ์ผ๋ถ€๊ฐ€ ํด๋ผ์šฐ๋“œ ๋น„์šฉ์„ ์ค„์ด๋Š” ๋ฐ ์œ ์šฉํ•˜๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ธฐ์‚ฌ ๋‚ด์šฉ์˜ ๋Œ€๋ถ€๋ถ„์€ ๋‹ค์Œ์—์„œ๋„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. YouTube์™€ ์Šฌ๋ผ์ด๋“œ์˜ DevOps Gathering 2019์—์„œ ์ œ๊ฐ€ ํ•œ ์ด์•ผ๊ธฐ.

Kubernetes์—์„œ ํด๋ผ์šฐ๋“œ ๋น„์šฉ์„ ์ ˆ์•ฝํ•˜๊ธฐ ์œ„ํ•œ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‹ค์Œ ์ฃผ์†Œ๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”. ํŠธ์œ„ํ„ฐ(@try_Exception_).

[1] ์‹ค์ œ๋กœ ์˜ˆ์•ฝ๋œ ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค๋กœ ์ธํ•ด ๋…ธ๋“œ์˜ ์ฒ˜๋ฆฌ๋Ÿ‰์ด ๊ฐ์†Œํ•˜๋ฏ€๋กœ 3๊ฐœ ๋ฏธ๋งŒ์˜ vCPU๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Kubernetes๋Š” ๋ฌผ๋ฆฌ์  ๋…ธ๋“œ ์šฉ๋Ÿ‰๊ณผ "ํ”„๋กœ๋น„์ €๋‹๋œ" ๋ฆฌ์†Œ์Šค๋ฅผ ๊ตฌ๋ณ„ํ•ฉ๋‹ˆ๋‹ค(๋…ธ๋“œ ํ• ๋‹น ๊ฐ€๋Šฅ).

[2] ๊ณ„์‚ฐ ์˜ˆ: 5GiB ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ–์ถ˜ m8.large ์ธ์Šคํ„ด์Šค 84๊ฐœ๋Š” ์›” ~$1 โ€‹โ€‹โ€‹โ€‹(eu-central-1, On-Demand)์ž…๋‹ˆ๋‹ค. ์ฆ‰, 8/10 ๋…ธ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜๋Š” ๋ฐ ๋“œ๋Š” ๋น„์šฉ์€ ๋Œ€๋žต ์›” $XNUMX์ž…๋‹ˆ๋‹ค.

[3] ์˜ˆ์•ฝ ์ธ์Šคํ„ด์Šค, Savings Plan ๋“ฑ EC2 ์ฒญ๊ตฌ์„œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ํ•ด๋‹น ์ฃผ์ œ๋ฅผ ๋‹ค๋ฃจ์ง€ ์•Š๊ฒ ์ง€๋งŒ ๊ผญ ์‚ดํŽด๋ณด์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค!

๊ณผ์ •์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€