Traefik Kubernetes 服务暴露实战:从首个 HTTP 服务到路径路由与 TLS 加密
本篇指南聚焦于 Traefik 在 Kubernetes 上暴露服务的基础能力:如何使用 whoami 演示应用完成第一个 HTTP 服务的暴露、基于 URL 路径进行多服务路由、以及用自签名证书为入口开启 TLS。读完本文,你可以独立在集群中选择 Gateway API(HTTPRoute)或 Traefik 自有 CRD(IngressRoute)两种路由方式完成服务暴露与加密,并理解 Traefik Provider 在源码层面是如何把这些资源转换成动态路由配置的。
前置条件
开始之前,请确保环境中具备以下条件(对应原文档 basic.md 的 Prerequisites 部分):
- 一个已安装 Traefik 的 Kubernetes 集群;
- 已配置好、可与集群交互的
kubectl; - Traefik 已通过 Kubernetes Setup 指南 部署完成(该指南演示了用官方 Helm chart 安装,并配置了
web/websecure入口点、Dashboard 认证与 Gateway 监听器)。
路由方式上,本指南提供两条可互换的路径,读者可按需二选一:
- Gateway API:Kubernetes 社区标准,跨发行版可移植;
- IngressRoute CRD:Traefik 自有资源,功能最完整,支持 Traefik 路由表达式与内建 ACME。
暴露第一个 HTTP 服务
首先用 traefik/whoami 演示镜像(一个回显请求元信息的调试应用)暴露一个最简单的 HTTP 服务。该 Deployment 创建 2 个副本以演示负载均衡,并配套一个选择 app: whoami 的 Service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
selector:
app: whoami
ports:
- port: 80
保存为 whoami.yaml 并应用:
kubectl apply -f whoami.yaml
接下来创建路由。下面分别给出 Gateway API 与 IngressRoute 两种写法。
方式一:使用 Gateway API(HTTPRoute)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway # 该 Gateway 由 Traefik 启用 Gateway API 时自动创建
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
保存为 whoami-route.yaml 并应用:
kubectl apply -f whoami-route.yaml
要点说明:
parentRefs.name: traefik-gateway指向 Traefik 开启 Gateway API provider 后自动创建的 Gateway 资源,它是 HTTPRoute 与监听器之间的桥梁;hostnames决定该路由匹配的 Host 头;rules[].matches中的PathPrefix匹配路径前缀,backendRefs指向同命名空间内的 Servicewhoami:80。
方式二:使用 IngressRoute CRD
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
保存为 whoami-ingressroute.yaml 并应用:
kubectl apply -f whoami-ingressroute.yaml
要点说明:
entryPoints指定路由绑定的入口点,这里使用 HTTP 入口web(80 端口);match使用 Traefik 路由表达式(Rule 语法),此处仅按Host(\whoami.docker.localhost`)` 匹配;services直接引用集群内的 Service 及其端口。
验证服务是否生效
服务现在应可通过 http://whoami.docker.localhost/ 访问。用 Host 头模拟域名进行验证:
curl -H "Host: whoami.docker.localhost" http://localhost/
!!! 注意
如果此前按 Kubernetes Setup 指南 安装 Traefik,记得从 values.yaml 中移除 ports.web.redirections 块,否则请求会被 302 跳转到 HTTPS 入口点,导致下面的 HTTP 验证失败:
redirections:
entryPoint:
to: websecure
成功时输出类似:
Hostname: whoami-6d5d964cb-8pv4k
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.18
IP: fe80::d4c0:3bff:fe20:b0a3
RemoteAddr: 10.42.0.17:39872
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-76cbd5b89c-rx5xn
X-Real-Ip: 10.42.0.1
响应中的 X-Forwarded-* 与 X-Real-Ip 头由 Traefik 注入,证明请求确实经过了代理转发到后端 whoami Pod(Hostname 显示 Pod 名)。
添加基于路径的路由规则
下一步按 URL 路径把流量分发到不同服务——这在 API 版本管理、前后端分离、微服务聚合等场景中非常常用。先部署一个代表 API 的第二个服务(通过 WHOAMI_NAME 环境变量把它标识为 "API Service"):
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: whoami-api
template:
metadata:
labels:
app: whoami-api
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "API Service"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-api
namespace: default
spec:
selector:
app: whoami-api
ports:
- port: 80
保存为 whoami-api.yaml 并应用:
kubectl apply -f whoami-api.yaml
Gateway API:路径规则
更新已有的 HTTPRoute,将 /api 前缀指向 whoami-api,根路径 / 兜底到 whoami。注意 rules 的先后顺序:前缀规则在前、兜底规则在后:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
更新 whoami-route.yaml 文件后应用:
kubectl apply -f whoami-route.yaml
IngressRoute:路径规则
更新已有的 IngressRoute,用 Traefik 路由表达式组合 Host 与 Path 条件:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
保存为 whoami-ingressroute.yaml 并应用:
kubectl apply -f whoami-ingressroute.yaml
两条 routes 的区别在于第一条附加了 Path(\/api`)精确路径条件,第二条仅按 Host 匹配充当兜底路由。从源码结构看([crd/kubernetes_http.go](https://gitcode.com/GitHub_Trending/tr/traefik/blob/14bc52dd1f1d1c08cedd1da531a527fc04d79c19/pkg/provider/kubernetes/crd/kubernetes_http.go?utm_source=gitcode_repo_files) 中的loadIngressRouteConfiguration),IngressRoute 的每一条 route 都会生成一个独立的 Traefik Router,match字段直接成为 Router 的 Rule,并记录Priority;而 [gateway/kubernetes.go](https://gitcode.com/GitHub_Trending/tr/traefik/blob/14bc52dd1f1d1c08cedd1da531a527fc04d79c19/pkg/provider/kubernetes/gateway/kubernetes.go?utm_source=gitcode_repo_files) 中的 Gateway provider 则负责解析 HTTPRoute的rules/matches/backendRefs`,将其转换为等价的动态路由配置。两种写法最终都收敛到同一套动态配置模型上,这也是二者可以互换使用的底层原因。
测试路径路由
分别请求根路径和 /api 路径,验证流量被路由到了不同服务:
# 根路径应路由到主 whoami 服务
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api 路径应路由到 whoami-api 服务
curl -H "Host: whoami.docker.localhost" http://localhost/api
针对 /api 的请求,响应中应能看到 "name":"API Service",证明路径路由生效:
{"hostname":"whoami-api-67d97b4868-dvvll","ip":["127.0.0.1","::1","10.42.0.9","fe80::10aa:37ff:fe74:31f2"],"headers":{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["curl/8.7.1"],"X-Forwarded-For":["10.42.0.1"],"X-Forwarded-Host":["whoami.docker.localhost"],"X-Forwarded-Port":["80"],"X-Forwarded-Proto":["http"],"X-Forwarded-Server":["traefik-669c479df8-vkj22"],"X-Real-Ip":["10.42.0.1"]},"url":"/api","host":"whoami.docker.localhost","method":"GET","name":"API Service","remoteAddr":"10.42.0.13:36592"}
为服务启用 TLS
现在用自签名证书为本地开发环境开启 HTTPS。
创建自签名证书
生成自签名证书:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=whoami.docker.localhost"
在 Kubernetes 中创建 TLS Secret:
kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
!!! 重要(Gateway API 使用 TLS 的前置条件)
使用 Gateway API 处理 TLS 之前,必须在 Traefik 安装配置中定义 websecure 监听器(通常通过 Helm values 完成)。values.yaml 示例:
ports:
web:
port: 80
websecure:
port: 443
gateway:
listeners:
web:
port: 80
protocol: HTTP
namespacePolicy:
from: All
websecure:
port: 443
protocol: HTTPS
namespacePolicy:
from: All
mode: Terminate
certificateRefs:
- kind: Secret
name: whoami-tls
group: ""
完整的安装细节参见 Kubernetes Setup 指南。其中 mode: Terminate 表示 TLS 在 Traefik 内部终结,certificateRefs 指定终结 TLS 所用的证书 Secret,namespacePolicy.from: All 则允许任意命名空间的路由绑定该监听器。
Gateway API:切换至 HTTPS 监听器
更新 HTTPRoute,通过 sectionName 指向 websecure 监听器即可复用同一组路径规则:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure # 指向 HTTPS 监听器
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
更新 whoami-route.yaml 文件并应用:
kubectl apply -f whoami-route.yaml
IngressRoute:声明 TLS Secret
更新 IngressRoute:把入口点从 web 改为 websecure,并在 tls 字段引用前面创建的 Secret:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure # 由 'web' 改为 'websecure'
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls # 新增的 TLS 配置
更新 whoami-ingressroute.yaml 文件并应用:
kubectl apply -f whoami-ingressroute.yaml
从源码结构看(crd/kubernetes_http.go),tls.secretName 会被 getTLSHTTP 解析:provider 从集群中拉取该 TLS Secret,加载证书后写入对应 Router 的 dynamic.Router.TLS 配置;同文件中还可以看到,tls.certResolver(ACME 自动签发)与 tls.options(TLSOption)也是在这一阶段解析到 Router 上的——这正是后文"进阶"章节中 Let's Encrypt 能力的入口。
验证 HTTPS 访问
现在可以通过 HTTPS 访问服务。由于是自签名证书,需要跳过证书校验:
curl -k -H "Host: whoami.docker.localhost" https://localhost/
浏览器同样可以访问 https://whoami.docker.localhost/(自签名证书会触发浏览器安全警告,需手动接受)。
小结与下一步
本文完整复现了 basic.md 的三条主线:首个 HTTP 服务暴露(Gateway API 与 IngressRoute 双方案)、基于路径的多服务路由、以及用自签名证书开启 TLS,并在关键节点补充了 Traefik Kubernetes Provider 的源码级实现佐证:
- Gateway API 路径:资源解析与 provider 配置项见 pkg/provider/kubernetes/gateway/kubernetes.go,参考文档见 Gateway API 参考;
- IngressRoute 路径:路由与 TLS 的转换逻辑见 pkg/provider/kubernetes/crd/kubernetes_http.go,参考文档见 IngressRoute 参考;
- 集群安装与
web/websecure监听器配置见 Kubernetes Setup 指南。
掌握这些基础后,可以继续进入 进阶指南,学习:为路由添加中间件实现安全与访问控制、用 Let's Encrypt(IngressRoute)或 cert-manager(Gateway API)自动签发证书、为有状态应用配置粘性会话(sticky sessions),以及基于 IngressRoute 的多层路由(multi-layer routing)实现认证前置等高级模式。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00