K8s 1.25 的 nginx-ingress 开了 session affinity,用户登录后刷新就掉线,浏览器里能看到 cookie,但同一个域名下不同路径的请求分到了不同 Pod。
一开始怀疑是「affinity-mode 用的是 cookie 但后端自己也下发同名 cookie,互相覆盖」,查了一圈,方向不对。
这类报错背后常见的原因有几处,逐个排除就行。affinity 的 cookie 只在命中的 Ingress 规则里生效,多个 Ingress 各自算一份。也可能是cookie 的 path 被设成具体路径,访问其他路径时不带这个 cookie。
少数情况下是副本数变化后旧的亲和表失效,用户被重新分配到新 Pod。
动手时先确认亲和注解是否生效
kubectl get ingress web -o jsonpath='{.metadata.annotations.nginx\.ingress\.kubernetes\.io/affinity}'
接着检查响应里的亲和 cookie
curl -sI https://www.example.com/login | grep -i set-cookie
再往下把亲和模式与 cookie 名固定下来
kubectl annotate ingress web nginx.ingress.kubernetes.io/affinity=cookie nginx.ingress.kubernetes.io/session-cookie-name=route nginx.ingress.kubernetes.io/session-cookie-path=/ --overwrite
连续请求验证是否落在同一 Pod
for i in 1 2 3; do curl -s -b 'route=xxx' https://www.example.com/whoami; done
恢复的判定其实很直接。三次连续请求返回同一个 Pod 名,Set-Cookie 里的 route 路径为根路径,刷新页面后仍处于登录态。
提醒一点。会话保持只解决粘性不解决共享,多副本的正确做法还是把 session 放 Redis;cookie 路径写成具体目录,跨路径访问必然丢会话。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
