首页
/ Traefik 在 Kubernetes 中的快速上手:从 k3d 本地集群到 IngressRoute 与 Gateway API 双模路由实践

Traefik 在 Kubernetes 中的快速上手:从 k3d 本地集群到 IngressRoute 与 Gateway API 双模路由实践

2026-09-04 15:44:30作者:戚魁泉Nursing

本文基于 Traefik 官方入门文档《Getting Started with Kubernetes and Traefik》,带你完整走一遍 Traefik 在 Kubernetes 环境下的落地全流程:用 k3d 创建本地集群、用 Helm 安装 Traefik、通过 Chart 自动暴露 Dashboard、部署 whoami 示例应用,并分别使用 Traefik 专有 CRD(IngressRoute)与标准 Kubernetes Gateway API(HTTPRoute)两种方式完成路由配置。读完本文,你不仅掌握一套可直接复制运行的操作手册,还能结合 Traefik 仓库源码理解 Gateway API provider 的静态配置结构、默认值与入口点注入机制。

Kubernetes 是 Traefik 的一等公民:Traefik 原生支持多种 Kubernetes 资源与最新的 Kubernetes 标准。无论你选择 Traefik 的 IngressRoute CRDIngress 还是 Kubernetes Gateway API,都能获得一致、顺滑的流量管理体验。

前置条件

开始之前,请确认本地环境已具备:

  • Kubernetes(或 k3d 等可以创建本地集群的工具)
  • Helm 3
  • kubectl
  • k3d(用于创建本地集群)

第一步:使用 k3d 创建 Kubernetes 集群

k3d 是轻量级本地 K3s 集群工具,非常适合快速验证 Traefik 的 Kubernetes 能力。执行以下命令创建集群:

k3d cluster create traefik \
  --port 80:80@loadbalancer \
  --port 443:443@loadbalancer \
  --port 8000:8000@loadbalancer \
  --k3s-arg "--disable=traefik@server:0"

这条命令做了三件事,理解参数含义有助于你调整自己的实验环境:

  • 创建一个名为 traefik 的 k3d 集群;
  • 将宿主机端口 804438000 映射到集群内置的 loadbalancer 节点,供后续访问服务使用(80/443 对应 Traefik 的 web/websecure 入口,8000 是 Traefik 默认的 API 端口);
  • 通过 --k3s-arg "--disable=traefik@server:0" 禁用 k3s 内置的 Traefik ingress controller,避免它与你要安装的 Traefik 抢占入口端口、造成路由冲突。

配置 kubectl 上下文:

kubectl cluster-info --context k3d-traefik

第二步:使用 Helm 安装 Traefik

方式一:使用 values 文件

先添加 Traefik 官方 Helm 仓库:

helm repo add traefik https://traefik.github.io/charts
helm repo update

创建 values 文件 values.yaml

# values.yaml
ingressRoute:
  dashboard:
    enabled: true
    matchRule: Host(`dashboard.localhost`)
    entryPoints:
      - web
providers:
  kubernetesGateway:
    enabled: true
gateway:
  listeners:
    web:
      namespacePolicy:
        from: All

逐项解析这份配置:

  • ingressRoute.dashboard.enabled: true:启用由 Chart 自动生成的 Dashboard IngressRoute。Dashboard 的访问入口正是这一步定义的,后续章节会直接受益;
  • ingressRoute.dashboard.matchRule: Host(\dashboard.localhost`):为 Dashboard 指定主机名路由规则,最终访问路径为 http://dashboard.localhost/dashboard/`;
  • ingressRoute.dashboard.entryPoints: [web]:将 Dashboard 绑定到 web 入口点(对应 80 端口);
  • providers.kubernetesGateway.enabled: true:启用 Kubernetes Gateway API provider,让 Traefik 能感知 GatewayClass/Gateway/HTTPRoute 等标准资源;
  • gateway.listeners.web.namespacePolicy.from: All:允许 Gateway 接受来自所有命名空间的 HTTPRoute 绑定。如果改为 Same(默认值),则只有与 Gateway 同命名空间内的 HTTPRoute 才能挂载到该 Gateway。

说明:使用 Helm Chart 时,Kubernetes CRD provider 默认就是启用的,因此 values 文件中无需再显式开启 providers.kubernetesCRD。这正是下一节 IngressRoute 方式能直接生效的原因。

执行安装:

helm install traefik traefik/traefik -f values.yaml --wait

方式二:使用 Helm CLI 参数

如果你不想落地一个 values 文件,也可以用 --set 参数完成等价配置。这条命令:

  • 将 80/443 端口映射到 web 与 websecure 入口(k3d 已做端口映射);
  • 启用带主机名规则的 Dashboard;
  • 启用 Kubernetes Gateway API provider;
  • 允许 Gateway 接受所有命名空间的 HTTPRoute。
helm install traefik traefik/traefik --wait \
  --set ingressRoute.dashboard.enabled=true \
  --set ingressRoute.dashboard.matchRule='Host(`dashboard.localhost`)' \
  --set ingressRoute.dashboard.entryPoints={web} \
  --set providers.kubernetesGateway.enabled=true \
  --set gateway.listeners.web.namespacePolicy.from=All

同样地,Kubernetes CRD provider 在 Helm Chart 中默认启用,CLI 参数中也无需设置。

安装完成后,Traefik 会自动创建一个名为 traefik 的默认 GatewayClass,可以用以下命令查看:

kubectl describe GatewayClass traefik

这个 GatewayClass 是 Gateway API 体系中"由哪个网关控制器接管流量"的声明;后续创建的 Gateway/HTTPRoute 都会通过它关联到 Traefik。

第三步:暴露 Traefik Dashboard

安装过程中我们通过 ingressRoute.dashboard 配置,让 Chart 生成了一个 Dashboard 的 IngressRoute。现在直接访问:

http://dashboard.localhost/dashboard/

Traefik Dashboard 界面

在 Dashboard 的 Providers 面板中,你应当能看到 KubernetesCRDKubernetesGateway 两个 provider 都处于激活状态——这是后续两种路由方式分别生效的直观证据。

第四步:部署示例应用

用 Traefik 官方的 traefik/whoami 镜像部署一个无状态的示例应用。创建 Deployment:

# whoami.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
spec:
  replicas: 2
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: traefik/whoami
          ports:
            - containerPort: 80

创建对应的 Service:

# whoami-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  ports:
    - port: 80
  selector:
    app: whoami

应用清单:

kubectl apply -f whoami.yaml
kubectl apply -f whoami-service.yaml

此时 whoami 服务已在集群内部可达(Service whoami:80),但外部流量仍无法进入——接下来分别用两种 Traefik 支持的方式把它暴露出去。

方式一:使用 IngressRoute(Traefik CRD)暴露应用

IngressRoute 是 Traefik 的专有 CRD(traefik.io/v1alpha1),它把"路由规则 + 入口 + 后端服务"聚合在一个对象里,配置直观、与 Traefik 深度集成。创建 IngressRoute:

# whoami-ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: whoami
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`whoami.localhost`)
      kind: Rule
      services:
        - name: whoami
          port: 80

关键字段说明:

  • entryPoints: [web]:流量从 80 端口的 web 入口进入;
  • match: Host(\whoami.localhost`):路由规则,匹配 Host 头为 whoami.localhost` 的请求。从源码结构看,这类规则字符串由 Traefik 的路由规则解析器编译为可执行的匹配谓词,解析逻辑位于 pkg/rules/parser.go
  • services: [{name: whoami, port: 80}]:指定后端为集群内的 Service whoami 的 80 端口。

应用清单:

kubectl apply -f whoami-ingressroute.yaml

验证

使用 curl 验证应用已被正确暴露:

curl http://whoami.localhost

预期输出(whoami 会回显收到的完整请求信息):

Hostname: whoami-76c9859cfc-6v8hh
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.11
IP: fe80::20ad:eeff:fe44:a63
RemoteAddr: 10.42.0.9:38280
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 127.0.0.1
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-598946cd7-zds59
X-Real-Ip: 127.0.0.1

注意 X-Forwarded-*X-Real-Ip 系列头:它们是 Traefik 作为反向代理自动注入的(请求经过 2 个副本时 Hostname 会随机落在不同 Pod 上,可借此观察负载均衡效果)。你也可以在浏览器访问 http://whoami.localhost 获得同样的页面效果:

whoami 应用响应页面

方式二:使用 Gateway API(标准 Kubernetes 方式)暴露应用

Gateway API 是 Kubernetes SIG 推出的标准化 ingress 规范,它把"谁提供网关能力(GatewayClass/Gateway)"与"谁声明路由(HTTPRoute 等)"分层解耦。前面安装时我们已经开启了 Gateway API provider,可以到 Dashboard 的 Providers 面板确认它已激活。

Traefik 的 Kubernetes Gateway provider 支持 Gateway API Standard 通道的 v1.5.1 版本,完整支持 HTTPRoute 核心能力,并覆盖 BackendTLSPolicyGRPCRouteTLSRoute 等 Standard 通道扩展资源,以及 Experimental 通道的 TCPRoute(需显式开启 experimentalChannel)。Traefik 仓库内附带了 conformance 测试报告,可在 integration/gateway-api-conformance-reports/v1.5.1/experimental-v3.7-default-report.yaml 中查看其一致性覆盖范围;仓库 pkg/provider/kubernetes/gateway/ 目录下还有大量 fixtures 测试数据,覆盖命名空间策略、TLS 配置、BackendTLSPolicy 等各种路由场景,可作为行为细节的第一手参考。

1. 安装 Gateway API CRD

Gateway API 的资源类型需要先装入集群:

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml

2. 创建 HTTPRoute

# httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami
spec:
  parentRefs:
    - name: traefik-gateway
  hostnames:
    - "whoami-gatewayapi.localhost"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: whoami
          port: 80

这份配置的含义:

  • 创建一个名为 whoami 的 HTTPRoute;
  • parentRefs 将其挂载到 Traefik 安装时自动创建的默认 Gateway(traefik-gateway)——这解释了前文 namespacePolicy.from: All 的作用:它决定了哪些命名空间里的 HTTPRoute 允许绑定这个 Gateway;
  • hostnames: [whoami-gatewayapi.localhost] 声明该路由处理的主机名;
  • 规则将 PathPrefix / 的全部流量转发到后端 Service whoami 的 80 端口。

应用清单:

kubectl apply -f httproute.yaml

3. 验证

curl http://whoami-gatewayapi.localhost

预期得到与之前类似的 whoami 响应(Host 头为 whoami-gatewayapi.localhost)。

回到 Dashboard 的 HTTP Routes 面板,可以确认新路由由 KubernetesGateway provider 接管——路由的 provider 归属列会标注为 Traefik 的 Gateway API provider,与 IngressRoute 方式下由 CRD provider 管理的路由形成对照:

Traefik Dashboard 中由 Gateway API provider 管理的 HTTP 路由

源码纵深:Gateway API provider 是怎么接入 Traefik 的

上面的实操背后,Traefik 仓库中有清晰的实现脉络,值得快速过一遍,便于排障和二次开发。

1. 静态配置入口。在静态配置的 Providers 定义中,kubernetesGatewaykubernetesCRD 是并列的两个 provider 开关,见 pkg/config/static/static_config.go

KubernetesCRD     *crd.Provider     `description:"Enables Kubernetes CRD provider." ...`
KubernetesGateway *gateway.Provider `description:"Enables Kubernetes Gateway API provider." ...`

Helm Chart 中的 providers.kubernetesGateway.enabled: true 最终就是映射到 --providers.kubernetesgateway=true 这一静态配置。

2. Provider 参数结构。Gateway API provider 的完整参数定义在 pkg/provider/kubernetes/gateway/kubernetes.go

type Provider struct {
    Endpoint                string            `description:"Kubernetes server endpoint (required for external cluster client)." ...`
    Token                   types.FileOrContent `description:"Kubernetes bearer token (not needed for in-cluster client)..." ...`
    QPS                     int               `description:"Defines the maximum QPS to the Kubernetes API server..."`
    Burst                   int               `description:"Defines the maximum burst of requests to the Kubernetes API server."`
    CertAuthFilePath        string            `description:"Kubernetes certificate authority file path..."`
    Namespaces              []string          `description:"Kubernetes namespaces."`
    LabelSelector           string          `description:"Kubernetes label selector to select specific GatewayClasses."`
    ThrottleDuration        ptypes.Duration `description:"Kubernetes refresh throttle duration"`
    ExperimentalChannel     bool              `description:"Toggles Experimental Channel resources support (TCPRoute, TLSRoute...)."`
    StatusAddress           *StatusAddress    `description:"Defines the Kubernetes Gateway status address."`
    NativeLBByDefault       bool              `description:"Defines whether to use Native Kubernetes load-balancing by default."`
    CrossProviderNamespaces []string          `description:"...allowed to declare TraefikService backendRef references."`
    ...
}

其中 SetDefaults() 给出默认限流值:QPS = 50Burst = 100(注释中说明这是 Kubernetes 客户端默认值的 10 倍),用于保护 API server 不被高频 watch 事件打爆;LabelSelector 则只作用于 GatewayClass 的筛选——留空时 Traefik 会处理配置命名空间内的全部 GatewayClass(即默认的 traefik 那个)。

3. 启动时的入口点注入。静态配置加载完成后,Traefik 会把已声明的入口点地址注入 Gateway provider,供其做 listener 校验与路由匹配,见 pkg/config/static/static_config.go

if c.Providers.KubernetesGateway != nil {
    entryPoints := make(map[string]gateway.Entrypoint)
    for epName, entryPoint := range c.EntryPoints {
        entryPoints[epName] = gateway.Entrypoint{Address: entryPoint.GetAddress(), HasHTTPTLSConf: entryPoint.HTTP.TLS != nil}
    }
    if c.Providers.KubernetesCRD != nil {
        c.Providers.KubernetesCRD.FillExtensionBuilderRegistry(c.Providers.KubernetesGateway)
    }
    c.Providers.KubernetesGateway.EntryPoints = entryPoints
}

这里有两点值得注意:HasHTTPTLSConf 记录了入口是否配置了 HTTP 上的 TLS,provider 据此判断 listener 的协议兼容性;而 FillExtensionBuilderRegistry 在 CRD 与 Gateway provider 同时启用时打通了两者——这正是 Gateway API 路由可以通过 backendRef 引用 CRD 定义的 TraefikService(跨 provider 复用 CRD 中间件)的底层机制,对应上文 crossProviderNamespaces 参数的行为。

4. 关键行为速查(参数详情与完整字段表见 Kubernetes Gateway provider 参考文档):

参数 说明 默认值
providers.kubernetesGateway.endpoint API server 端点。集群内部署时自动读取 KUBERNETES_SERVICE_HOST/PORT 环境变量与 ServiceAccount token;集群外部署时必填(如 kubectl proxy 地址) ""
providers.kubernetesGateway.namespaces 要 watch 的命名空间列表,留空则监听全部命名空间 []
providers.kubernetesGateway.labelSelector 仅对 GatewayClass 生效的标签筛选器 ""
providers.kubernetesGateway.throttleDuration 两次事件之间的最小等待时间,防止高频更新导致配置抖动 0s(另有全局 providersThrottleDuration,默认 2s)
providers.kubernetesGateway.experimentalChannel 开启 Experimental 通道资源(如 TCPRoute false
providers.kubernetesGateway.nativeLBByDefault 是否默认使用 Kubernetes 原生负载均衡模式 false
providers.kubernetesGateway.statusAddress.* 将主机名/IP/Service 状态地址写回 Gateway 的 status.addresses(可配合 External-DNS 之类工具) ""
providers.kubernetesGateway.qps / burst 客户端限流(源码默认 50 / 100) 50 / 100

5. 与 IngressRoute 方式的取舍。两种方式在本指南中并行验证,可以归纳为:IngressRoute 是 Traefik 的"专有方言",对象少、语义直白;Gateway API 是 Kubernetes 标准方言,跨网关可移植、与生态工具链互通,但对象模型(GatewayClass → Gateway → HTTPRoute)更复杂。两者可共存,且通过上文第 3 点的注册表打通机制,Gateway 路由还能引用 CRD 侧定义的 TraefikService。

小结与后续步骤

到这里,你已经:用 k3d 建好了实验集群;用 Helm 装好带 Dashboard 与双 provider 的 Traefik;部署了 whoami 应用;并分别用 IngressRoute(CRD)和 HTTPRoute(Gateway API)把它暴露到了 whoami.localhostwhoami-gatewayapi.localhost

建议的下一步:

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
981
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384