会话保持解决什么问题
Service 默认对每条新连接独立挑选后端 Pod,同一客户端的第二次连接可能落到另一个副本。把 spec.sessionAffinity 设为 ClientIP 后,kube-proxy 会按客户端源 IP 计算哈希,在超时时间内把来自同一 IP 的连接固定到同一个 Pod。它解决的是「旧应用把登录态、购物车放在进程内存」这类兼容问题,而不是分布式会话方案:超时到期或目标 Pod 重建后粘性即失效。
基本信息
| 适用平台 | Kubernetes 各版本,Service 字段,由 kube-proxy 实现 |
|---|---|
| 关键字段 | spec.sessionAffinity;spec.sessionAffinityConfig.clientIP.timeoutSeconds |
| 取值 | None(默认,不保持)|ClientIP(按源 IP 保持) |
| 默认超时 | 10800 秒(3 小时) |
| 影响范围 | 仅该 Service;滚动更新、驱逐、缩容仍会打断已建立的会话 |
典型使用场景
- 改造困难的单体应用:会话写在本机内存,短期无法改成无状态
- 带本地缓存的有状态计算:希望同一客户端连续命中同一副本的热数据
- 外购系统过渡期:供应商短期内不支持共享会话存储,先用粘性顶住
- 迁移窗口期:应用尚未接入 Redis 等集中存储,避免用户频繁掉登录
- 故障定位:临时固定来源,比较同一副本与其他副本的行为差异
配置示例
配置示例
apiVersion: v1
kind: Service
metadata:
name: web
spec:
sessionAffinity: ClientIP # 不启用时取默认值 None
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800 # 粘性窗口,默认 3 小时
selector:
app: web
ports:
- port: 80
targetPort: 8080查看与修改
查看与修改
kubectl get svc web -o jsonpath='{.spec.sessionAffinity} {.spec.sessionAffinityConfig.clientIP.timeoutSeconds}'
kubectl patch svc web -p '{"spec":{"sessionAffinity":"ClientIP","sessionAffinityConfig":{"clientIP":{"timeoutSeconds":3600}}}}'
kubectl describe svc web | grep -i -A2 session # 确认字段已落库取值与影响
| 取值 | 行为 | 适用判断 |
|---|---|---|
| None | 每条连接独立选后端,默认值 | 无状态应用保持默认即可 |
| ClientIP | 同一源 IP 在超时内固定后端 | 有本地会话状态的过渡方案 |
| timeoutSeconds | 粘性窗口长度 | 过长会让流量分布越来越偏 |
kube-proxy 在 iptables/IPVS 模式下按源 IP 计算哈希:客户端经 NAT 网关或运营商大出口上网时,大量用户会被算作同一个来源,流量集中到少数 Pod,反而加剧不均衡。
已经建立的 TCP 长连接本来就不会中途切换后端,sessionAffinity 主要影响「同一客户端后续新建连接」的落点。