Notes
K8s 09. Knative Workload
Knative를 Kubernetes-native serverless platform으로 이해하고, Serving, Eventing, Revision, traffic split, autoscaling, scale-to-zero의 동작 구조를 정리한다.
- Published
- Updated
- Area
- Cloud Infrastructure
- Type
- concept
- Series
- Kubernetes Essentials
- Category
- Notes
Kubernetes는 containerized workload를 배포하고 운영하는 강력한 orchestration platform이다. 하지만 개발자가 단순한 HTTP API 하나를 배포하려고 해도 Deployment, Service, Ingress, HorizontalPodAutoscaler, ConfigMap, Secret, probe, TLS, rollout 전략 등을 직접 조합해야 할 수 있다.
개발자가 원하는 것은 더 단순할 수 있다.
이 container image를 HTTP endpoint로 배포하고 싶다.
traffic이 없으면 비용을 줄이고 싶다.
traffic이 늘어나면 자동으로 scale out하고 싶다.
새 버전을 배포한 뒤 traffic을 조금씩 나눠보고 싶다.
event가 들어오면 특정 service를 실행하고 싶다.
Knative는 이런 요구를 Kubernetes 위에서 serverless-style로 풀기 위한 platform이다. Kubernetes를 대체하는 것이 아니라, Kubernetes 위에 더 높은 수준의 application runtime abstraction을 제공한다.
개발자는 containerized workload 또는 function을 정의한다.
Knative는 routing, revision, traffic split, autoscaling, scale-to-zero, event delivery를 처리한다.
Kubernetes는 실제 Pod scheduling, networking, storage, controller reconciliation을 수행한다.
핵심 요약
Knative는 Kubernetes 위에서 containerized application을 serverless처럼 실행할 수 있게 해주는 Kubernetes-native serverless platform이다.
Application code
↓
Container image / Function
↓
Knative
↓
Kubernetes
↓
Container runtime
↓
Node infrastructure
Knative는 크게 다음 영역을 중심으로 이해할 수 있다.
| 구성요소 | 역할 | 현재 관점 |
|---|---|---|
| Build | source code를 container image로 만드는 workflow | 역사적으로 중요했지만 현재는 Tekton 등으로 분화된 맥락이 있음 |
| Serving | HTTP/gRPC workload 배포, revision, routing, autoscaling, scale-to-zero | Knative 핵심 |
| Eventing | event producer와 consumer를 연결하는 event-driven architecture API | Knative 핵심 |
| Functions | function-style 개발과 container화를 돕는 도구 | 개발자 경험 보조 |
한 문장으로 정리하면 다음과 같다.
Knative는 Kubernetes 위에서 containerized application을 serverless처럼 실행하고, HTTP traffic과 event를 기준으로 자동 scaling·routing·revision 관리를 제공하는 Kubernetes-native serverless platform이다.
Serverless라는 말의 의미
Serverless는 “서버가 존재하지 않는다”는 뜻이 아니다. 실제로는 서버, VM, node, network, storage가 모두 존재한다. 다만 개발자가 서버를 직접 provision하거나, 특정 node를 관리하거나, replica 수를 항상 직접 조절하지 않아도 되도록 platform이 추상화해준다는 뜻에 가깝다.
serverless ≠ 서버가 없음
serverless = 서버 관리를 개발자 경험에서 숨김
Knative도 마찬가지다. Knative는 Kubernetes cluster 위에서 동작한다. 즉 node는 여전히 존재하고, Pod도 여전히 생성되며, container image도 여전히 registry에서 pull된다.
다만 개발자는 Deployment, Service, Ingress, HPA를 직접 조합하는 대신, 더 높은 수준의 Knative Service나 eventing resource를 선언할 수 있다.
Developer
↓
Knative Service / Eventing Resource
↓
Knative Controllers
↓
Kubernetes Deployment / Pod / Service / Networking
↓
Cluster Nodes
따라서 Knative에서 말하는 serverless는 Kubernetes 위에 serverless-style developer experience를 제공하는 것으로 이해해야 한다.
왜 Knative가 필요한가?
Kubernetes는 강력하지만, 단순한 애플리케이션 하나를 배포할 때도 사용자가 많은 resource를 알아야 한다.
일반 Kubernetes에서 API 하나를 배포하려면 보통 다음이 필요하다.
Deployment
Service
Ingress 또는 Gateway
HorizontalPodAutoscaler
ConfigMap
Secret
readinessProbe
livenessProbe
TLS 설정
rollout 전략
resource requests/limits
YAML도 많아진다.
deployment.yaml
service.yaml
ingress.yaml
hpa.yaml
configmap.yaml
secret.yaml
Kubernetes object를 직접 조합하는 방식은 유연하지만, 개발자 경험 관점에서는 부담이 될 수 있다.
Knative는 다음과 같은 반복을 줄인다.
HTTP endpoint 자동 생성
revision 기반 배포
traffic split
autoscaling
scale-to-zero
event source와 event consumer 연결
serverless workload abstraction
즉 Knative의 목표는 Kubernetes를 숨기는 것이 아니라, Kubernetes 위에서 HTTP/event 기반 workload를 더 serverless하게 다루는 것이다.
Knative의 위치
Knative는 Kubernetes 위의 platform layer다.
Serverless experience
↓
Knative abstraction
↓
Kubernetes orchestration
↓
Container runtime
↓
Infrastructure
Kubernetes는 containerized workload를 scheduling, scaling, self-healing하는 orchestration layer다. Knative는 그 위에서 다음 기능을 제공한다.
HTTP endpoint 자동 생성
revision 기반 배포
traffic split
autoscaling
scale-to-zero
event source와 event consumer 연결
serverless workload abstraction
중요한 것은 Knative가 Kubernetes의 대체재가 아니라는 점이다.
Kubernetes
→ Pod, Deployment, Service, Ingress, HPA 등을 제공하는 orchestration platform
Knative
→ Kubernetes 위에서 serverless workload experience를 제공하는 abstraction layer
Knative Serving
Knative Serving은 HTTP/gRPC 기반 containerized application을 serverless처럼 배포하고 scale하게 해주는 component다.
Serving이 해결하는 문제
일반 Kubernetes에서는 API 하나를 배포하려면 Deployment를 작성한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
template:
spec:
containers:
- name: api
image: registry.example.com/api:1.0.0
그리고 Service가 필요하다.
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
ports:
- port: 80
targetPort: 3000
외부 노출을 위해 Ingress 또는 Gateway도 필요하다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 80
Autoscaling까지 붙이면 HPA도 필요하다.
Knative Serving은 이 복잡한 조합을 더 높은 수준의 resource로 감싼다.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: api
spec:
template:
spec:
containers:
- image: registry.example.com/api:1.0.0
ports:
- containerPort: 3000
여기서 주의할 점은 Kubernetes의 Service와 Knative의 Service가 이름은 같지만 다른 resource라는 것이다.
Kubernetes Service
→ v1 Service
→ ClusterIP, NodePort, LoadBalancer 등 networking abstraction
Knative Service
→ serving.knative.dev/v1 Service
→ serverless workload lifecycle abstraction
Knative Service
Knative Service는 Serving의 가장 상위 abstraction이다. 사용자는 보통 Knative Service 하나를 선언한다.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: registry.example.com/hello:1.0.0
이 선언 하나로 Knative는 내부적으로 여러 resource를 관리한다.
Knative Service
├─ Configuration
├─ Revision
├─ Route
├─ Kubernetes Deployment
├─ Kubernetes Service
└─ networking resource
즉 개발자는 “이 container를 service로 배포하고 싶다”고 선언하고, Knative는 배포와 routing, revision, autoscaling을 담당한다.
Configuration, Revision, Route
Knative Serving을 제대로 이해하려면 Configuration, Revision, Route를 알아야 한다.
Knative Service
├─ Configuration
├─ Revision
└─ Route
Configuration
Configuration은 “어떤 container image와 설정으로 workload를 실행할 것인가”를 나타낸다.
Configuration
→ image
→ env
→ resource
→ container spec
→ runtime 설정
사용자가 Knative Service의 template을 바꾸면 Configuration이 바뀌고, 그 결과 새로운 Revision이 생성된다.
Revision
Revision은 특정 시점의 immutable한 workload snapshot이다.
예를 들어 처음에는 image api:1.0.0을 배포한다.
Revision: api-00001
image: api:1.0.0
이후 image를 api:1.1.0으로 바꾼다.
Revision: api-00002
image: api:1.1.0
Revision은 immutable하다고 이해하면 좋다. 새 버전이 나오면 기존 Revision을 수정하는 것이 아니라 새 Revision을 만든다.
api-00001 → image 1.0.0
api-00002 → image 1.1.0
api-00003 → image 1.2.0
이 구조 덕분에 traffic split, rollback, canary 배포가 쉬워진다.
Route
Route는 외부 endpoint와 Revision들을 연결한다.
Route
↓
Revision api-00001: 90%
Revision api-00002: 10%
Route는 사용자가 접근하는 URL과 실제 backend Revision 사이의 mapping을 담당한다.
Traffic splitting
Knative Serving의 강력한 기능 중 하나는 traffic split이다.
예를 들어 새 버전 api:1.1.0을 바로 100% 배포하지 않고, 10%만 보내고 싶다고 하자.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: api
spec:
traffic:
- revisionName: api-00001
percent: 90
- revisionName: api-00002
percent: 10
이렇게 하면 traffic이 다음처럼 분배된다.
90% → old revision, api-00001
10% → new revision, api-00002
운영 흐름은 다음과 같다.
1. 새 image 배포
2. 새 Revision 생성
3. 10% traffic만 새 Revision으로 전달
4. metric과 log 확인
5. 문제 없으면 50%, 100%로 증가
6. 문제 있으면 old Revision으로 rollback
이 구조는 canary deployment와 blue-green deployment를 구현하기 쉽게 만든다.
일반 Kubernetes에서도 Argo Rollouts, service mesh, Ingress Controller, Gateway API 등을 조합하면 비슷한 작업을 할 수 있다. Knative는 이 경험을 Serving resource 모델 안에 포함한다.
Autoscaling과 scale-to-zero
Knative의 대표적인 특징은 autoscaling과 scale-to-zero다.
Kubernetes HPA와의 차이
Kubernetes 기본 HorizontalPodAutoscaler는 보통 CPU, memory, custom metric을 기준으로 replica 수를 조정한다.
CPU usage 증가
↓
HPA가 replica 증가
하지만 HTTP request 기반 workload에서는 CPU만으로는 충분하지 않을 수 있다. 요청 수, concurrency, latency, queueing 같은 HTTP-level signal이 더 중요할 수 있다.
Knative Serving은 incoming demand에 맞춰 application을 자동 scale하는 구조를 제공한다.
Scale-to-zero
Knative의 핵심 기능 중 하나는 traffic이 없을 때 replica를 0까지 줄이는 것이다.
요청 없음
↓
replicas = 0
요청 발생
↓
Activator가 요청 수신
↓
Pod scale up
↓
준비되면 요청 전달
이 기능은 일반 Kubernetes Deployment와 HPA만으로는 자연스럽게 얻기 어렵다. replica가 0이면 Pod metric이 없고, 요청을 받아서 Pod를 다시 깨울 entrypoint도 필요하다.
Knative는 Activator와 networking layer를 이용해 이 serverless-style flow를 제공한다.
Scale-to-zero의 장점과 trade-off
장점:
traffic이 없는 서비스의 resource 사용량 감소
개발/테스트 환경 비용 절감
sporadic workload에 적합
function-style workload에 적합
trade-off:
cold start 발생 가능
첫 요청 latency 증가 가능
container image pull 시간이 길면 scale-from-zero 지연
초기화가 무거운 application에는 부적합할 수 있음
stateful workload에는 일반적으로 적합하지 않음
즉 scale-to-zero는 항상 좋은 것이 아니다. latency-sensitive API나 항상 warm 상태가 필요한 서비스는 minimum scale을 1 이상으로 설정하는 것이 나을 수 있다.
Activator의 역할
Knative scale-to-zero를 이해하려면 Activator를 알아야 한다.
일반적으로 Pod가 0개면 요청을 처리할 backend가 없다.
Client
↓
Service endpoint 없음
↓
요청 실패?
Knative에서는 Activator가 중간에서 요청을 받아줄 수 있다.
Client request
↓
Ingress / Gateway
↓
Knative Activator
↓
Autoscaler에 scale-up 필요 신호
↓
Pod 생성
↓
Pod Ready
↓
요청 전달
Activator는 단순 proxy 이상의 의미를 갖는다. scale-from-zero 상황에서 요청을 보류하고, autoscaler가 새 Pod를 띄운 뒤 준비된 Pod로 traffic을 넘기는 데 관여한다.
이 구조 덕분에 Knative는 “Pod가 0개인 상태에서도 endpoint를 유지”할 수 있다.
Concurrency 기반 scaling
Knative에서는 CPU뿐 아니라 request concurrency 기반으로 scaling을 설계할 수 있다.
예를 들어 container 하나가 동시에 10개의 요청까지만 처리하도록 하고 싶다고 하자.
metadata:
annotations:
autoscaling.knative.dev/target: "10"
개념적으로는 다음과 같다.
현재 동시 요청 수 = 100
target concurrency per pod = 10
필요 Pod 수 ≈ 10
이 방식은 HTTP server, gRPC service, event handler처럼 요청 단위로 부하가 들어오는 workload에 유용하다.
다만 concurrency를 너무 낮게 잡으면 Pod가 과도하게 많이 생성될 수 있고, 너무 높게 잡으면 latency가 증가할 수 있다.
target concurrency 낮음
→ 빠른 scale out
→ resource 사용 증가 가능
target concurrency 높음
→ resource 효율 증가
→ 요청 queueing과 latency 증가 가능
Knative Eventing
Knative의 또 다른 축은 Eventing이다.
Knative Eventing은 event-driven architecture를 Kubernetes 위에서 구성하기 위한 API와 component를 제공한다.
Event-driven architecture
Event-driven architecture에서는 서비스가 서로 직접 호출하기보다 event를 발행하고, 다른 서비스가 그 event를 구독해 처리한다.
예를 들어 주문 시스템을 생각해보자.
order-service
↓ emits OrderCreated event
payment-service
↓ consumes OrderCreated event
inventory-service
↓ consumes OrderCreated event
notification-service
↓ consumes OrderCreated event
직접 호출 방식:
order-service
├─ payment-service 호출
├─ inventory-service 호출
└─ notification-service 호출
event-driven 방식:
order-service
↓
OrderCreated event
↓
Broker
├─ payment-service
├─ inventory-service
└─ notification-service
장점은 producer와 consumer를 느슨하게 결합할 수 있다는 점이다.
Source, Broker, Trigger, Sink
Knative Eventing의 핵심 개념은 다음과 같다.
| 개념 | 의미 |
|---|---|
Source | event를 만들어내는 producer |
Broker | event를 받아 routing하는 중간 hub |
Trigger | 어떤 event를 어떤 consumer에게 보낼지 정의하는 rule |
Sink | event를 받는 consumer endpoint |
흐름은 다음과 같다.
Event Source
↓
Broker
↓
Trigger
↓
Sink
예를 들어 OrderCreated event만 특정 consumer에게 보내고 싶다면, Trigger가 event type을 기준으로 filtering할 수 있다.
Broker
↓
Trigger: type = com.example.order.created
↓
payment-service
CloudEvents
Knative Eventing은 event를 표준화된 형식으로 다루기 위해 CloudEvents를 사용한다.
개념적으로 event에는 다음 정보가 들어간다.
event id
event source
event type
event time
content type
data payload
예시:
{
"specversion": "1.0",
"id": "order-123",
"source": "/orders",
"type": "com.example.order.created",
"time": "2026-06-02T10:00:00Z",
"datacontenttype": "application/json",
"data": {
"orderId": "123",
"amount": 50000
}
}
이렇게 event shape을 표준화하면 producer와 consumer가 더 일관된 방식으로 통신할 수 있다.
Serving과 Eventing의 관계
Knative Serving과 Eventing은 독립적으로도 사용할 수 있지만 함께 쓰면 강력하다.
예를 들어 event가 들어왔을 때만 특정 service를 실행하고 싶다고 하자.
Event Source
↓
Broker
↓
Trigger
↓
Knative Service
↓
scale from zero
↓
event 처리
이 구조는 serverless function과 유사한 경험을 제공한다.
예시:
GitHub webhook event
↓
Knative Eventing
↓
build-trigger service
↓
scale from zero
↓
작업 수행 후 다시 scale to zero
또는 object storage에 파일이 올라왔을 때 처리할 수도 있다.
ObjectCreated event
↓
image-resizer service
↓
thumbnail 생성
↓
처리 완료 후 idle 시 scale to zero
즉 Knative는 HTTP request-driven workload와 event-driven workload를 모두 Kubernetes 위에서 다룰 수 있게 한다.
Knative Build: 역사적 맥락
Knative 초기에는 주요 구성요소로 Build가 함께 설명되었다. Build의 목적은 source code를 container image로 만드는 과정을 자동화하는 것이었다.
source code pull
dependencies install
container image build
registry push
흐름은 다음과 같다.
Git repository
↓
Build definition
↓
container image build
↓
registry push
↓
Serving workload로 배포
현재 관점에서는 build pipeline 영역은 Tekton 같은 별도 project로 발전한 맥락이 있다. 따라서 Knative를 정리할 때는 다음처럼 보는 것이 좋다.
초기 Knative 설명
→ Build, Serving, Eventing
현재 실무 관점
→ Serving/Eventing 중심
→ build는 Tekton 또는 CI/CD pipeline과 결합하는 경우가 많음
확인 필요: 실제 운영 환경에서 사용하는 Knative version과 설치 방식에 따라 Build 관련 기능의 위치와 지원 범위는 다를 수 있다.
Knative와 Istio의 관계
Knative Serving은 HTTP traffic routing, revision routing, traffic split, ingress/gateway 기능을 필요로 한다. 그래서 초기 Knative 설명에서는 Istio와의 관계가 자주 강조되었다.
Knative는 networking layer가 필요하다.
external request
↓
gateway / ingress
↓
Knative route
↓
revision
↓
Pod
초기에는 Istio가 대표적인 선택지였지만, Knative의 networking layer는 반드시 Istio만을 의미하지 않는다. Kourier, Contour 등 다른 networking layer도 사용할 수 있다.
정리하면 다음과 같다.
Knative
→ serverless workload abstraction
Istio / Kourier / Contour 등
→ traffic routing implementation
Kubernetes
→ workload scheduling과 resource management
즉 Knative는 traffic routing 기능을 사용하지만, 특정 service mesh 하나에만 종속된 개념으로 보면 안 된다.
Knative Service 예제 깊게 보기
간단한 Knative Service 예시를 보자.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/min-scale: "0"
autoscaling.knative.dev/max-scale: "10"
spec:
containers:
- image: registry.example.com/hello:1.0.0
env:
- name: TARGET
value: "Knative"
이 YAML의 의미는 다음이다.
hello라는 Knative Service를 만든다.
container image는 registry.example.com/hello:1.0.0이다.
traffic이 없으면 0까지 scale down할 수 있다.
traffic이 많아져도 최대 10개 replica까지만 늘린다.
이 resource를 apply한다.
kubectl apply -f hello.yaml
상태를 확인한다.
kubectl get ksvc
예시 출력은 이런 형태일 수 있다.
NAME URL READY
hello https://hello.default.example.com True
여기서 ksvc는 Knative Service를 의미한다.
ksvc = Knative Service
이제 사용자는 URL을 호출한다.
curl https://hello.default.example.com
traffic이 없으면 Pod가 0개까지 줄어들 수 있다.
kubectl get pods
요청이 들어오면 다시 Pod가 생긴다.
request received
↓
Knative Activator
↓
scale up
↓
Pod Ready
↓
response
Revision 기반 배포 예시
처음 image가 hello:1.0.0이라고 하자.
image: registry.example.com/hello:1.0.0
이때 revision이 생성된다.
hello-00001
이후 image를 hello:1.1.0으로 바꾼다.
image: registry.example.com/hello:1.1.0
새 revision이 생성된다.
hello-00002
이제 traffic split을 걸 수 있다.
spec:
traffic:
- revisionName: hello-00001
percent: 90
- revisionName: hello-00002
percent: 10
이 구조는 다음 운영에 유용하다.
canary deployment
blue-green deployment
rollback
A/B testing
progressive delivery
Knative에서는 Revision이 배포 단위 추적의 핵심이 된다.
Git commit
↓
image tag
↓
Knative Revision
↓
traffic percent
Knative와 Kubernetes Deployment 비교
| 항목 | Kubernetes Deployment | Knative Service |
|---|---|---|
| 기본 목적 | Pod replica 유지 | serverless HTTP workload lifecycle 관리 |
| replica 설정 | 사용자가 replicas 지정 | autoscaling 중심 |
| scale-to-zero | 기본적으로 직접 지원하지 않음 | KPA 기반으로 지원 가능 |
| revision | ReplicaSet/rollout history 중심 | Revision이 핵심 abstraction |
| traffic split | 기본 Deployment만으로는 제한적 | Route에서 revision별 traffic split 가능 |
| endpoint | Service/Ingress 별도 구성 | URL/routing abstraction 포함 |
| event-driven 연계 | 별도 도구 필요 | Eventing과 자연스럽게 결합 |
| 적합한 대상 | 항상 떠 있는 app, 일반 workload | HTTP/event 기반 serverless workload |
Knative Service는 Deployment를 대체한다기보다, HTTP serverless workload를 더 높은 수준으로 표현한다.
Knative와 FaaS의 차이
Knative는 종종 Function-as-a-Service, FaaS와 함께 설명된다. 하지만 Knative 자체를 단순히 FaaS라고만 보면 좁다.
FaaS는 보통 다음 경험을 의미한다.
function code 작성
event trigger 연결
요청 시 실행
사용량 기반 scale
Knative는 container 기반이다.
container image를 실행한다.
HTTP service를 scale한다.
event source와 sink를 연결한다.
function-style 개발도 가능하지만 container workload가 기본이다.
즉 Knative는 “함수만 실행하는 platform”이라기보다 serverless container platform에 가깝다.
FaaS
→ function 단위 추상화
Knative
→ Kubernetes 위의 serverless container / eventing abstraction
Knative Functions를 사용하면 function-style 개발 경험도 얻을 수 있지만, Knative Serving의 기본 단위는 containerized workload다.
Knative와 KEDA 비교
Knative를 공부하다 보면 KEDA와 비교하게 된다.
둘 다 scale-to-zero와 event-driven scaling 맥락에서 등장한다. 하지만 초점이 다르다.
| 구분 | Knative | KEDA |
|---|---|---|
| 주요 초점 | serverless HTTP workload + eventing platform | event source 기반 autoscaling |
| 핵심 resource | Knative Service, Broker, Trigger | ScaledObject, TriggerAuthentication |
| HTTP endpoint abstraction | 강함 | 기본 핵심은 아님 |
| revision/traffic split | Serving에서 제공 | 직접 제공하지 않음 |
| scale-to-zero | Serving/KPA 기반 | external metrics 기반 HPA 확장 |
| 적합한 경우 | HTTP/gRPC serverless service, event-driven service | queue, Kafka, Prometheus, external metric 기반 worker scaling |
예를 들어 HTTP API를 serverless endpoint로 배포하고 traffic split까지 하고 싶다면 Knative가 잘 맞는다.
HTTP API
revision
traffic split
scale-to-zero
반면 Kafka queue lag에 따라 worker Deployment를 0에서 N까지 scale하고 싶다면 KEDA가 더 단순할 수 있다.
Kafka lag
↓
KEDA ScaledObject
↓
Deployment scale
둘은 경쟁 관계라기보다 문제 영역이 일부 겹치는 도구로 이해하는 것이 좋다.
Knative가 적합한 경우
Knative가 잘 맞는 경우는 다음과 같다.
HTTP 기반 service를 serverless처럼 운영하고 싶다.
traffic이 없는 시간대에는 0까지 scale down하고 싶다.
canary/blue-green traffic split을 간단히 하고 싶다.
event-driven architecture를 Kubernetes 위에서 구성하고 싶다.
개발자가 Deployment, Service, Ingress, HPA를 직접 다루는 부담을 줄이고 싶다.
container 기반 serverless platform을 직접 운영하고 싶다.
예시 workload:
sporadic internal API
webhook processor
image thumbnail generator
event processor
lightweight backend service
demo/test environment service
low-traffic admin service
function-style HTTP handler
Knative가 적합하지 않을 수 있는 경우
Knative가 항상 정답은 아니다.
항상 warm 상태가 필요한 latency-sensitive API
초기화 시간이 매우 긴 application
stateful database
long-running connection 중심 workload
raw TCP/UDP service
GPU resource를 장시간 점유하는 service
매우 단순한 Kubernetes Deployment로 충분한 workload
특히 scale-to-zero는 cold start를 만든다.
첫 요청
↓
Pod scale from zero
↓
image pull 또는 container start
↓
readiness 통과
↓
응답
이 시간이 사용자 경험에 영향을 주면 min-scale을 1 이상으로 두거나, 일반 Deployment를 사용하는 것이 나을 수 있다.
운영 관점에서 봐야 할 것
Knative를 도입하면 application YAML은 단순해질 수 있지만, platform 운영자는 새로운 책임을 갖는다.
Knative Serving 설치와 upgrade
Knative Eventing 설치와 upgrade
networking layer 선택
Activator와 autoscaler 상태 확인
CRD version 관리
Knative controller logs 확인
scale-to-zero 정책 설정
domain template 설정
TLS/cert-manager 연동
event broker backend 선택
observability 구성
즉 Knative는 개발자 경험을 단순화하지만, platform layer는 더 풍부해진다.
Knative troubleshooting 흐름
Knative Service가 정상 동작하지 않을 때는 일반 Kubernetes resource와 Knative resource를 함께 봐야 한다.
Knative Service 확인
kubectl get ksvc
kubectl describe ksvc hello
확인할 것:
READY 상태인가?
URL이 생성되었는가?
latest created revision은 무엇인가?
latest ready revision은 무엇인가?
conditions에 error가 있는가?
Revision 확인
kubectl get revisions
kubectl describe revision hello-00001
확인할 것:
Revision이 Ready인가?
container image pull이 성공했는가?
resource 설정이 올바른가?
readiness 실패가 있는가?
Pod 확인
kubectl get pods
kubectl logs <pod-name>
kubectl describe pod <pod-name>
확인할 것:
Pod가 생성되었는가?
ImagePullBackOff가 있는가?
CrashLoopBackOff가 있는가?
containerPort가 맞는가?
application이 HTTP request를 받을 준비가 되었는가?
Route 확인
kubectl get routes.serving.knative.dev
kubectl describe route hello
확인할 것:
URL이 올바른가?
traffic split이 의도대로 되어 있는가?
revision target이 존재하는가?
Networking layer 확인
사용 중인 networking layer에 따라 확인할 namespace와 resource가 달라진다.
kubectl get pods -n knative-serving
kubectl get pods -n kourier-system
kubectl get pods -n istio-system
확인할 것:
Activator가 Running인가?
Autoscaler가 Running인가?
Controller가 Running인가?
Gateway/Ingress가 정상인가?
DNS가 Knative endpoint를 가리키는가?
Eventing 확인
Eventing 문제라면 다음을 확인한다.
kubectl get brokers
kubectl get triggers
kubectl get sources
kubectl describe broker <broker-name>
kubectl describe trigger <trigger-name>
확인할 것:
Source가 event를 발행하는가?
Broker가 Ready인가?
Trigger filter가 너무 좁지 않은가?
Sink URL이 올바른가?
consumer service가 Ready인가?
Knative와 DevOps workflow
Knative를 쓰면 CI/CD 흐름도 약간 달라진다.
일반 Kubernetes Deployment 흐름:
Source code
↓
CI test
↓
container image build
↓
registry push
↓
Deployment image tag update
↓
kubectl apply / GitOps sync
↓
rollout
Knative Serving 흐름:
Source code
↓
CI test
↓
container image build
↓
registry push
↓
Knative Service template image update
↓
new Revision 생성
↓
traffic split 또는 latest revision routing
GitOps와 결합하면 다음처럼 된다.
Git repository
↓
Knative Service YAML 변경
↓
Argo CD / Flux sync
↓
Knative controller reconcile
↓
Revision 생성
↓
Route traffic 적용
중요한 점은 Knative에서는 Revision이 배포 단위 추적의 핵심이 된다는 것이다.
Git commit
↓
image tag
↓
Knative Revision
↓
traffic percent
Knative와 observability
Knative는 autoscaling과 event-driven routing이 들어가기 때문에 observability가 중요하다.
확인해야 할 metric:
request count
concurrency
request latency
cold start latency
revision별 traffic
revision별 error rate
autoscaler decision
pod replica count
scale-to-zero 횟수
event delivery success/failure
broker latency
trigger delivery failure
일반 Kubernetes Deployment보다 더 봐야 할 것이 많다.
Pod가 몇 개인가?
왜 0개인가?
왜 scale up이 늦는가?
어느 Revision이 traffic을 받고 있는가?
event가 source에서 broker까지 왔는가?
trigger가 sink로 전달했는가?
Knative는 developer experience를 단순화하지만, 운영자는 control plane의 상태를 잘 관찰해야 한다.
Knative의 장점과 trade-off
장점
| 장점 | 설명 |
|---|---|
| serverless developer experience | 개발자가 Kubernetes object 세부 조합을 덜 다룸 |
| scale-to-zero | traffic이 없을 때 replica를 0까지 줄일 수 있음 |
| request 기반 autoscaling | HTTP/gRPC workload에 적합 |
| Revision 모델 | 버전별 immutable deployment snapshot 제공 |
| traffic split | canary, blue-green, rollback에 유용 |
| Eventing | event-driven architecture를 Kubernetes 위에서 구성 |
| Kubernetes-native | CRD와 controller를 통해 Kubernetes API와 통합 |
Trade-off
| Trade-off | 설명 |
|---|---|
| platform 복잡도 증가 | Knative controller, autoscaler, activator, networking layer 운영 필요 |
| cold start | scale-to-zero 이후 첫 요청 latency 증가 가능 |
| workload 적합성 | stateful, long-running TCP workload에는 부적합할 수 있음 |
| debugging 범위 증가 | Knative resource와 Kubernetes resource를 함께 봐야 함 |
| networking 의존성 | Kourier, Istio, Contour 등 선택과 운영 필요 |
| version 변화 | Knative component와 CRD lifecycle 관리 필요 |
Kubernetes, Knative, Serverless의 관계 정리
전체 관계를 다시 정리하면 다음과 같다.
Kubernetes
→ container orchestration platform
→ Pod, Deployment, Service, Ingress, HPA 등을 제공
Knative
→ Kubernetes 위의 serverless workload platform
→ Serving, Eventing, autoscaling, scale-to-zero, revision, traffic split 제공
Serverless
→ 개발자가 server 관리보다 code와 event/request 처리에 집중하는 운영 모델
즉 Knative는 Kubernetes 위에서 serverless를 구현하는 한 방식이다.
Serverless experience
↓
Knative abstraction
↓
Kubernetes orchestration
↓
Container runtime
↓
Infrastructure
자주 생기는 오해
오해 1: Knative를 쓰면 Kubernetes를 몰라도 된다
아니다. Knative는 Kubernetes 위에서 동작한다. 문제가 생기면 결국 다음을 봐야 한다.
Pod
Service
Revision
Route
Activator
Autoscaler
Ingress/Gateway
DNS
container logs
Knative는 Kubernetes를 숨기는 것이 아니라, Kubernetes 위에 serverless abstraction을 얹는 것이다.
오해 2: Serverless는 항상 비용이 0에 가까워진다
Knative Service가 scale-to-zero되면 해당 workload의 Pod resource는 줄어들 수 있다. 하지만 cluster node, control plane, Knative system component, networking component는 여전히 존재한다.
scale-to-zero
→ application Pod는 0개 가능
하지만
→ cluster node는 여전히 존재
→ Knative control plane은 동작
→ networking layer도 동작
즉 Knative serverless는 public cloud FaaS의 과금 모델과 동일하다고 보면 안 된다.
오해 3: 모든 서비스를 scale-to-zero하면 좋다
아니다. cold start가 문제될 수 있다.
사용자-facing latency-sensitive API
실시간 처리 서비스
긴 초기화 시간이 필요한 app
large model loading app
이런 workload는 min-scale을 1 이상으로 두거나 일반 Deployment가 더 적합할 수 있다.
오해 4: Knative는 Function 전용이다
Knative는 function-style 개발을 지원할 수 있지만, 기본적으로 containerized workload를 실행한다. 따라서 일반 HTTP container service도 Knative Serving으로 배포할 수 있다.
오해 5: Knative Eventing은 message queue를 완전히 대체한다
Knative Eventing은 event routing abstraction을 제공한다. 실제 event delivery backend는 Kafka, RabbitMQ, NATS 등과 결합할 수 있다. 따라서 Eventing은 message broker를 없애는 것이 아니라, Kubernetes-native event routing API를 제공하는 쪽에 가깝다.
실제 선택 기준
Knative를 도입할지 판단할 때는 다음 질문을 던져야 한다.
HTTP/gRPC workload를 serverless처럼 운영하고 싶은가?
traffic이 없는 시간대가 긴 서비스가 많은가?
cold start를 감수할 수 있는가?
revision과 traffic split이 중요한가?
event-driven architecture를 Kubernetes 위에서 표준화하고 싶은가?
platform team이 Knative control plane을 운영할 수 있는가?
기존 Ingress/Gateway, monitoring, GitOps stack과 통합할 수 있는가?
Knative가 잘 맞는 경우:
sporadic traffic
webhook processor
internal tool
event handler
demo environment
serverless-style API
canary traffic split이 필요한 HTTP service
Knative보다 단순 Kubernetes가 나은 경우:
항상 떠 있어야 하는 core API
초저지연이 중요한 service
stateful database
운영팀이 Knative layer를 추가로 관리하기 어려운 환경
단순 Deployment + HPA로 충분한 workload
전체 mental model
Knative를 이해하기 위한 흐름은 다음과 같다.
1. Kubernetes는 container orchestration을 제공하지만,
개발자가 Deployment, Service, Ingress, HPA 등을 직접 조합해야 할 때가 많다.
2. Serverless는 개발자가 server와 replica 관리보다
request/event 처리 로직에 집중하게 해주는 운영 모델이다.
3. Knative는 Kubernetes 위에서 serverless-style developer experience를 제공한다.
4. Knative Serving은 HTTP/gRPC workload를 배포하고,
revision, route, traffic split, autoscaling, scale-to-zero를 제공한다.
5. Knative Eventing은 event source, broker, trigger, sink를 통해
event-driven architecture를 Kubernetes-native하게 구성한다.
6. Knative의 scale-to-zero는 traffic이 없을 때 Pod를 0개까지 줄이고,
요청이 들어오면 Activator와 Autoscaler를 통해 다시 scale up하는 구조다.
7. Knative는 Kubernetes를 대체하지 않는다.
Kubernetes 위에 CRD와 controller를 추가해 더 높은 수준의 abstraction을 제공한다.
8. Knative를 도입하면 개발자 경험은 단순해질 수 있지만,
platform team은 Knative control plane, networking layer, autoscaling, observability를 운영해야 한다.
요약
Kubernetes는 containerized workload를 운영하는 강력한 platform이지만, 개발자가 직접 Deployment, Service, Ingress, HPA, traffic routing, autoscaling을 모두 조합해야 할 수 있다. Knative는 이 복잡도를 줄이고, HTTP/event 기반 workload를 serverless처럼 배포할 수 있게 한다.
핵심은 다음이다.
Knative Serving
→ HTTP/gRPC workload 배포, revision, route, traffic split, autoscaling, scale-to-zero
Knative Eventing
→ event source, broker, trigger, sink 기반 event-driven architecture
Knative Functions
→ function-style 개발과 container화를 돕는 tooling
Kubernetes
→ 실제 Pod scheduling, networking, controller reconciliation 수행
한 문장으로 정리하면 다음과 같다.
Knative는 Kubernetes 위에서 containerized application을 serverless처럼 실행하고, HTTP traffic과 event를 기준으로 자동 scaling·routing·revision 관리를 제공하는 Kubernetes-native serverless platform이다.