Route actor hosts by optional "<port>-" prefix#296
Open
rogeroger (rogeroger-yu) wants to merge 2 commits into
Open
Route actor hosts by optional "<port>-" prefix#296rogeroger (rogeroger-yu) wants to merge 2 commits into
rogeroger (rogeroger-yu) wants to merge 2 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Encode an optional target service port in the left-most DNS label of an
actor host, so a single actor can expose multiple in-actor services
without dynamic Envoy listeners or per-actor reverse proxies:
<actor-id>.<suffix> -> <worker-ip>:80 (unchanged default)
<port>-<actor-id>.<suffix> -> <worker-ip>:<port>
parseActorID now returns the parsed port alongside the actor ID. A
left-most label matching ^([0-9]+)-(.+)$ is treated as port-prefixed;
the port is validated to be in 1..65535 and otherwise fails routing
rather than silently falling back. Hosts without a numeric prefix keep
routing to port 80, so existing actors are unaffected.
The deterministic rule means actor IDs minted for multi-port access must
not themselves begin with "<digits>-"; this is the one documented
ambiguity, since DNS-1123 permits such labels.
Refs agent-substrate#265
The actor prerouting DNAT previously matched only TCP/80 and rewrote both the destination address and port to the actor veth on port 80. That made port-prefixed actor routing a no-op end to end: atenet would forward to <podIP>:<port> for a "<port>-<actor>" host, but any port other than 80 was dropped before reaching the actor. Match all inbound TCP destined for the worker pod IP and DNAT only the destination address to the actor veth, leaving the port unchanged (RegProtoMin unset). The actor decides which ports it listens on. ateom serves its own control RPCs over a unix socket, not a pod-IP TCP port, so this catch-all does not shadow the control path. This is the actor-network half of port-prefixed routing; the routing half lives in atenet's parseActorID. Refs agent-substrate#265
21b6202 to
22fd06c
Compare
Collaborator
|
Would be good to resolve the conversations on the linked issue before we get too far along in the implementation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Encode an optional target service port in the left-most DNS label of an actor host, so a single actor can expose multiple in-actor services without dynamic Envoy listeners or per-actor reverse proxies.
Examples:
This is the design proposed in #265.
Why this shape
atenet.actors.resources.substrate.ate.dev.Changes
Two layers had to change for this to work end to end:
atenetrouting (cmd/atenet/internal/router):parseActorIDnow returns(actorID, port). A left-most label matching^([0-9]+)-(.+)$is parsed as<port>-<actorID>; the port is validated to be in1..65535and otherwise fails routing with a 404 rather than silently falling back.handleRequestHeadersforwards to<workerIP>:<port>instead of a hard-coded:80.ateom-gvisoractor DNAT (cmd/ateom-gvisor/main.go): the actor prerouting DNAT previously matched only TCP/80 and rewrote both address and port to the actor veth on 80, which made port-prefixed routing a no-op end to end. It now matches all inbound TCP to the worker pod IP and DNATs only the destination address to the actor veth, preserving the original port. (ateomserves its own RPCs over a unix socket, not a pod-IP TCP port, so this catch-all does not shadow the control path.)Ambiguity
Actor IDs that themselves start with
<digits>-are interpreted as port-prefixed. DNS-1123 permits such labels, so this is a documented, deterministic rule: tools that mint actor IDs for multi-port access must avoid IDs beginning with<digits>-. IDs that start with digits but have no<digits>-prefix (e.g.123abc) keep routing to the default port.Tests
extproc_in_test.gocover default-port routing, prefixed-port routing, min/max ports, port 0, out-of-range ports, leading-zero normalization, and the existing host/connection-port parsing.my-actor.<suffix>-> 200, served from port 808080-my-actor.<suffix>-> 200, served from port 8080 (distinct response body)0-my-actor.<suffix>/99999-my-actor.<suffix>-> 404 (invalid port)atenetlogs confirmtargetAddrof<ip>:8080vs<ip>:80.Notes