Nginx Ingress粘性会话配置不生效问题排查求助
我之前维护过v1.8.x版本的Nginx Ingress Controller,遇到过几乎一样的问题,咱们一步步来排查:
首先,先确认最基础的点:你添加的注解真的成功保存到Ingress对象里了吗?
你说kubectl describe ing mying看不到这些注解,先别着急看控制器的问题,先运行这个命令查看Ingress的完整配置:
kubectl get ing mying -o yaml
找到annotations字段,看看你加的三个粘性会话注解是不是在里面。如果没有,那肯定是之前的kubectl edit操作没成功——大概率是yaml格式错了,比如注解的冒号后面没加空格(比如写成nginx.ingress.kubernetes.io/affinity:cookie而不是nginx.ingress.kubernetes.io/affinity: cookie),或者编辑时没保存就退出了。重新编辑Ingress,确保格式像下面这样:
annotations: nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/session-cookie-hash: "md5" nginx.ingress.kubernetes.io/session-cookie-name: "foobar"
要是yaml里有注解,但describe还是看不到?那你看看是不是漏加了namespace参数,比如Ingress不在默认namespace的话,要加-n <你的Ingress所在namespace>再运行describe。
接下来,检查IngressClass的匹配问题——这是最容易踩坑的点:
Nginx Ingress Controller只会处理和自己配置的IngressClass匹配的Ingress资源。先看看控制器的启动参数里指定了哪个IngressClass:
kubectl get pods -n <Ingress控制器所在namespace> -o yaml | grep -A5 "command"
找有没有--ingress-class=xxx的参数,一般默认是nginx。然后检查你的Ingress有没有指定对应的IngressClass:
- 如果你的Ingress是
networking.k8s.io/v1版本,看spec.ingressClassName字段是不是等于控制器的--ingress-class值; - 如果是旧版本的Ingress(比如
extensions/v1beta1),看annotations里有没有kubernetes.io/ingress.class: xxx的注解,值要和控制器的参数一致。
要是Ingress没指定正确的IngressClass,控制器会直接忽略这个Ingress,自然不会处理粘性会话的注解。
然后,看看控制器有没有禁用粘性会话:
有些部署会在Ingress Controller的启动命令里加--disable-affinity参数,直接把粘性会话功能关了。用刚才查看启动参数的命令检查有没有这个参数,如果有,去掉它,然后重启控制器的Pod:
kubectl rollout restart deployment <ingress-controller-deployment-name> -n <namespace>
另外,如果你配置了TLS,还要检查有没有开SSL Passthrough:
要是Ingress Controller启动时加了--enable-ssl-passthrough参数,那粘性会话注解肯定不生效——因为SSL Passthrough会把加密流量直接转发到后端Pod,Nginx根本不会解析请求、处理Cookie相关的配置。这种情况要么关掉SSL Passthrough,要么让后端Pod自己处理粘性会话。
如果上面的检查都没问题,那就去看控制器的日志找线索:
kubectl logs <ingress-controller-pod-name> -n <namespace>
搜索affinity、cookie或者你的Ingress名称mying,看看有没有报错信息,比如“忽略Ingress因为IngressClass不匹配”、“无法解析注解”之类的,这些日志会直接告诉你问题出在哪。
最后,确认下后端Service的类型:
粘性会话要求后端Service是ClusterIP或NodePort类型,不能是ExternalName——因为ExternalName只是域名跳转,Nginx没法直接和后端Pod建立关联,自然没法设置会话粘性。
按照这些步骤排查,应该能找到问题。我之前遇到最多的就是IngressClass不匹配和yaml格式错误,你可以先重点查这两个点。
内容的提问来源于stack exchange,提问作者ACC

