先看现象。K8s 外的 nginx 用域名做 upstream,后端扩了一台新机器并改了 DNS 解析,nginx 里还是只往旧地址发流量,reload 之后才把新机器加进来。

原因不止一个,得分开看。nginx 启动时解析一次 upstream 域名,之后一直用缓存,DNS 变更不会自动生效。少数情况下是系统 resolv.conf 里 valid 时间很长,本地也不重新查询。

另外,upstream 里加了 resolve 参数但缺少 resolver 指令,配置直接报错不生效。

少数情况下是DNS 返回了多条记录,nginx 在启动时只取了第一条。

第一件事是确认 nginx 当前连的是哪些地址

ss -tnp | grep nginx | awk '{print $5}' | sort | uniq -c

随后配置 resolver 并让 upstream 动态解析

printf 'resolver 10.0.0.2 valid=30s;\nupstream app { zone app 64k; server api.inner:8080 resolve; }\n' > /etc/nginx/conf.d/up.conf

校验配置里 resolver 是否在 http 块内

nginx -t && nginx -T | grep -n resolver

等前面都确认过,再改完观察是否连上新地址

nginx -s reload && ss -tn state established '( dport = :8080 )' | tail -5

恢复的判定其实很直接。established 连接里出现新后端 IP,旧机器连接数逐步归零,接口耗时与扩容前一致。

容易忽略的是,需要动态跟随 DNS 就必须配 resolver 加 zone,少了任何一项都会退回启动时解析;不追求动态也至少要在变更后 reload 一次。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189