You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:14:53