Kubernetes无服务器运行时
Knative 在 Kubernetes 之上提供无服务器(Serverless)能力,最核心的特性是按请求自动伸缩,并且可以缩容到零。它由两大部分组成:
Serving 的对象模型:
serving.knative.dev/v1) —— 面向使用者的入口,一次声明「镜像 + 版本 + 流量」。伸缩由 KPA(Knative Pod Autoscaler) 负责,它支持缩容到零,这是与原生 HPA 最大的区别。
# 1. 安装 CRD
kubectl apply -f \
https://github.com/knative/serving/releases/download/knative-v1.21.3/serving-crds.yaml
# 2. 安装核心组件
kubectl apply -f \
https://github.com/knative/serving/releases/download/knative-v1.21.3/serving-core.yaml
# 3. 安装网络层:Kourier(注意仓库已迁到 knative-extensions)
kubectl apply -f \
https://github.com/knative-extensions/net-kourier/releases/download/knative-v1.21.1/kourier.yaml
# 4. 把 Kourier 设为默认 Ingress 实现
kubectl patch configmap/config-network \
--namespace knative-serving \
--type merge \
--patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'
# 5. 验证
kubectl get pods --namespace knative-serving
kubectl get pods --namespace kourier-system
# 6. 取得网络层入口地址(用于配置 DNS)
kubectl --namespace kourier-system get service kourier
Knative 需要一个域名才能生成可访问的 URL。两种做法:
# 方式一:Magic DNS(用 sslip.io 自动解析,仅测试用)
kubectl apply -f \
https://github.com/knative/serving/releases/download/knative-v1.21.3/serving-default-domain.yaml
# 方式二:用自己的域名(需要把 DNS 指向网络层入口)
kubectl patch configmap/config-domain \
--namespace knative-serving \
--type merge \
--patch '{"data":{"knative.example.com":""}}'
# 完全不配 DNS 时,可以先用占位域名
kubectl patch configmap/config-domain \
--namespace knative-serving \
--type merge \
--patch '{"data":{"example.com":""}}'
# macOS
brew install knative/client/kn
# Linux:从 Releases 下载后改名并放入 PATH
curl -LO https://github.com/knative/client/releases/latest/download/kn-linux-amd64
chmod +x kn-linux-amd64
sudo mv kn-linux-amd64 /usr/local/bin/kn
# 注意二进制名是 kn-linux-amd64 / kn-darwin-amd64,没有 kn-macos-amd64
# 也可以用容器运行
docker run --rm -v "$HOME/.kube/config:/root/.kube/config" \
gcr.io/knative-releases/knative.dev/client/cmd/kn:latest service list
kn version
# 创建服务
kn service create hello \
--image ghcr.io/knative/helloworld-go:latest \
--env TARGET="Knative" \
--port 8080 \
--scale-min 0 \
--scale-max 10
# 查看
kn service list
kn revision list
kn route list
# 访问
curl http://hello.default.knative.example.com
# 更新:会产生一个新的 Revision
kn service update hello --env TARGET="v2"
# 流量切分:旧版本 90%,新版本 10%
kn service update hello \
--traffic hello-00001=90 \
--traffic @latest=10
# 删除
kn service delete hello
kn service create 的常用参数:--image、--env(-e)、--port(-p)、--annotation(-a)、--revision-name、--cluster-local、--concurrency-limit、--request / --limit、--volume / --mount、--timeout(默认 300 秒)、--wait(默认 true)。
伸缩参数的写法比较特殊,不是 --min-scale:
kn service create hello --image <image> --scale-min 1 --scale-max 20
kn service create hello --image <image> --scale 1..5 # 同时指定上下限
kn service create hello --image <image> --scale-metric concurrency \
--scale-target 50 --scale-utilization 70
按 Revision 打注解可以覆盖自动伸缩行为:
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
metadata:
annotations:
# 缩容到零(默认值即 0)
autoscaling.knative.dev/min-scale: "0"
# 0 表示不限制
autoscaling.knative.dev/max-scale: "20"
# 伸缩指标:concurrency(默认)/ rps / cpu / memory
autoscaling.knative.dev/metric: "concurrency"
# 每个 Pod 的目标并发,默认 "100"
autoscaling.knative.dev/target: "50"
# 目标利用率百分比,默认 70
autoscaling.knative.dev/target-utilization-percentage: "70"
# 缩容前的稳定窗口,默认 60s
autoscaling.knative.dev/window: "60s"
spec:
# 硬限制:与上面的软限制取较小值生效
containerConcurrency: 100
containers:
- image: ghcr.io/knative/helloworld-go:latest
全局默认值在 knative-serving 命名空间的 config-autoscaler ConfigMap 中,重点关注 scale-to-zero-grace-period(默认 30s)与 enable-scale-to-zero(默认 true)。
kubectl edit configmap config-autoscaler -n knative-serving
kubectl edit configmap config-network -n knative-serving
kubectl edit configmap config-domain -n knative-serving
config-domain 时,生成的 URL 落在示例域名上,既解析不了也访问不到;测试环境用 Magic DNS,生产环境要配真实域名并把 DNS 指向网络层入口。min-scale: 1,或适当调大 scale-to-zero-grace-period。kn 的伸缩参数是 --scale-min / --scale-max。没有 --min-scale、--max-scale 这两个参数,照搬注解名的写法会直接报错。target 是软限制,containerConcurrency 是硬限制。两者同时存在时取较小值生效;只想限制上限就设 containerConcurrency,想让调度器按目标值决策就调 target。scale-to-zero-grace-period 只能在全局 ConfigMap 里配置,不能按 Revision 覆盖。LoadBalancer 类型的 Service 暴露 IPv4 地址或主机名;裸机或 minikube 环境需要 minikube tunnel 之类的方案,否则只能靠端口转发访问。metric: cpu 依赖 metrics-server。用并发或 RPS 作为指标不需要,但选 CPU 指标时必须有可用的 metrics-server。knative-serving 命名空间。config-network 管 Ingress 实现、config-autoscaler 管伸缩默认值、config-domain 管域名,改错命名空间不生效。Deploying 或频繁重启。eventing-crds.yaml 与 eventing-core.yaml,并额外部署一个 Broker 实现。kubectl — Kubernetes集群管理工具keda — Kubernetes事件驱动自动伸缩组件hpa — Kubernetes水平自动伸缩ingress — Kubernetes入口资源argo-events — Kubernetes事件驱动自动化框架