Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add route to local table for non loopback devices #138

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

hown3d
Copy link

@hown3d hown3d commented Sep 25, 2024

What this PR does / why we need it:
When introducing the management of network interfaces with #128, using another interface than lo in g/g currently results in connectivity issues.
Reason is that loopback devices automatically add routes for IP addresses assigned to it to the local routing table.

This PR creates the needed routes in the local table to ensure routing of the apiserver IP works.
Route is only added when not using the lo interface.

Special notes for your reviewer:
The constants used from the golang.org/x/sys/unix package are only visible when GOOS is linux.
For more information see rtnetlink manpage

Lukas Hoehl added 3 commits September 25, 2024 14:15
Signed-off-by: Lukas Hoehl <[email protected]>
Signed-off-by: Lukas Hoehl <[email protected]>
@hown3d hown3d requested a review from a team as a code owner September 25, 2024 13:20
@gardener-robot gardener-robot added the needs/review Needs review label Sep 25, 2024
@gardener-robot
Copy link

@hown3d Thank you for your contribution.

@gardener-robot gardener-robot added the size/m Size of pull request is medium (see gardener-robot robot/bots/size.py) label Sep 25, 2024
@gardener-robot-ci-2
Copy link
Contributor

Thank you @hown3d for your contribution. Before I can start building your PR, a member of the organization must set the required label(s) {'reviewed/ok-to-test'}. Once started, you can check the build status in the PR checks section below.

Copy link
Member

@ScheererJ ScheererJ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it required to add the routes? It seems like the same is working without routes in node-local-dns where a device nodelocaldns is created with a specific IP address. Please explain.

@hown3d
Copy link
Author

hown3d commented Sep 28, 2024

Why is it required to add the routes? It seems like the same is working without routes in node-local-dns where a device nodelocaldns is created with a specific IP address. Please explain.

Nodelocaldns uses a different scope for the ip addresses added to the dummy device.
https://github.com/kubernetes/dns/blob/fa0192f004c9571cf24d8e9868be07f57380fccb/pkg/netif/netif.go#L19 -> Scope is 0 which correlates to RT_SCOPE_UNIVERSE.
apiserver-proxy is using scope host instead.

Additionally nodelocaldns deploys IPTables rules that create the rules in the local routing table: https://github.com/kubernetes/dns/blob/fa0192f004c9571cf24d8e9868be07f57380fccb/cmd/node-cache/app/cache_app.go#L112-L145

The kernel does a lookup in the local route table when a packet with a IP enters to see if a route for the address exists. There is a difference how the lookup works by scope:

  • global
    • Lookup local route table: Route exists? -> Keep packet in local stack. If the route does not exist, look up in global routing table.
  • host
    • Lookup local route table: Route exists? -> Keep packet in local stack. If the route does not exist the packet is black holed.

Since the lo interface creates routes in the local table by default, there is no need to add them manually.
Other interfaces need to populate the local route table to ensure the ip address is routable on the host.
If there's no route for a IP address with scope host, the kernel even refuses processes to bind to the address.
E.g. envoy errors when using interface != lo and scope host without a route being present:
[2024-09-28 17:11:58.019][1][info][main] [source/server/server.cc:1029] exiting cannot bind '100.83.17.145:443': Cannot assign requested address

@ScheererJ
Copy link
Member

Why is it required to add the routes? It seems like the same is working without routes in node-local-dns where a device nodelocaldns is created with a specific IP address. Please explain.

Nodelocaldns uses a different scope for the ip addresses added to the dummy device. https://github.com/kubernetes/dns/blob/fa0192f004c9571cf24d8e9868be07f57380fccb/pkg/netif/netif.go#L19 -> Scope is 0 which correlates to RT_SCOPE_UNIVERSE. apiserver-proxy is using scope host instead.

Why do we use host scope instead of universe scope if it makes our life more complicated?

Additionally nodelocaldns deploys IPTables rules that create the rules in the local routing table: https://github.com/kubernetes/dns/blob/fa0192f004c9571cf24d8e9868be07f57380fccb/cmd/node-cache/app/cache_app.go#L112-L145

I am not sure I can follow. How do iptables rules create routing rules? The NOTRACK rules should just prevent from conntrack entries being created and the ACCEPT rules allow the traffic.
Could you please explain in more detail?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs/review Needs review size/m Size of pull request is medium (see gardener-robot robot/bots/size.py)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants