AlinsRan commented on issue #2822:
URL:
https://github.com/apache/apisix-ingress-controller/issues/2822#issuecomment-5111933292
Thanks for the detailed report. I could not reproduce this, and the premise
it rests on does not hold: APISIX does use `service.hosts` for route matching
when the route itself has no `hosts`.
### APISIX inherits hosts from the service
Both HTTP routers resolve hosts with a service-level fallback.
`apisix/http/router/radixtree_host_uri.lua` (and the same logic in
`apisix/http/route.lua` for `radixtree_uri`):
```lua
local hosts = route.value.hosts
if not hosts then
if route.value.host then
hosts = {route.value.host}
elseif route.value.service_id then
local service = service_fetch(route.value.service_id)
hosts = service.value.hosts
end
end
```
`_M.match` also caches `cached_service_version` alongside
`cached_router_version`, so a change to `service.hosts` rebuilds the router
even when the route object is untouched.
### Reproduction attempt
I built exactly the shape from your report — two services with different
`hosts`, two routes with **no** `hosts`, both `uris: ["/*"]` with `vars:
[["uri","~~","/user$"]]`, priorities 20 and 5 — on
`apache/apisix:3.16.0-debian`:
| setup | tenant-a | tenant-b | unknown host |
|---|---|---|---|
| standalone (`config_provider: yaml`, `PUT /apisix/admin/configs`) |
service A | service B | 404 |
| traditional + etcd (Admin API) | service A | service B | 404 |
| `apisix.router.http: radixtree_uri` | service A | service B | 404 |
Then end-to-end through ADC `0.26.0` against APISIX 3.16.0 (etcd mode),
syncing the same resource layout the controller produces:
```
services: svc-a hosts=[tenant-a.example.com] svc-b
hosts=[tenant-b.example.com]
routes: route-a hosts=None priority=20 route-b hosts=None priority=5
Host: tenant-a.example.com -> upstream 127.0.0.1:1980 (svc-a)
Host: tenant-b.example.com -> upstream 127.0.0.1:1981 (svc-b)
Host: other.example.com -> 404
```
The priority-20 route never captured traffic for `tenant-b`. Changing
`svc-b.hosts` to a third hostname without touching the route took effect
immediately in both modes.
### Why restoring `route.Hosts` is not the fix
The API7 backend in ADC (`libs/backend-api7/src/transformer.ts`) maps only
`service.hosts` — it has no route-level hosts field at all. Setting
`route.Hosts` again would make the local state carry a field the remote dump
can never return, producing a diff and a write on every sync cycle. That is the
regression #2743 fixed.
### What would help
Your report includes the route dump but not the services, which is where the
hosts should be. Could you attach:
1. `curl http://<admin>/apisix/admin/services` — specifically whether the
two services carry `hosts`;
2. exact versions (APISIX, ADC, controller image digest) rather than
`3.16.x` / `0.26.x`;
3. `apisix.router.http` from your APISIX `config.yaml`;
4. the two `ApisixRoute` manifests as applied (`kubectl get apisixroute -o
yaml`).
If the services do carry `hosts` and matching still fails, that is a data
plane issue rather than a translator one. If they do not, the bug is upstream
of `buildRoute` and the dump will show us where.
Independently of this report, the host-isolation semantics are currently not
covered by a negative assertion in e2e — every ApisixRoute case sends the
matching Host and expects 200. I will add a case with two routes on the same
path, different hosts, different backends and different priorities, asserting
each host reaches its own backend and an unknown host gets a 404.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]