K8s Knative 서버리스 운영

Knative란? K8s 위의 서버리스 플랫폼

Knative는 Kubernetes 위에서 서버리스 워크로드를 실행하는 오픈소스 플랫폼이다. AWS Lambda 같은 벤더 종속 서버리스와 달리, K8s 클러스터 어디서든 동일한 서버리스 경험을 제공한다. 트래픽이 없으면 Pod를 0으로 스케일다운(scale-to-zero)하고, 요청이 들어오면 자동으로 스케일업한다.

Knative는 두 가지 핵심 컴포넌트로 구성된다:

  • Knative Serving — 요청 기반 자동 스케일링, 트래픽 분할, 리비전 관리
  • Knative Eventing — 이벤트 드리븐 아키텍처, 소스-브로커-트리거 패턴

이 글에서는 Serving과 Eventing의 실전 구성부터 scale-to-zero 튜닝, 트래픽 분할 배포, 이벤트 브로커 파이프라인까지 심화 수준으로 다룬다.

Knative Serving 설치와 기본 구조

Knative Serving은 Kourier(경량 Ingress) 또는 Istio와 함께 설치한다.

# Knative Serving CRDs + Core
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.14.0/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.14.0/serving-core.yaml

# Kourier 네트워킹 레이어 (경량)
kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.14.0/kourier.yaml

# Kourier를 기본 Ingress로 설정
kubectl patch configmap/config-network 
  --namespace knative-serving 
  --type merge 
  -p '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'

Knative Service: 서버리스 워크로드 배포

Knative Service(ksvc)는 일반 K8s Deployment + Service + Ingress를 하나로 추상화한다.

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: order-api
  namespace: production
spec:
  template:
    metadata:
      annotations:
        # 스케일링 설정
        autoscaling.knative.dev/minScale: "0"       # scale-to-zero 허용
        autoscaling.knative.dev/maxScale: "20"       # 최대 Pod 수
        autoscaling.knative.dev/target: "100"        # Pod당 동시 요청 100개
        autoscaling.knative.dev/metric: "concurrency"
        # 콜드 스타트 최적화
        autoscaling.knative.dev/scale-down-delay: "30s"
        autoscaling.knative.dev/window: "60s"
    spec:
      containerConcurrency: 100
      timeoutSeconds: 300
      containers:
        - image: registry.example.com/order-api:v1.2.0
          ports:
            - containerPort: 8080
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
          resources:
            requests:
              cpu: 200m
              memory: 256Mi
            limits:
              cpu: "1"
              memory: 512Mi
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 3

배포하면 Knative가 자동으로 Revision(불변 스냅샷)을 생성하고, Route를 통해 트래픽을 라우팅한다.

# 배포 및 확인
kubectl apply -f order-api-ksvc.yaml

# 서비스 상태 확인
kubectl get ksvc order-api
# NAME        URL                                        READY
# order-api   https://order-api.production.example.com   True

# 리비전 목록
kubectl get revisions
# NAME              CONFIG NAME   GENERATION   READY
# order-api-00001   order-api     1            True

Scale-to-Zero 튜닝: 콜드 스타트 최적화

Scale-to-zero는 Knative의 핵심 가치이지만, 콜드 스타트 지연이 트레이드오프다. 실무에서는 워크로드 특성에 맞게 튜닝해야 한다.

파라미터 설명 권장값
scale-down-delay 마지막 요청 후 스케일다운 대기 API: 30~60s, 배치: 0s
minScale 최소 Pod 수 (0이면 zero 가능) 지연 민감: 1, 비용 절감: 0
window 스케일링 결정 관찰 윈도우 60s (안정적 스케일링)
target Pod당 목표 동시 요청 수 워크로드 프로파일링 후 결정
target-utilization-percentage 목표 사용률 (70%면 미리 스케일업) 70% (버스트 대비)

글로벌 설정은 config-autoscaler ConfigMap에서 관리한다:

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-autoscaler
  namespace: knative-serving
data:
  enable-scale-to-zero: "true"
  scale-to-zero-grace-period: "30s"
  scale-to-zero-pod-retention-period: "0s"
  stable-window: "60s"
  panic-window-percentage: "10.0"
  panic-threshold-percentage: "200.0"
  max-scale-up-rate: "1000.0"
  max-scale-down-rate: "2.0"
  target-burst-capacity: "200"

트래픽 분할: 카나리와 블루-그린 배포

Knative의 Revision 기반 트래픽 분할은 카나리 배포를 선언적으로 구현한다.

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: order-api
spec:
  template:
    metadata:
      name: order-api-v2  # 새 리비전 명시적 이름
    spec:
      containers:
        - image: registry.example.com/order-api:v2.0.0
  traffic:
    # 기존 버전에 90% 트래픽
    - revisionName: order-api-v1
      percent: 90
    # 새 버전에 10% 카나리
    - revisionName: order-api-v2
      percent: 10
      tag: canary  # canary.order-api.production.example.com으로 직접 접근 가능

카나리 검증 후 트래픽을 100%로 전환:

# 점진적 전환
kubectl patch ksvc order-api --type merge -p '
  {"spec":{"traffic":[
    {"revisionName":"order-api-v1","percent":50},
    {"revisionName":"order-api-v2","percent":50}
  ]}}'

# 완전 전환
kubectl patch ksvc order-api --type merge -p '
  {"spec":{"traffic":[
    {"revisionName":"order-api-v2","percent":100}
  ]}}'

Knative Eventing: 이벤트 드리븐 아키텍처

Knative Eventing은 CloudEvents 표준을 기반으로 이벤트 소스, 브로커, 트리거를 연결한다.

# Eventing 설치
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/eventing-crds.yaml
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/eventing-core.yaml

# In-Memory Channel (개발용) 또는 Kafka Channel (프로덕션)
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/in-memory-channel.yaml

Broker + Trigger 패턴으로 이벤트 파이프라인을 구성한다:

# 1. Broker 생성 — 네임스페이스의 이벤트 허브
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  name: default
  namespace: production
  annotations:
    eventing.knative.dev/broker.class: MTChannelBasedBroker
---
# 2. Trigger — 특정 이벤트 타입을 구독하여 서비스로 라우팅
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: order-created-trigger
  namespace: production
spec:
  broker: default
  filter:
    attributes:
      type: com.example.order.created    # CloudEvents type 필터
      source: /api/orders
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: inventory-service            # 이 ksvc가 이벤트 수신
---
# 3. 또 다른 Trigger — 같은 이벤트를 다른 서비스도 구독
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: order-notification-trigger
spec:
  broker: default
  filter:
    attributes:
      type: com.example.order.created
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: notification-service

KafkaSource: 외부 이벤트 소스 연동

apiVersion: sources.knative.dev/v1beta1
kind: KafkaSource
metadata:
  name: order-events-source
spec:
  consumerGroup: knative-order-consumer
  bootstrapServers:
    - kafka-cluster:9092
  topics:
    - order-events
  sink:
    ref:
      apiVersion: eventing.knative.dev/v1
      kind: Broker
      name: default
  # 소비자 설정
  initialOffset: latest
  consumers: 3

Kafka 토픽의 메시지가 CloudEvents로 변환되어 Broker에 전달되고, Trigger 필터를 통해 적절한 Knative Service로 라우팅된다.

실전 운영 패턴과 주의점

패턴 설명 적용 시점
minScale: 1 콜드 스타트 제거, 항상 1개 Pod 유지 지연 민감 API (p99 < 200ms)
target-burst-capacity Activator 버퍼링으로 급증 흡수 트래픽 스파이크가 잦은 서비스
Revision GC 오래된 리비전 자동 정리 빈번한 배포 환경
DomainMapping 커스텀 도메인 매핑 프로덕션 도메인 연결
Kafka Channel InMemory 대신 Kafka 기반 채널 프로덕션 이벤트 안정성

Knative vs 전통 K8s Deployment

항목 K8s Deployment + HPA Knative Serving
Scale-to-Zero 불가 (최소 1 Pod) 네이티브 지원
스케일링 지표 CPU/메모리 중심 동시 요청 수 (concurrency)
리비전 관리 수동 (ReplicaSet) 자동 불변 리비전
트래픽 분할 Istio/Ingress 별도 설정 ksvc 스펙에 선언적
적합한 워크로드 상시 실행 서비스 이벤트/요청 기반, 간헐 트래픽

마무리

Knative는 K8s 위에서 서버리스의 핵심 가치 — scale-to-zero, 이벤트 드리븐, 선언적 트래픽 관리 — 를 벤더 종속 없이 실현한다. 상시 트래픽이 있는 서비스에는 과잉이지만, 간헐적 트래픽의 마이크로서비스나 이벤트 처리 파이프라인에서는 인프라 비용을 극적으로 절감할 수 있다. FluxCD GitOps와 결합하면 Knative Service의 선언적 배포를 자동화할 수 있고, Gateway API HTTPRoute와 함께 사용하면 더 세밀한 트래픽 제어가 가능하다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux