Knative 实战:Kubernetes 上的 Serverless 弹性工作负载

当你的 Kubernetes 集群里跑着几十个常驻 Pod,但流量只在白天出现时,空闲资源就是实打实的成本。Knative 是一套构建在 Kubernetes 之上的 Serverless 编排框架,它让无状态服务能够按请求自动扩缩容、并在无流量时缩容到零,有请求再来时秒级冷启动。本文从组件原理到本地部署,带你把 Knative 真正跑在 Kubernetes 上。

一、为什么需要 Knative:从常驻 Pod 到缩容到零

传统 Deployment 无论如何都要保留至少一个副本,而 Knative 的 Serving 组件引入了「缩容到零(scale-to-zero)」能力:流量归零后 Pod 完全释放,只保留一个轻量的 Activator 等待请求;新请求到达时再拉起 Pod 并完成冷启动。对定时任务型、流量波峰波谷明显的服务,这能直接砍掉 30%–70% 的闲置算力开销。

如果你已经在用 k3s 搭建轻量 Kubernetes 集群,或靠 Karpenter 做节点弹性伸缩,Knative 补上的正是「工作负载层」的弹性——节点伸缩解决「有没有机器」,Knative 解决「Pod 该不该存在」。

举个真实场景:一个内部报表服务每天只在 09:00–18:00 被调用,其余 15 小时几乎零流量。用 Deployment 保底 2 副本,等于为「一天只用三分之一时间」的服务付 100% 费用;改用 Knative 后,非工作时段 Pod 缩容到零,月度算力账单可下降约 60%。这还不包括副本减少带来的内存占用与 kube-apiserver 负载压力下降。对测试环境、演示环境这类「白天用、夜里空转」的集群,收益更明显。

二、核心组件:Serving 与 Eventing

2.1 Serving:Revision、Configuration、Route、Service

Serving 用四个 CRD 描述一个服务:Configuration 定义期望的 Pod 模板;每次变更会生成不可变的 Revision;Route 把流量路由到某个 Revision(支持按比例切流做灰度);顶层的 Service 把 Configuration 与 Route 绑在一起。这种「每次发布都是新 Revision」的模型,天然支持蓝绿与金丝雀。

2.2 Eventing:事件驱动与 Broker/Trigger

Eventing 提供基于 CloudEvents 的事件总线。你用 Broker 收事件、用 Trigger 按过滤条件把事件投递给 Knative Service,从而把「收到消息才跑一次」的函数式场景落地——这正是 Serverless 的另一半价值。

三、快速上手:本地装 Knative

以下以 k3s 或任意已就绪集群为例。先装 Serving 核心与 Kourier 网关:

# 安装 Knative Serving
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.15.0/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.15.0/serving-core.yaml

# 安装 Kourier 网络层(轻量、适合自托管)
kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.15.0/kourier.yaml
kubectl patch configmap/config-network \
  -n knative-serving \
  --type merge \
  -p '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'

完成后 kubectl get pods -n knative-serving 应全部 Running。想用eventing 再 apply eventing-crds / eventing-core 即可。需要本地起集群可参考 k3s 实战 一把梭。

安装完成后用 kubectl get ksvc hello -o jsonpath='{.status.url}' 即可拿到服务地址。本地没有 LoadBalancer 时,可借 Nginx 反向代理 把 Kourier 入口暴露到公网域名;生产集群则建议直接挂云厂商 LB 或 Contour/Istio 入口网关,配合 HTTPS 证书统一管理。

四、部署第一个 Serverless 服务

最简洁的方式是用 kn CLI 直接创建一个服务,也可以写 YAML 交给 GitOps:

kn service create hello \
  --image gcr.io/knative-samples/helloworld-go:latest \
  --port 8080 \
  --revision-name hello-v1

等价 YAML(适合 GitHub Actions 流水线下发):

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hello
  namespace: default
spec:
  template:
    spec:
      containers:
        - image: gcr.io/knative-samples/helloworld-go:latest
          ports:
            - containerPort: 8080
          env:
            - name: TARGET
              value: "Knative"

五、自动扩缩容与缩容到零

Knative 内置基于请求的自动扩缩容器(KPA)。通过注解即可调行为:

metadata:
  annotations:
    # 单个 Revision 最多并发 100 请求
    autoscaling.knative.dev/target: "100"
    # 最小保留 0 个副本(缩容到零)
    autoscaling.knative.dev/min-scale: "0"
    # 最多 10 个副本
    autoscaling.knative.dev/max-scale: "10"
    # 无流量后 30 秒缩容到零
    autoscaling.knative.dev/scale-to-zero-grace-period: "30s"
注解作用常用值
target单副本并发目标10 / 50 / 100
min-scale最小副本数0(省成本)/ 1(保低延迟)
max-scale最大副本数10 / 50
scale-to-zero-grace-period缩零宽限期30s

六、Eventing 实战:事件触发函数

创建一个 Broker 并用 Trigger 把事件路由到上面的 hello 服务:

apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  name: default
  namespace: default
---
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: hello-trigger
  namespace: default
spec:
  broker: default
  filter:
    attributes:
      type: dev.knative.samples.hello
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: hello

这样任何发往 Broker、type 匹配的 CloudEvent 都会自动唤醒 hello 服务——即便它此刻已缩容到零。

Knative 还提供 Event Sources(如 KafkaSource、GitHubSource、ContainerSource)把外部系统的事件「喂」进 Broker。例如 KafkaSource 能把某个 topic 的消息自动转成 CloudEvent 投递,实现「消息到达即触发函数」的流式 Serverless;GitHubSource 则可在代码推送时唤醒构建服务。配合 GitHub Actions 做 CI、再用 Eventing 做 CD 触发,能拼出完整的事件驱动流水线。

七、与云原生生态协同

Knative 不是孤岛。它和 Kubernetes 基础、Prometheus 监控、Nginx 反向代理 都能自然配合:用 Prometheus 采集 Knative 的扩缩容指标做告警,用入口网关统一暴露服务。当流量真把 Pod 打满时,再交给 Karpenter 扩容节点——两层弹性叠加才是完整的成本优化闭环。

成本侧也值得关注:当 Knative 把副本缩到零,节点利用率上升,Karpenter 便可顺势回收闲置节点,形成「Pod 缩零 → 节点缩容」的连锁省钱效应。再叠加 Prometheus 的扩缩容指标看板,你既能看清弹性是否生效,也能用数据向老板证明降本成效。

八、生产落地检查清单

项建议
入口网关生产用 Contour/Istio,Kourier 适合中小集群
冷启动优化镜像瘦身、配置 min-scale≥1 保热
并发模型多路复用服务设高 target,重服务设低 target
可观测接入 Prometheus + 分布式追踪
发布策略用 Revision + 按比例 Route 做金丝雀

九、常见误区与排障

现象根因处理
请求 502/超时冷启动慢于默认 10s 宽限调大 revision 的 timeout / 提高 min-scale
始终不缩容到零有健康检查或长连接保活确认无后台常驻连接
网关不通ingress-class 未匹配检查 config-network 的 ingress-class
事件不触发Trigger filter 不匹配核对 CloudEvent type/attributes

十、Knative 与 Deployment + HPA 的本质区别

很多人会问:Kubernetes 自带 HPA(Horizontal Pod Autoscaler),为什么还要 Knative?核心差别在「缩容下限」与「扩缩依据」。HPA 默认按 CPU/内存扩缩,且 production 环境几乎不会把 minReplicas 设为 0(否则流量来了要等冷启动、还可能误判);Knative 的 KPA 直接以「请求并发数(RPS)」为信号,并把缩容到零作为一等公民支持。此外每次发布生成不可变 Revision,让灰度与回滚变得原子化。

维度Deployment + HPAKnative Serving
缩容下限通常 ≥1可到 0
扩缩依据CPU / 内存请求并发 RPS
冷启动无有,需优化
发布模型滚动更新不可变 Revision + 按比例路由
典型适用长期稳定服务波峰波谷 / 事件驱动

结论很清晰:稳态常驻服务用 HPA 足够;真正能省钱的「缩容到零」场景,才是 Knative 的主场。两者并不互斥——同一集群里可以一部分服务跑 HPA、一部分跑 Knative,按流量特征各取所需。

十一、结语

Knative 把 Serverless 的弹性与 Kubernetes 的通用性结合,让「按需运行、缩容到零」从概念变成一条 YAML。它适合流量不均的 Web 服务、事件驱动的后台任务,也是你从「常驻资源」走向「按量计费」的关键一步。下一篇可以聊聊它与 Dapr 在微服务侧的分工差异。

上一篇 Java FFM API 实战:用 Panama 安全调用本地代码
下一篇 CrashLoopBackOff 排查实战:K8s 容器重启循环
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]