☰
KubeVela gateway 运维特征(Trait)实战:为组件一键暴露公网流量与 Ingress 配置详解
2026/9/28 12:33:39 网站建设 项目流程
  • 云原生
  • DevOps
  • 运维
  • 微服务

【免费下载链接】kubevela

The Modern Application Platform.

项目地址:https://gitcode.com/gh_mirrors/ku/kubevela
点击查看免费下载

导读

gateway是 KubeVela 内置的运维特征(Trait),用于为应用组件暴露公网 HTTP 流量:它会在组件旁自动创建 Service 与 Ingress,并把域名、路径到端口的路由规则声明成一份简洁的应用配置。本文以references/docgen/def-doc/trait/gateway.eg.md中的示例为主线,结合仓库中vela-templates/definitions/internal/trait/gateway.cue的完整定义,逐项讲解 domain、http、class、classInSpec、secretName、pathType、annotations、labels、existingServiceName、gatewayHost 与多网关 name 等参数的用法,并说明网关 Trait 的状态输出、健康检查逻辑及与 K8s 版本适配的底层原理。读完本文,你将掌握在 KubeVela Application 中声明式接入 Ingress 的完整实操方案。

gateway Trait 能做什么

在 KubeVela 中,Trait 是以“组件之上叠加能力”的声明方式存在的运维特征。gatewayTrait 的核心职责是让一个组件可以被公网访问,它同时完成两件事:

  1. 若组件没有对应的 Service,则自动生成一个Service,将组件的工作负载端口暴露出来;
  2. 生成一条Ingress规则,把指定域名(domain)和 HTTP 路径映射到组件端口,由集群内的 Ingress Controller 完成公网流量接入。

从 gateway.cue 的定义可以看到,该 Trait 的应用范围(appliesToWorkloads)限定为deployments.apps与statefulsets.apps两类工作负载,并且podDisruptive: false,即添加、修改该 Trait 不会导致 Pod 被重建,适合在运行期随时调整。

gateway与ingressTrait 功能相近,二者的差别主要在语义与默认行为上:ingress只生成 Ingress 对象,要求组件本身已经具备可访问的 Service(例如由webservice组件自动生成的 Service);而gateway更“重”一些,它会替你补齐 Service 创建这一步,并额外支持existingServiceName复用已有 Service、支持在单个组件上挂载多个网关等场景。

最简示例:一个域名、一条路径

references/docgen/def-doc/trait/gateway.eg.md给出了 gateway Trait 的最小可用示例,直接在 Application 的组件 traits 段声明即可:

apiVersion: core.oam.dev/v1beta1 kind: Application metadata: name: first-vela-app spec: components: - name: express-server type: webservice properties: image: oamdev/hello-world port: 8000 traits: - type: gateway properties: domain: testsvc.example.com http: "/": 8000

将这份 YAML 保存为vela-app.yaml后,通过vela up或kubectl apply -f交付即可。它的效果等价于:

  • 生成一个名为express-server的 Service,把容器端口 8000 暴露出来;
  • 生成一条名为express-server的 Ingress,将http://testsvc.example.com/的流量路由到该 Service 的 8000 端口。

这里只用到两个必填语义:domain(要暴露的域名)和http(路径到端口的路由映射表)。http是一个键值映射,键为 URL 路径,值为工作负载端口,可以一次声明多条,例如同时开放"/": 8000与"/api": 8080。

参数全解:从 domain 到 existingServiceName

对照 gateway.cue 中parameter段的定义,gateway Trait 共支持如下参数:

参数类型必填默认值说明
domainstring否无要暴露的域名,对应 Ingress 规则中的 host;不填则不限定主机名
httpmap[string]int是无HTTP 路径到组件端口的映射关系,如"/": 8000
classstring否"nginx"使用的 Ingress Class,即 Ingress Controller 的名称
classInSpecbool否false为 true 时把 class 写入spec.ingressClassName字段,否则写入kubernetes.io/ingress.class注解
secretNamestring否无引用已有的 TLS Secret 名称,配置后将自动生成 Ingress 的 tls 段
gatewayHoststring否无Ingress 网关的主机名,用于在 host 为空时生成访问端点
namestring否无该网关的唯一名称,用于在一个组件上挂载多个 gateway Trait 时区分彼此
pathTypestring否"ImplementationSpecific"Ingress 路径匹配类型,可选ImplementationSpecific/Prefix/Exact
annotationsmap[string]string否无附加到 Ingress 上的自定义注解
labelsmap[string]string否无附加到 Ingress 上的自定义标签
existingServiceNamestring否无若指定,则复用已有的 Service,不再自动创建 Service

必填项:http 路径映射

http: [string]: int是唯一强制要求提供的参数。它定义了“哪些路径由哪个端口服务”,模板中通过for k, v in parameter.http遍历生成两条关键内容:

  • 自动创建 Service 时,为每个端口生成一条ports项,port与targetPort均为该端口值(见 gateway.cue);
  • 生成 Ingress 规则时,每个路径对应一个http.paths条目,将 path 与后端 Service 端口关联起来(见 gateway.cue)。

域名与 TLS:domain + secretName

domain会写入 Ingress 的spec.rules[].host;当同时提供secretName时,模板会追加spec.tls段,把该域名与指定的 Secret 绑定,从而启用 HTTPS:

traits: - type: gateway properties: domain: testsvc.example.com secretName: my-tls-secret http: "/": 8000

生成的 Ingress tls 段形如:

spec: tls: - hosts: - testsvc.example.com secretName: my-tls-secret

注意:模板只负责引用 Secret,不会创建 Secret,你需要提前在集群中准备好 TLS 证书 Secret。

Ingress Class 的两种声明方式:class 与 classInSpec

Kubernetes 1.19 之后推荐使用spec.ingressClassName字段指定 Ingress Controller,而更早的版本普遍使用kubernetes.io/ingress.class注解。gateway Trait 通过classInSpec参数兼容这两种写法:

  • classInSpec: false(默认):把class值写入注解kubernetes.io/ingress.class;
  • classInSpec: true:把class值写入spec.ingressClassName字段。

对应的模板逻辑位于 gateway.cue 与 gateway.cue。class默认值为"nginx",即默认对接集群内的 NGINX Ingress Controller。

pathType 路径匹配

pathType决定路径的匹配语义,默认ImplementationSpecific(由具体 Ingress Controller 决定匹配规则),可选:

  • ImplementationSpecific:匹配方式由 Ingress Controller 自行实现;
  • Prefix:前缀匹配,如/api可匹配/api/v1;
  • Exact:精确匹配,仅命中完全一致的路径。

该值会被写入每个http.paths[].pathType(见 gateway.cue)。

自定义注解与标签:annotations + labels

Ingress Controller 的许多高级能力(如重写路径、限流、CORS、认证等)依赖注解配置。gateway Trait 允许通过annotations与labels原样透传任意键值对:

traits: - type: gateway properties: domain: testsvc.example.com http: "/": 8000 annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/ssl-redirect: "true" labels: team: frontend

模板会把这些键值逐一写入 Ingress 的metadata.annotations与metadata.labels(见 gateway.cue)。

复用已有 Service:existingServiceName

如果组件已经存在现成的 Service(例如由工作负载定义自带,或希望多个网关共用同一个 Service),可以用existingServiceName直接引用,此时 Trait 不再自动创建 Service:

traits: - type: gateway properties: existingServiceName: my-existing-svc domain: testsvc.example.com http: "/": 8000

模板逻辑在 gateway.cue:只有未指定existingServiceName时才会生成Service输出,且生成的 Service 名称、Ingress 名称都会按规则拼接后缀。

单组件多网关:name 与命名后缀

name参数用于在一个组件上声明多个 gateway Trait。未指定name时,生成的 Service 与 Ingress 名称均为context.name;指定后,名称变为context.name + "-" + name(后缀拼接逻辑见 gateway.cue)。例如一个组件同时暴露业务域名和内部管理域名:

traits: - type: gateway properties: name: public domain: www.example.com http: "/": 8000 - type: gateway properties: name: admin domain: admin.example.com http: "/admin": 8001

此时会生成express-server-service-public、express-server-ingress-public与express-server-service-admin、express-server-ingress-admin两组资源,互不冲突。

gatewayHost:host 为空时的访问端点

gatewayHost用于指定 Ingress 网关的主机名。当domain未设置(host 为空)时,它会被写入ingress.controller/host注解(见 gateway.cue),供上层平台根据该主机名生成可访问的端点地址。

底层原理:Service + Ingress 的生成逻辑

自动生成的 Service

当没有指定existingServiceName时,模板在outputs中生成一个v1/Service,其selector固定为app.oam.dev/component: context.name,即按组件名选择工作负载 Pod;ports则遍历http映射生成,port与targetPort取同一端口值,端口名统一为port-<端口号>(见 gateway.cue)。

自动生成的 Ingress

Ingress 是 gateway Trait 的核心产物,其完整结构由 gateway.cue 生成,要点包括:

  • apiVersion根据集群版本自动选择:context.clusterVersion.minor < 19时使用networking.k8s.io/v1beta1,否则使用networking.k8s.io/v1(兼容 K8s 1.20+ 的标准 API,这也是该定义 description 中“the ingress API matches K8s v1.20+”的由来);
  • metadata.name由组件名与name参数拼接;
  • 注解、标签、tls、rules 均按上文参数规则动态渲染。

状态输出:customStatus 与 healthPolicy

gateway Trait 定义了两段可观测逻辑,帮助vela status与健康检查直接使用:

  • customStatus(gateway.cue):从生成的 Ingress 中提取 LoadBalancer 的 IP 与第一条 rule 的 host。若已获得负载均衡 IP,则输出Visiting URL: <host>, IP: <ip>;若 IP 尚未就绪,则提示“No loadBalancer found, visiting by using 'vela port-forward <应用名>'”,引导用户用端口转发临时访问。
  • healthPolicy(gateway.cue):以“是否已生成对应名称的 Ingress”作为健康判据isHealth,供控制器对应用状态进行聚合判定。

这两段 CUE 定义说明 gateway Trait 与 KubeVela 的应用状态体系深度集成,用户可以借助vela status <应用名>直接看到公网访问入口是否就绪。

与 K8s 版本的适配说明

gateway Trait 对 Kubernetes API 版本的选择是自动的,无需用户干预:

集群版本生成的 Ingress apiVersion
minor < 19(1.18 及更早)networking.k8s.io/v1beta1
minor >= 19(1.19+,含 1.20+)networking.k8s.io/v1

这一判断来自模板中的legacyAPI: context.clusterVersion.minor < 19(gateway.cue),并在生成 backend 时区分两种写法:旧版本使用serviceName/servicePort,新版本使用service.name/service.port.number(见 gateway.cue)。因此,在 K8s 1.20+ 集群上,gateway Trait 生成的是标准networking.k8s.io/v1Ingress;在更早的集群上则自动降级到 v1beta1。

常见场景与排查提示

  • 只想复用已有 Ingress Controller 之外的能力:结合annotations透传 Ingress Controller 特有配置(重写、灰度、限流等),这是让 gateway Trait 与具体网关生态(NGINX、Traefik 等)协同的关键入口。
  • 访问入口迟迟未就绪:执行vela status <应用名>查看状态信息,若提示 “No loadBalancer found”,说明 Ingress Controller 尚未分配负载均衡 IP,可先用vela port-forward <应用名>临时验证服务本身可用;同时确认集群中已部署对应的 Ingress Controller,且class(或classInSpec)与 Controller 名称匹配。
  • 多网关冲突:同一组件挂载多个 gateway Trait 时务必为每个 Trait 指定不同的name,否则生成的 Ingress 名称相同会导致资源冲突。
  • TLS 无法生效:检查secretName指向的 Secret 是否真实存在且位于应用同一命名空间,Ingress Controller 无法引用不存在的 Secret。

参考资料

  • 示例文档:references/docgen/def-doc/trait/gateway.eg.md
  • 定义源码:vela-templates/definitions/internal/trait/gateway.cue
  • 功能相近的 ingress Trait 示例:references/docgen/def-doc/trait/ingress.eg.md
  • 云原生
  • DevOps
  • 运维
  • 微服务

【免费下载链接】kubevela

The Modern Application Platform.

项目地址:https://gitcode.com/gh_mirrors/ku/kubevela
点击查看免费下载
上一篇:5分钟掌握Upscayl:免费AI图像放大工具的终极使用指南
下一篇:Python控制流终极指南:if、for、while、try四大语句全掌握 🚀

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询