ingress-nginx通过Lua动态设置后端无效,仍使用默认服务
问题分析
你遇到的问题根源在于NGINX Ingress Controller默认生成的配置中,proxy_pass是硬编码指向Ingress spec里定义的固定上游服务,而你在Lua块中修改的proxy_upstream_name变量并没有被proxy_pass引用,所以动态设置的上游不会生效。
解决方案
1. 修复Lua代码的错误处理
你的Lua代码未处理authserver请求失败的场景,当httpc:request_uri返回错误时,res会是nil,直接访问res.body会触发Lua运行时错误,导致请求失败。需要先判断请求是否成功:
access_by_lua_block { local cjson = require("cjson") local http = require "resty.http" local default_backend="docs1" local httpc = http.new() local res, err = httpc:request_uri("http://authserver.ingress-nginx-helpers.svc.cluster.local:5000/find-backend", { method = "POST", body = cjson.encode({ real_url = ngx.var.request_uri }), headers = { ["Content-Type"] = "application/json", ["Token"] = ngx.req.get_headers()['token'], ["cookie"] = ngx.req.get_headers()['cookie'] } }) -- 处理请求authserver失败的情况 if not res then ngx.log(ngx.ERR, "Failed to call authserver: ", err) ngx.var.proxy_upstream_name = ngx.var.namespace .. "-" .. default_backend .. "-5000" return end local response, decode_err = cjson.decode(res.body) if not response then ngx.log(ngx.ERR, "Failed to decode response: ", decode_err) ngx.var.proxy_upstream_name = ngx.var.namespace .. "-" .. default_backend .. "-5000" else ngx.var.proxy_upstream_name = ngx.var.namespace .. "-" .. response.backend .. "-5000" end }
2. 覆盖默认的proxy_pass配置
需要让NGINX使用你设置的proxy_upstream_name变量作为上游,所以在configuration-snippet中添加proxy_pass指令,覆盖默认的硬编码上游:
annotations: nginx.ingress.kubernetes.io/configuration-snippet: | proxy_pass http://$proxy_upstream_name; access_by_lua_block { -- 上面修复后的Lua代码 }
3. 确保所有后端Service存在
NGINX Ingress Controller只会为集群中存在的Service生成上游配置(命名格式为{namespace}-{service-name}-{port}),所以你需要确保authserver返回的所有backend对应的Service都已部署在集群中,否则NGINX会因找不到上游返回503错误。
4. 验证配置
应用修改后的Ingress配置后,可通过以下命令查看NGINX生成的配置,确认proxy_pass是否使用了变量:
kubectl exec -it <nginx-ingress-controller-pod-name> -n <ingress-namespace> -- cat /etc/nginx/nginx.conf | grep -A 20 "location /api/v1/docs1/docs/custom/"
预期会看到类似配置:
location /api/v1/docs1/docs/custom/ { proxy_pass http://$proxy_upstream_name; ... access_by_lua_block { ... } }
额外注意事项
- 如果后端服务使用不同端口,需在Lua代码中动态拼接正确端口号,确保
proxy_upstream_name格式与Ingress Controller生成的上游名称一致。 - 可开启NGINX debug日志查看
proxy_upstream_name实际值,辅助排查问题:annotations: nginx.ingress.kubernetes.io/configuration-snippet: | proxy_pass http://$proxy_upstream_name; access_by_lua_block { -- 修复后的Lua代码 ngx.log(ngx.DEBUG, "Upstream set to: ", ngx.var.proxy_upstream_name) }
内容的提问来源于stack exchange,提问作者ankit
相关产品推荐
相关产品推荐

