背景
传统的 HPC 环境一般仅开放登录节点,计算节点严格限制内网访问。所以在原先基于 Slurm 调度的 HPC 集群中,如果想方便用户启动一个类似 jupyter notebook 的网页服务并访问时,主流的做法是 Open OnDemand 的 Apache 监听端口并通过 Lua 脚本解析路径映射 + Nginx 转发的方式实现反向代理。而在最近在做 k8s 相关设计时,发现想实现作业服务转发选择相对会多不少。
简单 Vibe Research 一下主流方案有以下几种:
- 基于 Ingress Controller(Ingress Nginx / Tarefik)
- 基于 API 网关(APISIX / Kong)
- 基于 Service Mesh(Istio)
Why Traefik
从需求本身出发,需要反向代理的目的仅仅为了节点 web 服务的转发和自定义路径映射。那么上面提到的很多相对较重的服务所具备的特性(负载均衡、强鉴权等)对我们都没有意义,从轻量优先的角度自然选择 Traefik 作为优先考虑的实现方式。
Traefik 有以下几个优势特性:
- 开源 Go 语言编写
- 配置热更新
- 自带一个 Dashboard
What Is Tarefik
Traefik(发音为 “traffic ”)是一款现代化的 HTTP 反向代理和负载均衡器,可轻松部署微服务。

Traefik 会实时监听你的服务注册中心或编排器的 API,并自动动态生成路由,从而将你的微服务无缝连接到外部世界——完全无需你再进行任何额外的手动干预。
Quickstart
部署
国内环境按照官方文档的 helm 仓库配置部署会因为网络连接问题报错,可以 git clone 官方的 Traefik Helm Chart 项目进行部署。
1 | git clone https://github.com/traefik/traefik-helm-chart.git |
注意 helm 版本兼容性(需要 v3.9.0+ 版本)
新建一个 values 配置,通过 NodePort 转发 dashboard(注意不同版本格式区别较大,这里使用的是 v3.6.7 的 traefik)。
1 | # my-values.yaml |
编辑保存后安装应用:
1 | # 首次安装 |
本地访问服务器 30900 端口的 /dashboard 端点({node-ip}:30900/dashboard)即可进入 dashboard:

同时可以通过命令确认 web 端口:
1 | [root@mgt ~]# kubectl get svc traefik -n traefik -o yaml | grep -A 20 "ports:" |
代理应用服务
接下来就可以尝试转发 k8s 中的应用服务了,这里以 jupyter 为例。
作为 AI 平台我们一般期望使用 url 路径来隐藏端口,那么就需要修改 jupyter 启动参数中的 NotebookApp.base_url。路由规则的话用作业名称区分相对比较合理(暂时假定单个作业对应单个应用服务转发,如果存在多个服务则需要配置子路径)。
需要注意的问题是 k8s 中资源声明相对静态,而启动 jupyter 时已经需要指定具体的 base_url 了,所以要用到 Downward API 接口(参数定义和注入)来暴露作业名称给容器的启动命令。
你可以通过
fieldRef从可用的 Pod 级字段传递信息。在 API 层面,Pod 的spec始终至少定义一个容器。你可以通过resourceFieldRef从可用的容器级字段传递信息。
环境变量声明:
1 | spec: |
容器启动参数:
1 | spec: |
启动之后还需要建两个资源和 traefik 路由匹配:
- Service:ClusterIP,暴露端口
- IngressRoute:匹配 PathPrefix 路由到 Service
IngressRoute 示例:
1 | apiVersion: traefik.io/v1alpha1 |
创建后就可以通过 http://{traefik_addr}:{traefik_port}/app/jupyter-test-9z7w9 直接访问 jupyter 服务了。

dashboard 中也可以观测到路由和服务的绑定等信息。