Knative 接入 Kubernetes Gateway API:net-gateway-api 安装与外部/本地网关配置实战

原创2026-10-13 19:56:501,712 阅读
文章标签:文档教程云原生

Knative 接入 Kubernetes Gateway API:net-gateway-api 安装与外部/本地网关配置实战

本文基于 Knative 官方文档的 Gateway API 网络层安装流程,系统讲解如何为 Knative Serving 安装并启用 net-gateway-api 控制器,通过 config-gateway ConfigMap 配置面向外部(north-south)与集群本地(east-west)两类流量的 Gateway 资源,并切换到 gateway-api.ingress.networking.knative.dev 入口类,最终完成 DNS 指向。读完本文,你将掌握在已有 Gateway API 实现的集群上,用 YAML 方式快速接入 Knative Gateway API 网络层的完整实战路径,并理解其底层 KIngress → Gateway/HTTPRoute 的转换原理。

功能状态与前置条件

net-gateway-api 是 Knative 的 Gateway API 网络层实现,当前处于 beta 阶段,API 与配置细节在未来版本中仍可能发生变化。Knative 团队目前针对 Istio、Contour 与 Envoy Gateway 三种 Gateway API 实现进行测试,因此在生产环境落地前,建议先确认所用实现与 Knative 版本的兼容性(可参见 net-gateway-api 仓库中的 test-version 文档)。

安装 Gateway API 网络层前,集群必须满足以下条件:

  1. 已安装一个 Gateway API 实现。Knative 只负责自己的网络层控制器,不会替你安装底层数据面;Gateway API 的流量转发能力由 Istio、Contour、Envoy Gateway 等实现提供。
  2. 已部署 Kubernetes Gateway API 的 CRD(GatewayClass、Gateway、HTTPRoute 等)。多数 Gateway API 实现会随安装一并提供 CRD,未安装时需先补齐。
  3. 已完成 Knative Serving 核心组件安装,即已应用 serving-crds.yaml 与 serving-core.yaml(具体安装步骤见 install-serving-with-yaml.md)。

第一步:安装 Knative Gateway API 控制器

通过 kubectl apply 直接应用 net-gateway-api 的发布清单:

kubectl apply -f {{ artifact(repo="net-gateway-api",org="knative-extensions",file="net-gateway-api.yaml") }}

清单中的 {{ artifact(...) }} 是 Knative 文档站点使用的模板宏,构建时会自动解析为与当前文档版本匹配的发布文件下载地址。该宏的实现位于仓库 hack/macros.py:当环境变量 KNATIVE_VERSION 为空时指向 knative-nightly 的 nightly 构建,否则按语义化版本匹配 knative-extensions/net-gateway-api 仓库中对应 tag 的发布文件。

应用完成后,可以在 knative-serving 命名空间看到形如 net-gateway-api-* 的控制器 Pod(与 Kourier 的 kourier-control-*、Contour 的 contour-*、Istio 的 istio-webhook-* 命名习惯一致,参见 config-network-adapters.md 中的 "Ascertain status and settings" 一节):

kubectl get pods -n knative-serving

第二步:配置 config-gateway 网关映射

net-gateway-api 控制器不会自动发现集群中的 Gateway,它通过 knative-serving 命名空间下的 config-gateway ConfigMap 获知"该用哪些 Gateway 承载 Knative 流量"。Knative 假定集群中存在两类 Gateway:

  • external-gateways(外部/南北向):承接来自集群外的流量;
  • local-gateways(内部/东西向):承接集群内本地流量,例如通过 networking.knative.dev/visibility=cluster-local 标记的私有服务(详见 private-services.md)。

如果不需要为本地流量单独划分 Gateway,也可以只配置外部 Gateway,让其同时承担两类流量。

Knative 在匹配流量时会综合校验三个维度:Gateway 所在的 Kubernetes 命名空间、Gateway 资源自身的名称,以及 Gateway 对应的底层 DNS 名称(通常是一个 Kubernetes Service 的 FQDN,例如 xxx.svc.cluster.local)。

以下命令创建一个同时声明外部与本地网关的 config-gateway ConfigMap:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-gateway
  namespace: knative-serving
data:
  external-gateways: |
    - name: knative-ingress-gateway  # Name of the external Gateway resource
      namespace: knative-serving     # Namespace where the Gateway is deployed
      service: knative-ingress-service.knative-serving.svc.cluster.local  # backing Service FQDN
  local-gateways: |
    - name: knative-local-gateway    # Name of the local Gateway resource
      namespace: knative-serving     # Namespace where the Gateway is deployed
      service: knative-local-service.knative-serving.svc.cluster.local    # backing Service FQDN
EOF

字段含义说明:

  • name:集群中实际存在的 Gateway 资源名,必须与 kubectl get gateway 看到的名称一致;
  • namespace:该 Gateway 资源所在的命名空间;
  • service:Gateway 底层承载流量转发的数据面 Service 的 FQDN,必须写全限定域名(FQDN),例如 istio-ingressgateway.istio-system.svc.cluster.local 或 knative-external.eg-external.svc.cluster.local。

在更完整的 Gateway API 配置(例如 Istio 实现)中,config-gateway 还支持 class(对应的 GatewayClass 名称)与 supported-features(控制器可用的功能特性,如 HTTPRouteRequestTimeout)字段,完整示例可参考 config-network-adapters.md 的 "Gateway configurations" 一节。

第三步:切换 Knative Serving 入口类

config-network ConfigMap 中的 ingress-class 键决定了 Knative Serving 将 KIngress 对象交给哪个网络层控制器处理。将其切换为 Gateway API 入口类:

kubectl patch configmap/config-network \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"ingress-class":"gateway-api.ingress.networking.knative.dev"}}'

需要注意,config-network 中可能存在两个历史键:带连字符的 ingress-class 与带点号的 ingress.class。带连字符的 ingress-class 是更现行、优先级更高的写法,会覆盖点号写法。若集群中同时存在,务必以 ingress-class 为准(这一点同样适用于切换 Kourier、Contour、Istio 等其他入口类,见 config-network-adapters.md 的 "Changing the controller" 一节)。

每个网络层控制器只处理标注了对应入口类的 KIngress 对象,切换入口类后,已有 Route 对应的 KIngress 将由新控制器接管。需要提示的是:对已存在的 Route 修改入口类可能产生未定义行为,建议在切换后对路由进行验证。

第四步:验证网关配置

使用 kubectl describe 检查 config-gateway 的实际生效值:

kubectl describe configmaps config-gateway -n knative-serving

重点核对 external-gateways 与 local-gateways 两个键下的 name、namespace、service 是否与集群中真实存在的 Gateway 资源及其底层 Service 完全一致。任何一处不匹配都会导致流量无法正确路由。

第五步:获取外部 IP 并配置 DNS

查询集群中所有 Gateway 资源的状态与地址信息:

kubectl get gateway --all-namespaces

在输出中找到外部 Gateway(如 knative-ingress-gateway),记录其 STATUS 中的地址(LoadBalancer IP 或 CNAME),作为后续配置 DNS 记录的依据。DNS 解析完成后,Knative 服务即可通过域名对外访问;在配置 DNS 之前,也可以先用 curl 配合 Host 请求头验证流量已到达服务。

底层原理:KIngress 到 Gateway/HTTPRoute 的转换

从架构角度看,net-gateway-api 与 Kourier、Contour、Istio 走的是同一条抽象路径:Knative Serving 控制器将 Route 对象转换为 networking.internal.knative.dev 的 KIngress 对象,再由各个网络层控制器消费 KIngress 并编程底层数据面。Gateway API 网络层的独特之处在于其落地对象是标准化的 Gateway API 资源:

  1. net-gateway-api 控制器读取 Knative 生成的 KIngress 对象;
  2. 根据 config-gateway 中的映射,更新或创建集群中的 Gateway 资源;
  3. 为每条路由创建 HTTPRoute,将其挂接到对应的 Gateway 上;
  4. 底层的 Gateway API 实现(Contour、Istio、Envoy Gateway 等)通过各自的 GatewayClass 控制器消费 Gateway 与 HTTPRoute,最终完成流量转发。

上述完整架构图(包括 net-gateway-api、Gateway、HTTPRoute 与底层实现之间的关系)可在 config-network-adapters.md 的 Gateway API 小节中查看。Knative 同时设计为支持将 Gateway API 策略(policy)附加到 Knative 创建的 HTTPRoute 以及管理这些路由的既有 Gateway 资源上,便于与平台既有的 Gateway API 治理体系协同。

补充:通过 Knative Operator 声明式启用 Gateway API

除 YAML 直装方式外,从 Knative v1.22 起,Knative Operator 也支持将 net-gateway-api 作为 Serving 的入口选项,通过 KnativeServing CR 声明式管理:安装网络层、设置入口类、把网关配置写入 config-gateway 全部由 Operator 完成。

最小化的 KnativeServing 配置只需启用 Gateway API 插件并指定入口类:

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: knative-serving
  namespace: knative-serving
spec:
  ingress:
    gateway-api:
      enabled: true
  config:
    network:
      ingress-class: "gateway-api.ingress.networking.knative.dev"

需要注意的是,若省略 spec.config.gateway,net-gateway-api 会回退到内置的 Istio 风格网关名(istio-system/knative-gateway 与 istio-system/knative-local-gateway),仅当你的 Gateway API 实现恰好提供这些资源时才有效。对 Envoy Gateway、Contour 或自定义网关名,必须显式配置 spec.config.gateway,其键格式与直装方式下的 config-gateway 一致(class、namespace/name 形式的 gateway 与 service,以及可选的 supported-features),完整示例见 configuring-serving-cr.md 的 "Configure the Gateway API ingress" 一节,更多实战演示可参考博客 gateway-api-ingress-with-knative-operator.md。

常见问题与注意事项

  • 实现版本兼容性:net-gateway-api 是 beta 特性,且 Knative 仅对 Istio、Contour、Envoy Gateway 三种实现做过测试;例如 Knative v1.22 发布时即针对 Gateway API v1.4.1、Istio v1.28.2、Contour v1.33.1 与 Envoy Gateway v1.6.2 验证(见 announcing-knative-v1-22-release.md)。请以实际部署版本对应的测试矩阵为准。
  • Service 命名约定差异:Istio 的 Gateway API 实现会按 <gateway-name>-istio 的命名约定创建底层 Service,配置 service 字段时务必与实际 Service 名保持一致。
  • class、gateway、service 必须一致:这些值必须与集群中真实的 GatewayClass、Gateway 和 Service 资源名逐一对应,否则控制器无法建立有效的流量路径。
  • 多网络层共存:集群中可同时安装多个入口控制器,但每个控制器只接管标注了自己入口类的 KIngress;也可通过 Service 级自定义入口类注解实现按服务分流(详见 config-network-adapters.md)。
  • 大集群规模评估:对于拥有大量 Knative Service 的集群,Gateway API 网络层可能遇到规模限制,建议先在小规模集群验证性能表现再推广。
登录后查看全文
docs