AI 推理、智能体等有状态服务中,同一客户端的请求若被路由到不同 Pod,会导致上下文丢失或会话断开。Knative 会话保持(Session Affinity)通过唯一的 Session Key 标识(来自 Cookie、Header 或 Token),可确保同一客户端的请求始终路由到同一 Pod。
结合 Knative 原生自动扩缩容,当前会话保持功能提供完整的“会话感知”生命周期管理:
按需扩容:新会话到来时自动创建 Pod
精准缩容:会话过期后自动删除对应 Pod
1对1会话转发:支持将单个会话定向转发到对应 Pod
工作原理
会话保持为 Knative 服务提供以下三项核心能力:
能力 | 说明 |
一致性路由 | 同一客户端的请求始终转发到同一 Pod,保持有状态服务的上下文连续。 |
会话感知扩缩容 | 支持以活跃会话数为扩缩容基准,新会话触发 Pod 创建,会话到期触发 Pod 回收。 |
多存储模式 | 支持内存存储(默认)和 Redis 存储,适配不同规模和可靠性要求。 |
Knative 会话保持支持多种 Session Key 配置方式,灵活适配不同客户端接入模式。
Key | 适用场景 | 说明 |
自定义 Cookie | Web 端聊天应用等 | 首次自动生成 UUID 并 Set-Cookie |
Authorization Header | API Key / OAuth 接入 | Bearer Token 的 SHA256 摘要作为 Key |
X-Session-Key Header | 自定义集成 | 客户端显式指定,适配内部系统 |
准备工作
已安装1.18.3及以上版本的 Knative 组件,详见部署Knative。
(Redis 模式)会话映射关系默认存储在内存中,Activator 重启后可能丢失。生产环境或多 Activator 副本场景下,需提前创建云数据库 Tair(兼容 Redis)实例并获取连接地址。
关于两种模式的详细对比,请参见会话存储模式对比。
操作步骤
1、创建支持会话保持的 Knative 服务
以下步骤以 1 个会话独占 1 个 Pod、空闲 5 分钟自动回收为例,适用于短时有状态任务(如 API 调试、短会话推理)。
长时 AI 推理会话中,建议将session-timeout调整为30m或更长,避免会话被提前回收。
登录容器计算服务控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择应用 > Knative。
在服务管理页面,选择命名空间为
default,单击使用模板创建,选择示例模板为自定义,使用以下 YAML 部署服务。示例使用对应 Annotation 的推荐默认值。如需自定义超时时间、Cookie 名称或每 Pod 会话数,请参见Annotation 参数说明。
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: my-sessions-per-pod spec: template: metadata: annotations: # 启用会话保持 serving.knative.dev/session-affinity: "true" # 会话空闲超时时间,超过后 Pod 自动回收 serving.knative.dev/session-timeout: "5m" # 用于会话识别的 Cookie 名称 serving.knative.dev/session-affinity-cookie: "demo" # 以会话数为扩缩容指标 autoscaling.knative.dev/metric: "session" # 每个 Pod 承载的最大会话数 autoscaling.knative.dev/target: "1" spec: containers: - image: registry-cn-hangzhou-vpc.ack.aliyuncs.com/acs/knative-samples-helloworld-go-session:v1.0-bfdce98等待
my-sessions-per-pod部署完成后,在服务管理页面,获取访问网关地址和服务的默认域名。验证会话路由。
不同 Cookie 值的请求应路由到不同 Pod。
使用
Cookie demo=11访问,路由到 Pod A。curl -i -H "Host: my-sessions-per-pod.default.example.com" http://47.xx.xx.xx \ -H "Cookie: demo=11"Pod-A预期输出:
HTTP/1.1 200 OK Date: Tue, 21 Apr 2026 09:57:44 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 77 Connection: keep-alive Hello World! Cookies: Name: demo Value: 11 Raw Cookie Header: demo=11使用
Cookie demo=22访问,路由到 Pod B。curl -i -H "Host: my-sessions-per-pod.default.example.com" http://47.xx.xx.xx \ -H "Cookie: demo=22"Pod-B预期输出:
HTTP/1.1 200 OK Date: Tue, 21 Apr 2026 11:27:15 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 77 Connection: keep-alive Hello World! Cookies: Name: demo Value: 22 Raw Cookie Header: demo=22
确认两个会话对应的 Pod 均已创建。
kubectl get pods -l serving.knative.dev/service=my-sessions-per-pod预期输出显示 2 个 Running 状态的 Pod,分别承载
Cookie demo=11和demo=22的会话。Pod 数量与活跃会话数一致,表明会话感知扩缩容已生效。
(可选)2、配置 Redis 存储模式
生产环境多 Activator 副本场景下,需使用 Redis 存储模式保证会话一致性。在 knative-serving 命名空间的 config-defaults ConfigMap 中设置 Redis 地址。
关于两种模式的详细对比,请参见会话存储模式对比。
apiVersion: v1
kind: ConfigMap
metadata:
name: config-defaults
namespace: knative-serving
data:
# 替换为实际 Redis 实例的连接地址
session-storage-redis-addr: "r-xxxxxxxxxxxx.redis.rds.aliyuncs.com:6379"配置参考
Annotation 参数说明
以下为会话保持相关的全部 Annotation,可在 Knative 服务的 spec.template.metadata.annotations 中按需配置。
Annotation | 说明 | 默认值 | 示例 |
| 启用会话保持 |
|
|
| 自定义 Cookie 名称 | 自动检测 |
|
| 会话空闲超时 |
|
|
| 扩缩容指标类型 |
|
|
| 每个 Pod 承载的会话数 |
|
|
会话存储模式对比
内存模式开箱即用,更适用于开发测试;Redis 模式支持多 Activator 副本,更适用于生产环境。
维度 | 内存模式(默认) | Redis 模式 |
部署复杂度 | 零依赖,开箱即用 | 需阿里云 Redis 实例 |
多 Activator 支持 | 不支持 | 完全支持 |
一致性 | 最终一致 | 强一致 |
Activator 重启后会话 | 可能丢失 | 即时恢复 |
适用场景 | 单 Activator,可容忍部分会话丢失 | 生产环境(推荐) |
典型场景:AI 推理会话(1对1 隔离)
每个推理会话独占一个 GPU Pod,会话期间 Pod 不释放。session-timeout: 30m 表示用户 30 分钟无操作后 GPU Pod 才释放,避免频繁冷启动影响响应速度,同时防止长时间空闲占用 GPU 资源产生不必要费用。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: ai-inference
spec:
template:
metadata:
annotations:
serving.knative.dev/session-affinity: "true"
# 会话空闲 30 分钟后自动回收 GPU Pod
serving.knative.dev/session-timeout: "30m"
# 用于会话识别的 Cookie 名称
serving.knative.dev/session-affinity-cookie: "demo"
autoscaling.knative.dev/metric: "session"
# 每个 GPU Pod 仅承载 1 个推理会话
autoscaling.knative.dev/target: "1"
spec:
containers:
- image: registry-vpc.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:73fbdd56
resources:
limits:
nvidia.com/gpu: "1"常见问题
内存模式和 Redis 模式如何选择?
根据部署规模和可靠性要求选择合适的存储模式。
场景 | 推荐模式 |
开发测试 | 内存模式 |
生产环境和 1对1 隔离 | Redis 模式 |
多 Activator 副本 | Redis 模式 |
需要会话持久化 | Redis 模式 |
设置了会话保持但没有生效怎么办?
检查以下项:
serving.knative.dev/session-affinity: "true"是否设置在 Revision 的spec.template.metadata.annotations中。请求中是否携带了可识别的 Session Key 。
使用自定义 Cookie 时,
session-affinity-cookie的值是否与请求 Cookie 名称一致。查看 Activator 日志:
kubectl -n knative-serving logs -l app=activator -c activator
一个 Knative 服务可以同时使用 session 和 concurrency 指标吗?
不可以。session 与 concurrency/RPS 扩缩容指标互斥,一个服务只能配置其中一种。
灰度发布与会话保持如何协同工作?
两者是正交关系:流量首先按配置的百分比分发到不同 Revision,每个 Revision 内独立维持会话保持。
维度 | 作用域 | 目的 |
流量比例 | 跨 Revision | 控制灰度发布的流量分配 |
会话保持 | Revision 内 | 保证同一客户端在同一 Revision 的 Pod 上保持一致 |