์ค๋ ๊ธฐ๊ฐ ๋์ ์งํํ Kubernetes ์ ํ ๊ณผ์ ์ดํ์๋, ํ ๋ด์์ ๋ ๋์ ํ๊ฒฝ์ ์ ๊ณตํ๊ธฐ ์ํด ์ฌ๋ฌ ๊ณํ์ ์งํํ๊ณ ์์ต๋๋ค.
์ต๊ทผ์๋ ์ด๋ฒคํธ์ ํธ๋ํฝ์ ๋ฐ๋ฅธ ์์ ๊ด๋ฆฌ๋ฅผ ๋ณธ๊ฒฉ์ ์ผ๋ก ์์ํ ํ์์ฑ์ด ์๊ฒผ๊ณ , ์ด๋ฅผ ์ํด KEDA๋ฅผ ๋์
ํ๊ฒ ๋์์ต๋๋ค.
์ด๋ฅผ ๊ตฌ์ฑํ ๊ณผ์ ๊ณผ ๋๋ ์ ์ ๊ฐ๋จํ ์ ๋ฆฌํด ๋ณด์์ต๋๋ค.
KEDA
KEDA๋ ๋ค์ํ ์ด๋ฒคํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ปจํ
์ด๋๋ฅผ ๋์ ์ผ๋ก ํ์ฅํ๊ฑฐ๋ ์ถ์ํ ์ ์๋๋ก ์ง์ํ๋ Kubernetes ์ปดํฌ๋ํธ๋ก, CNCF Graduated Project์ด๊ธฐ๋ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ฉ์์ง ํ๋ DB์ ์์ธ ๋ฐ์ดํฐ์ ์์ ๋ณด๊ณ ํธ๋ํฝ์ ์กฐ์ ํ๊ฑฐ๋, CronJob์ฒ๋ผ ํน์ ์๊ฐ๋๋ฅผ ๊ธฐ์ค์ผ๋ก Pod ์๋ฅผ ์กฐ์ ํ ์ ์์ต๋๋ค.

Image: KEDA Architecture from KEDA - Docs, Apache 2.0
KEDA์ ์๋ฆฌ๋ฅผ ๊ฐ๋จํ ์ค๋ช
ํ๋ฉด, ScaledObject๋ผ๋ ๋ฆฌ์์ค๋ฅผ ์ ์ํ์ฌ HPA(Horizontal Pod Autoscaler)์ ์ํ๋ฅผ ์ง์์ ์ผ๋ก ์
๋ฐ์ดํธํ๋ ๊ฒ์
๋๋ค.
์ธ๋ถ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ScaledObject๊ฐ Scaling ๊ท์น์ ๋ณ๊ฒฝํ๊ณ , ์ด๋ฅผ HPA์ ์ ๋ฌํ์ฌ Pod ์๋ฅผ ์กฐ์ ํ๋๋ก ํฉ๋๋ค.
์ค์ ๋ก ScaledObject๋ฅผ ์์ฑํด ๋ณด๋ฉด ์๋์ผ๋ก HPA๊ฐ ์์ฑ๋๋ ๊ฒ์ ํ์ธํ ์ ์๊ณ , Pod scaling ์ด๋ฒคํธ ์์ฒด๋ HPA์ ์์๋ฉ๋๋ค.
๊ธฐ์กด์ HPA๋ ๋ณดํต CPU ๋๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ์ ๋ฐ๋ผ Pod์ ์๋ฅผ ์กฐ์ ํ๋ ๋ฐฉ์์ด์์ต๋๋ค. KEDA๋ ์ด๋ฅผ ํ์ฅํ์ฌ ์ด๋ฒคํธ ์์ค๋ฅผ ์ค์ฌ์ผ๋ก ๋ ์ ์ฐํ๊ณ ํ์ฅ๋ ์กฐ๊ฑด์์์ ๋ฆฌ์์ค ์กฐ์ ์ ๊ฐ๋ฅํ๋๋ก ํด ์ค๋๋ค.
์ ํฌ ํ์ฌ์ ๊ฒฝ์ฐ์๋ ๋ฌธ์ ์ฒ๋ฆฌ๋ ๊ฐ์ข
๋ฐฐ์น ์ฒ๋ฆฌ๋ฅผ RabbitMQ ์ด๋ฒคํธ๋ฅผ ๋ณด๊ณ ๋์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์ ํ๋ ์๊ตฌ๊ฐ ์์์ต๋๋ค.
๊ธฐ์กด์๋ ์ฝ๋๋ก ์ด ๋ก์ง์ ์ง์ ๊ตฌํํ์๋๋ฐ, Kubernetes ํ๊ฒฝ์ผ๋ก ์ ํํ๋ฉด์ ์ค์ KEDA๋ฅผ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝ์ด ํ์ํ์ต๋๋ค.
๋ํ B2B ์๋น์ค๊ฐ ๋ฉ์ธ์ด๊ธฐ ๋๋ฌธ์ ํ์ฌ ์๋น์ค์ ํธ๋ํฝ์ ํน์ ์๊ฐ๋์ ๋ชฐ๋ฆฌ๋ ๊ฒฝํฅ์ด ์์๊ณ , ์ด์ ๋ฐ๋ฅธ ํธ๋ํฝ ๋์๊ณผ ๋ฆฌ์์ค ํจ์จํ์๋ KEDA๊ฐ ์ข์ ํด๊ฒฐ์ฑ
์ด ๋ ์ ์์์ต๋๋ค.
RabbitMQ ์ฐ๋ํ๊ธฐ
์ ํฌ๊ฐ KEDA๋ฅผ ์ ์ฉํ๊ณ ์ ํ ์ฑ๋ค์ ์ด๋ฒคํธ ์์ค๋ RabbitMQ์๊ณ , ๋ฐ๋ผ์ ์ด๋ฅผ ์ง์ค์ ์ผ๋ก ๊ตฌํํ์ต๋๋ค. RabbitMQ ์ด๋ฒคํธ ์์ค๋ฅผ ์ด๋ป๊ฒ ์ฐ๋ํ๋์ง๋ ์ด ๋ฌธ์์ ์ฌ๋ก๋ณ๋ก ์์ธํ ๋์ ์์ต๋๋ค.
๊ธฐ๋ณธ ๊ตฌํ
KEDA ์ค์น๋ Helm chart๋ฅผ ํตํด ์ฝ๊ฒ ์ค์นํ ์ ์์ต๋๋ค.
KEDA๋ฅผ ์ฌ์ฉํ ๋ชจ๋ ํด๋ฌ์คํฐ์ ์ค์นํด์ผ ํฉ๋๋ค.
KEDA๋ฅผ ๊ตฌํํ ๋๋ ๋ค์ ๋ฆฌ์์ค๋ค์ ๊ตฌํํด์ผ ํฉ๋๋ค.
- ScaledObject: ์ด๋ฒคํธ ์์ค๋ฅผ ๋ชจ๋ํฐ๋งํ๊ณ , HPA๊ฐ ์๋ํ๊ธฐ ์ํ Scaling ๊ท์น์ ์ ์ํฉ๋๋ค. ScaledObject๊ฐ ์ ์๋๋ฉด ์๋์ผ๋ก HPA๊ฐ ์์ฑ๋ฉ๋๋ค.
- TriggerAuthentication: ์ด๋ฒคํธ ์์ค์ ๋ํ ์ธ์ฆ ์ ๋ณด๋ฅผ ์ ์ฅํฉ๋๋ค. ์ฌ๊ธฐ์๋ RabbitMQ์ URL์ด๋ ์ธ์ฆ ์ ๋ณด๊ฐ ํด๋น๋ฉ๋๋ค.
- Secret: ๋น์ฐํ ๋ฆฌ์์ค์ ์ง์ ๋น๋ฐ ์ ๋ณด๋ฅผ ์
๋ ฅํ๋ ๊ฒ์ ์ข์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์ด๋ฅผ Secret์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
- ์ ํฌ๋ External Secret Operator๋ฅผ ์ฌ์ฉํ์ฌ ์ธ๋ถ Secret Manager์์ ๋น๋ฐ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋๋ก ์ค์ ํ์ต๋๋ค.
๊ด๋ จ๋ ๊ตฌํ์ฒด๋ ๊ณต์ ๋ฌธ์์ ๋งค์ฐ ์ ์ค๋ช
๋์ด ์์ต๋๋ค.
์ ๋ ์ด ๋ฆฌ์์ค๋ค์ ๊ธฐ์กด ์๋น์ค Helm chart ํ
ํ๋ฆฟ์ ํตํฉํ์ฌ values.yaml์์ ์ฝ๊ฒ ์ ์ฉํ ์ ์๋๋ก ํ์ต๋๋ค.
ํน์ ํ ์ง์ ํ๊ธฐ
๊ฐ์ RabbitMQ๋ฅผ ์ฌ์ฉํ๋๋ผ๋ ์ฑ๋ง๋ค ์กฐ๊ธ์ฉ ์๊ตฌ์ฌํญ์ด ๋ฌ๋์ต๋๋ค.
์ฐ์ ํน์ ์ค์ผ์ค๋ง ์์
์ ์ฒ๋ฆฌํ๋ Batch ์ฑ์ ๊ฒฝ์ฐ ์ ํด์ง ํ 2~3๊ฐ๋ง ๋ฐ๋ผ๋ณด๋ฉด ๋์์ต๋๋ค.
์ด ๊ฒฝ์ฐ์๋ triggers ํญ๋ชฉ์ ๋ชจ๋ํฐ๋งํ ํ ์ด๋ฆ์ ์ง์ ๋ช
์ํ๋ฉด ๋ฉ๋๋ค.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: batch-worker-scaledobject
namespace: default
spec:
scaleTargetRef:
name: batch-worker-deployment
triggers:
- type: rabbitmq
metadata:
protocol: auto
queueName: foo
mode: QueueLength
value: "50"
activationValue: "1"
- type: rabbitmq
metadata:
protocol: auto
queueName: bar
mode: QueueLength
value: "50"
activationValue: "1"
์ ๊ท์ ํํฐ ์ฌ์ฉํ๊ธฐ
๋ฌธ์ ํ์ฑ์ ๋ด๋นํ๋ ์ฑ๋ค์ ์๋ฅผ ๋ค๋ฉด document- ๋ผ๋ Prefix๋ก ์์ํ๋ ๋ชจ๋ ํ๋ฅผ ์ฌ์ฉํ๊ณ ์์์ต๋๋ค.
KEDA์์๋ ์ ๊ท์์ ์ด์ฉํ ํ ํํฐ๋ง ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์, ์๊ตฌ์ฌํญ์ ๋ง์กฑ์ํฌ ์ ์์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ๋ฉด ๋ฉ๋๋ค.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: document-worker-scaledobject
namespace: default
spec:
scaleTargetRef:
name: document-worker-deployment
triggers:
- type: rabbitmq
metadata:
protocol: http # Required for regex usage
useRegex: "true" # Enable regex pattern matching
queueName: "document-.*" # Or other regex pattern
mode: QueueLength
value: "5"
activationValue: "1"
๋ค๋ง, ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ RabbitMQ Management API๋ฅผ ํตํ ์ํ ์กฐํ ๋ฑ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ ํ๋กํ ์ฝ์ http๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
ํผํฌ ํ์ ํธ๋ํฝ ๋์ํ๊ธฐ
์์ 2๊ฐ์ง ์ผ์ด์ค๋ ๊ณํ๋ ๋ด์ฉ์ด์์ง๋ง, ๊ทธ ์ธ์๋ KEDA๋ฅผ ํ์ฉํ ์ผ์ด ์๊ฒผ์ต๋๋ค.
์ต๊ทผ์ ์ฃผ ์ฌ์ฉ ์๊ฐ๋(ํ์ผ ์ค์ 8์ ~ ์คํ 7์)์ ์๋น์ค ์๋ต ์๋๊ฐ ๋๋ ค์ง๋ค๋ ๋ถ๋ง์ด ์ ๊ธฐ๋์์ต๋๋ค.
๋ฌผ๋ก ์ ํ๋ฆฌ์ผ์ด์
๋ก์ง์ ๊ฐ์ ํ๋ ๊ฒ๋ ํ์ํ์ง๋ง ๋น์ฅ์ ์งํํ๊ธฐ ์ด๋ ค์ ๊ณ ์ธํ๋ผ ๋ ๋ฒจ์์ ์ ์ ๋์์ด ํ์ํ์ต๋๋ค.
์ฒ์์๋ CronJob ๋ฑ์ผ๋ก ๋ช ์์ Scaling์ ํ ์ง ๊ณ ๋ฏผํ์ง๋ง, ์กฐ์ฌํ๋ฉด์ KEDA์ Cron Scaler๋ฅผ ์ฌ์ฉํด ํน์ ์๊ฐ๋์ Pod ์๋ฅผ ์ ์งํ๋ ๋ฐฉ๋ฒ์ ์ฐพ๊ฒ ๋์์ต๋๋ค.
Cron Scaler๋ฅผ ์ฌ์ฉํ๋ฉด ์ ํด์ง ์๊ฐ๋์ ์ํ๋ Pod ์๋ฅผ ๋ณด์ฅํ๋๋ก ์ค์ ํ ์ ์์ต๋๋ค. ์ ํฌ๋ ํผํฌ ํ์ ์ด์ ์ ๋ฆฌ์์ค๊ฐ ์ฌ๋ผ์ค๋ ์๊ฐ๊น์ง ๊ฐ์ํ์ฌ, ์ ํ 15๋ถ ์ ๋ ์ฌ์ ๋ฅผ ๋์์ต๋๋ค. ๋ํ, ๊ธฐ์กด์ HPA์ฒ๋ผ CPU ์ฌ์ฉ๋ฅ ๊ธฐ์ค Scaling๋ ๊ฐ์ด ์ ์ฉํ ์ ์๋ค๊ณ ํ์ฌ ํด๋น ์ต์ ๋ ์ถ๊ฐํ์ต๋๋ค.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: web-cron-scaledobject
namespace: default
spec:
scaleTargetRef:
name: web-deployment
triggers:
- type: cron
metadata:
timezone: Asia/Tokyo
start: "45 7 * * 1-5"
end: "15 19 * * 1-5"
desiredReplicas: "30"
- type: cpu
metadata:
type: Utilization
value: "85"
์ฌ๊ธฐ์ desiredReplicas์ ์์น๋ ๊ณ์ ์๋ต ์๋๋ฅผ ๋ณด๋ฉด์ ์กฐ์ ํ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ 2~3๋ฒ ์ ๋์ ์กฐ์ ์ ๊ฑฐ์ณ ์ต์ ์ ์์น๋ฅผ ์ฐพ์ ์ ์์์ต๋๋ค.
์ฌ์ฉํ๋ ๋ฆฌ์์ค๋ฅผ ๋ ๋๋ฆฌ๋ ํ์์๊ธฐ ๋๋ฌธ์ ์ถ๊ฐ์ ์ธ ๋น์ฉ ๋ฐ์์ ์ด์ฉ ์ ์์์ง๋ง, ํ์คํ ์ฑ๋ฅ์ด ๊ฐ์ ๋์๋ค๋ ํผ๋๋ฐฑ์ ๋ฐ์ ์ ์์์ต๋๋ค.
Cron Scaler์ ๋ํ ์ถ๊ฐ ์ ๋ณด๋ ์ด ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
์ฃผ์์ฌํญ
- Argo CD๋ก KEDA๋ฅผ ์ค์นํ ๋ ๋ช ๊ฐ์ง ์ด์๊ฐ ์์์ต๋๋ค.
- CRD ๋ฌธ์ ๋ก Server-side Apply๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
- ์ผ๋ถ OutOfSync ์ํ ํด๊ฒฐ์ ์ํด
ignoreDifferences์ฒ๋ฆฌ๊ฐ ํ์ํ์ต๋๋ค.
- KEDA๋ฅผ ํ์ฑํํ๊ธฐ ์ ์ ๋ฐ๋์ HPA๋ฅผ ๋นํ์ฑํํด์ผ ํฉ๋๋ค.
- KEDA๊ฐ ์์ฒด์ ์ผ๋ก HPA๋ฅผ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์๊ธฐ์น ์์ ์ถฉ๋์ด๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
- ์ด๋ HPA์ ๋์ผํ๋ฐ, KEDA๋ฅผ ํ์ฑํํ๋ค๋ฉด Deployment์
replicas๊ฐ์ ๋น์ ๋์ด์ผ ํฉ๋๋ค.- HPA๊ฐ ์กฐ์ ํ๋ ค๋ ๊ฐ๊ณผ
replicas๊ฐ์ด ์ถฉ๋ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. - ์ด๋ฅผ ๊ฐ์ฅ ์ฝ๊ฒ ํ์ธํ๋ ค๋ฉด
replicas๋ฅผ ์ค์ ํด ๋๊ณ , KEDA์์ Zero scaling, ์ฆ ์ต์๋ฅผ 0์ผ๋ก ์ค์ ํด ๋ณด๋ฉด ๋ฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด KEDA๊ฐ ๊ณ์ Pod๋ฅผ ์ข ๋ฃ์ํค๊ณ Deployment๋ ๊ณ์ ๋ณต๊ตฌ์ํค๋ ๋ฌดํ ๋ฃจํ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
- HPA๊ฐ ์กฐ์ ํ๋ ค๋ ๊ฐ๊ณผ
๋ง์น๋ฉฐ
์ด๋ ๊ฒ KEDA๋ฅผ ๋์
ํ์ฌ ์ด๋ฒคํธ ๊ธฐ๋ฐ์ ๋์ ์ค์ผ์ผ๋ง ํ๊ฒฝ์ ๊ตฌ์ถํ๊ณ , ์ถ๊ฐ๋ก ์๋น์ค ์์ ์ฑ๋ ํด๊ฒฐํ ์ ์์์ต๋๋ค.
KEDA๋ ์์์ ์ค๋ช
ํ 2๊ฐ์ ๊ธฐ๋ฅ ์ธ์๋ ๋ง์ ๊ธฐ๋ฅ๊ณผ ์ด๋ฒคํธ ์์ค๋ฅผ ์ง์ํ๊ธฐ ๋๋ฌธ์ ๋์ฑ ๋ค์ํ ์ํฉ์์ ํ์ฉํ ์ ์์ต๋๋ค. ๋ํ, ์ถํ์๋ Cold start๋ฅผ ๊ณ ๋ คํ์ง ์์๋ ๋๋ ์ฑ์ ๋ํด Scale-to-zero ๊ฐ๋
์ ์ ์ฉํ์ฌ ๋์ฑ ํจ์จ์ ์ธ ์์ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋ํ๊ณ ์์ต๋๋ค.
๊ฐ์ธ์ ์ผ๋ก ํ ๋ฒ ์จ ๋ณด๊ณ ์ถ์๋ ๋๊ตฌ๋ผ ๋ง์กฑ๋๊ฐ ์ด์ง ๋ ๋์๋ ๊ฒ์ ๋ค์ ๋๋ค ๐
๋ค๋ง ์์ผ๋ก๋ Scaling ์ต์
์ ๊ณ์ ์กฐ์ ํด ๋๊ฐ๋ฉฐ ์ต์ ์ ์ค์ ์ ์ฐพ๊ณ , ๋ํ KEDA Scaling ์ด๋ฒคํธ๋ฅผ ์์งํ์ฌ ๋ชจ๋ํฐ๋งํ๋ ์์
๋ ํ์ํ๋ค๊ณ ์๊ฐํ๊ณ ์์ต๋๋ค.
(ํ์์ ๊ฐ์ฅ ํ์คํ ๊ฒ์ Deployment์ ์ด๋ฒคํธ๋ฅผ ์์งํ๋ ๊ฒ์ด๋ผ๊ณ ๋ณด๊ณ ์์ต๋๋ค.)
์์ผ๋ก๋ KEDA ์ธ์ ์ ์ฉํด ๋ณด๊ณ ์ถ์ ๋๊ตฌ๊ฐ ๋ง์ต๋๋ค. ์์ ์ฑ์ ์๊ฐํ๋ฉด์ ์ ์ ๋ฐ์ ๋ ํ๊ฒฝ์ ๊ตฌ์ถํด ๋๊ฐ๋ ค๊ณ ํฉ๋๋ค.
์ฐธ๊ณ ์๋ฃ
- KEDA ๊ณต์ ๋ฌธ์
- keda admissionwebhook shows out of sync in argocd due to cabundle field
- CustomResourceDefinition.apiextensions.k8s.io โscaledjobs.keda.shโ is invalid: metadata.annotations: Too long: must have at most 262144 bytes
- HPA and ArgoCD - scaling is disabled since the replica count of the target is zero