当你的 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 + HPA | Knative Serving |
| 缩容下限 | 通常 ≥1 | 可到 0 |
| 扩缩依据 | CPU / 内存 | 请求并发 RPS |
| 冷启动 | 无 | 有,需优化 |
| 发布模型 | 滚动更新 | 不可变 Revision + 按比例路由 |
| 典型适用 | 长期稳定服务 | 波峰波谷 / 事件驱动 |
结论很清晰:稳态常驻服务用 HPA 足够;真正能省钱的「缩容到零」场景,才是 Knative 的主场。两者并不互斥——同一集群里可以一部分服务跑 HPA、一部分跑 Knative,按流量特征各取所需。
十一、结语
Knative 把 Serverless 的弹性与 Kubernetes 的通用性结合,让「按需运行、缩容到零」从概念变成一条 YAML。它适合流量不均的 Web 服务、事件驱动的后台任务,也是你从「常驻资源」走向「按量计费」的关键一步。下一篇可以聊聊它与 Dapr 在微服务侧的分工差异。




