Skip to content

Knative Serving v1.23.0 部署文档(uat1 / 192.168.122.31)

  • 日期:2026-08-05
  • 目标集群:uat1,API Server 192.168.122.31,RKE2 v1.35.6+rke2r1,6 节点(3 master+worker / 3 worker)
  • 组件:Knative Serving v1.23.0 + net-kourier v1.23.0(官方 release YAML,不含 Eventing)
  • 目标仓库:Harbor 192.168.122.156:30000,项目 knative(HTTP 明文,节点 containerd 已配 insecure)
  • 镜像源:DaoCloud gcr.m.daocloud.io/knative-releasesdocker.m.daocloud.io
  • 结果:8 个镜像全部同步;Serving + Kourier 部署成功;端到端路由、KPA 扩容、缩容到零、冷启动唤醒、Prometheus 监控全部验证通过

1. 背景与架构

内网/离线集群无法直接访问 gcr.io(Knative 镜像唯一官方源)与 GitHub Release,需要:

  1. gh-proxy.com 下载官方 release YAML;
  2. 经 DaoCloud 镜像站拉取 gcr.io/docker.io 镜像,推送内网 Harbor;
  3. 离线化 YAML(registry 替换 + Kourier svc 改 ClusterIP)后部署;
  4. 复用集群现有 Traefik(DaemonSet,hostPort 80/443)做泛域名入口,不引入 MetalLB。
客户端(内网)
   │  HTTP :80  Host: <svc>-<ns>.knative.ai-ear.cn

任一节点 hostPort 80 → Traefik(DaemonSet)
   │  IngressRoute:HostRegexp(`^[a-z0-9-]+\.knative\.ai-ear\.cn$`)

svc/kourier(ClusterIP,kourier-system)

Activator(副本=0 时接管并缓存请求)/ queue-proxy sidecar → Revision Pod(KPA 0↔N 自动伸缩)

版本依据:Knative v1.23.0 发布于 2026-07-28,最低 K8s 1.34,EOL 2027-02-02,为社区支持期内最新版,兼容本集群 v1.35.6。

2. 前置条件

bash
export KUBECONFIG=~/.kube/config-122.31
kubectl get nodes                 # 能列出 6 个节点
skopeo login --tls-verify=false -u admin -p "$HARBOR_PASSWORD" 192.168.122.156:30000
  • 节点 containerd 已将 192.168.122.156:30000 配为 HTTP insecure registry(本集群 ES/MySQL 已在用,无需再配)。
  • 本机可达 gh-proxy.com(GitHub 代理)与 *.m.daocloud.io

3. 下载 release 与提取镜像清单

bash
BASE="https://gh-proxy.com/https://github.com"
curl -sL -o serving-crds.yaml "$BASE/knative/serving/releases/download/knative-v1.23.0/serving-crds.yaml"
curl -sL -o serving-core.yaml "$BASE/knative/serving/releases/download/knative-v1.23.0/serving-core.yaml"
curl -sL -o kourier.yaml      "$BASE/knative-extensions/net-kourier/releases/download/knative-v1.23.0/kourier.yaml"

# 提取全部镜像(注意 net-kourier 的镜像在 kourier.yaml 中,勿漏)
grep -hoE 'image: [^ ]+' serving-core.yaml kourier.yaml | awk '{print $2}' | grep -v disabled | sort -u > images.txt

v1.23.0 共 7 个镜像(5 个 serving digest 固化 + 1 个 net-kourier + 1 个 envoy),另有验证示例 knative-samples/helloworld-go

4. 镜像同步到 Harbor

bash
# 创建项目(已存在返回 409,忽略)
curl -s -X POST -u "admin:$HARBOR_PASSWORD" -H 'Content-Type: application/json' \
  -d '{"project_name":"knative","public":true}' \
  "http://192.168.122.156:30000/api/v2.0/projects"

./sync-images.sh        # 全程约 40 分钟(镜像站限速,单镜像 5-8 分钟)

digest 处理:官方 YAML 用 repo@sha256:<hex> 固化镜像;同步时以 digest 前 16 位为 tag 推 Harbor(如 cmd/controller:ca5062ece0329d00),离线 YAML 同步改写为 tag 引用,规避 skopeo 1.4.1 attestation 层导致 digest 变化的问题。

踩坑记录:

问题现象解法
skopeo 1.4.1 处理 attestation 层失败unsupported MIME type ... in-toto+json(helloworld-go 命中)脚本自动 fallback:--override-os linux --override-arch amd64 单架构复制(集群全 amd64)
Harbor API 查 artifact 404 假象仓库名含多级 /repository_name 需双重 URL 编码(/%252F)
gcr 镜像无 tag 列表skopeo list-tags 返回空直接按 digest 复制,无需 tag

校验(缺失必须为 0):

bash
# 逐镜像 artifact 级校验,详见 rancher/knative-1.23.0-images-offline-sync.md
缺失: 0 / 8

5. 离线化与安装

bash
# 已由仓库内文件完成:serving-core-offline.yaml / kourier-offline.yaml
# 重新生成方法:
sed -E "s|gcr\.io/knative-releases/(knative\.dev/[a-z0-9/._-]+)@sha256:([0-9a-f]{16})[0-9a-f]*|192.168.122.156:30000/knative/\1:\2|g" serving-core.yaml > serving-core-offline.yaml
sed -E -e "s|gcr\.io/knative-releases/...|...|" \
       -e "s|docker\.io/envoyproxy/envoy|192.168.122.156:30000/knative/envoyproxy/envoy|g" \
       -e "s|^  type: LoadBalancer$|  type: ClusterIP|" kourier.yaml > kourier-offline.yaml

# 一键部署(CRDs → core → kourier → 最佳实践配置 → HA → 入口 → 监控)
./deploy.sh            # 首次已同步镜像则直接部署;./deploy.sh --sync 含镜像同步

关键部署细节:

  1. Kourier svc 改 ClusterIP:官方默认 LoadBalancer(集群无 MetalLB 会 Pending),由 Traefik 转发后无需 LB。
  2. net-kourier-controller 在 knative-serving 命名空间(不在 kourier-system),等待 readiness 时注意。
  3. config-deployment.queue-sidecar-image 必须随离线化同步改写:它是所有 Revision 注入的 queue-proxy sidecar 镜像,config-knative.yaml 中已固化为 Harbor 地址,遗漏会导致全部业务 Pod ImagePullBackOff。
  4. registries-skipping-tag-resolving: 192.168.122.156:30000:Knative controller 解析镜像 tag→digest 只走 HTTPS,对 HTTP Harbor 必失败,跳过解析绕过。

6. 最佳实践配置说明(config-knative.yaml)

ConfigMap关键项说明
config-domainknative.ai-ear.cn默认域名所有 ksvc 的 URL 后缀
config-networkdomain-template{{.Name}}-{{.Namespace}}.{{.Domain}}改单级子域,泛域名匹配/未来泛证书可覆盖(默认两级 name.ns.domain)
config-networkautocreate-cluster-domain-claims"false"防止普通用户抢占域名
config-deploymentregistries-skipping-tag-resolvingHarbor 地址见上
config-deploymentqueue-sidecar-imageHarbor queue 镜像见上
config-defaultsrevision-timeout-seconds300请求最长 5 分钟
config-autoscalercontainer-concurrency-target-default100KPA 目标并发
config-autoscalerenable-scale-to-zero"true"缩容到零(UAT 省资源;低延迟敏感业务用 min-scale=1 覆盖)
config-autoscalerstable-window / scale-to-zero-grace-period60s / 30s缩容窗口
config-gcmin-non-active-revisions10 / 48h / 24h非活跃 Revision 回收,保留最近 10 个便于回滚
config-observabilitymetrics-protocol"prometheus"v1.23 默认为 none,不显式开启则 9090 无指标
config-observabilityrequest-metrics-protocol"prometheus"queue-proxy 请求指标(见已知限制)

HA(deploy.sh 步骤 6):

  • controller/autoscaler 无 HPA,直接 scale --replicas=2(leader election 保证安全);
  • activator/webhook/kourier-gateway 官方自带 HPA(min=1),手工 scale 会被 HPA 缩回,必须 kubectl patch hpa ... minReplicas=2;
  • 全部组件配 PDB(minAvailable=1),activator 在缩零流量路径上,生产必须 ≥2 副本。

7. 入口(Traefik 泛域名)

traefik-ingressroute.yaml(放 kourier-system,规避跨命名空间引用):

yaml
metadata:
  annotations:
    kubernetes.io/ingress.class: traefik    # 必须!RKE2 Traefik 启用了 --providers.kubernetescrd.ingressClass=traefik
spec:
  entryPoints: [web]
  routes:
    - match: HostRegexp(`^[a-z0-9-]+\.knative\.ai-ear\.cn$`)
      services: [{name: kourier, port: 80}]

踩坑记录(本环境实测):

问题现象解法
IngressRoute 缺 ingress.class 注解Traefik 不接收,404kubernetes.io/ingress.class: traefik(或 spec.ingressClassName)
Traefik v3 HostRegexp 语法{subdomain:[a-z-]+}.domain(v2 花括号语法)路由 enabled 但不匹配,404v3 默认 ruleSyntax 下直接写纯正则:HostRegexp(^[a-z0-9-]+.knative.ai-ear.cn$)

DNS:内网 DNS 添加泛解析 *.knative.ai-ear.cn → 192.168.122.31(或各节点 IP 轮询/前置 LB VIP);未配 DNS 时用 curl -H 'Host: <svc>-<ns>.knative.ai-ear.cn' http://<节点IP>/

HTTPS 升级路径:申请 *.knative.ai-ear.cn 证书后,IngressRoute 复制一条 entryPoints: [websecure] + tls.secretName 即可(现有 DigiCert 证书仅覆盖 ai-ear.cn/www.ai-ear.cn,不含泛域名)。

8. 监控接入

config-observability.metrics-protocol: prometheus 开启后,controller/webhook/autoscaler/activator 在 9090 端口暴露指标;rancher-monitoring 的 serviceMonitorSelector: {}(全匹配),servicemonitor.yaml apply 后即被发现(实测 8 个 target 全 up)。

Grafana 常用指标:kn_revision_pods_desiredkn_revision_concurrency_stablekn_revision_panic_modekn_activator_request_countkn_autoscaler_scrape_duration_seconds

已知限制:v1.23 queue-proxy 请求级指标的 prometheus 拉取未生效(OTel 迁移过渡期);切勿设置 request-metrics-endpoint: 0.0.0.0:9090 —— 会与 queue-proxy 自带 metrics server 冲突导致所有 Revision Pod CrashLoopBackOff(bind: address already in use,本环境实测)。需要请求级指标时建议部署 OTel Collector 接收 OTLP 推送(request-metrics-protocol: http/protobuf)。

9. 端到端验证(本次实测结果)

bash
kubectl apply -f examples/helloworld.yaml
kubectl wait --for=condition=Ready ksvc/helloworld-go --timeout=240s
# URL: http://helloworld-go-default.knative.ai-ear.cn   READY True

# ① 路由:6 个节点 hostPort 80 全部返回 "Hello Knative v1.23 on uat1!"
curl -H 'Host: helloworld-go-default.knative.ai-ear.cn' http://192.168.122.31/

# ② KPA 扩容:30 并发持续压测(target=10),Pod 1 → 2
# ③ 缩容到零:停止流量约 70s 后 Pod = 0(activator 接管)
# ④ 冷启动:首个请求 10.7s 唤醒(镜像已缓存),后续毫秒级
# ⑤ 监控:Prometheus 8 个 knative target 全部 up

10. 生产注意事项

  1. 资源:Serving 控制面 2 副本约需 1C2G;KPA 扩容会快速消耗 worker 资源,关注 max-scale 与集群水位。
  2. 低延迟业务:缩零冷启动 5-15s(镜像预热后可降至 ~2s),敏感服务加注解 autoscaling.knative.dev/min-scale: "1"
  3. queue-proxy 资源:默认无限制,可通过 config-deploymentqueue-sidecar-* 键统一设 requests/limits。
  4. 升级:Knative 不支持跨 2 个以上小版本升级;v1.23 → v1.24 时按同样流程重新同步镜像、按序 apply 新 YAML。
  5. Revision 清理:config-gc 已限制非活跃版本,仍需关注 etcd 中 Revision 对象数量。

11. 卸载(回滚)

bash
kubectl delete -f examples/helloworld.yaml
kubectl delete -f servicemonitor.yaml -f traefik-ingressroute.yaml
kubectl delete -f kourier-offline.yaml
kubectl delete -f serving-core-offline.yaml
kubectl delete -f serving-crds.yaml    # 危险:级联删除所有 ksvc/Revision,确认后再执行
kubectl delete ns knative-serving kourier-system