-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
node: Install individual per node routes #1888
Conversation
0f7da8d
to
535d68d
Compare
6b75af5
to
24e9319
Compare
pkg/node/logfields.go
Outdated
package node | ||
|
||
const ( | ||
fieldRoute = "route" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, which package will have its logfields defined? CC @raybejjani
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log fields which are specific to a package don't need to be global but I'm open to a discussion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. fieldRoute
is used in an Error message, and it is likely to be common in logs. I'd vote to put it in logfields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to logfields
pkg/node/manager.go
Outdated
} | ||
|
||
func replaceNodeRoute(ip *net.IPNet) { | ||
link, err := netlink.LinkByName("cilium_host") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a const for cilium_host
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
pkg/node/manager.go
Outdated
if err := netlink.RouteAdd(&route); err != nil { | ||
scopedLog.WithError(err).Error("Unable to add node route") | ||
} else { | ||
scopedLog.Info("Installed node route") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I was a user, I wouldn't understand which node route is this. Can you add the specific route that was installed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scopedLog
contains the full route description as field.
pkg/node/manager.go
Outdated
return nil | ||
} | ||
|
||
func replaceNodeRoute(ip *net.IPNet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a description to that function of what it does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
24e9319
to
79c1314
Compare
IP4_SVC_RANGE=$8 | ||
IP6_SVC_RANGE=$9 | ||
MODE=${10} | ||
IP4_HOST=$3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not too relevant, but we could use shift
to avoid renumbering args on refactor. This doesn't happen too often, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scanf is working on removing init.sh
entirely in favor of a golang native implementation.
if err != nil { | ||
log.WithError(err).WithField(logfields.V6Prefix, v6ServicePrefix).Fatal("Invalid IPv6 service prefix") | ||
} | ||
|
||
node.AddAuxPrefix(ipnet) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be the else case for if err != nil
since we don't exit/return on error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, nevermind, it's a fatal
if err != nil { | ||
log.WithError(err).WithField(logfields.V4Prefix, v4ServicePrefix).Fatal("Invalid IPv4 service prefix") | ||
} | ||
|
||
node.AddAuxPrefix(ipnet) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be the else case for if err != nil since we don't exit/return on error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, nevermind, it's a fatal
pkg/k8s/init.go
Outdated
|
||
k8sNode, err := GetNode(Client(), nodeName) | ||
if err != nil { | ||
return fmt.Errorf("unable to retrieve k8s node information: %s", err) | ||
} | ||
|
||
node := ParseNode(k8sNode) | ||
n := ParseNode(k8sNode) | ||
log.Infof("Retrieved node's %s information from kubernetes", n.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.WithField(logfields.NodeName, n.Name).Info("Retrieved node information from kubernetes")
to be consistent with our logrus usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
pkg/node/logfields.go
Outdated
package node | ||
|
||
const ( | ||
fieldRoute = "route" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. fieldRoute
is used in an Error message, and it is likely to be common in logs. I'd vote to put it in logfields.
pkg/node/manager.go
Outdated
nodes = map[Identity]*Node{} | ||
ciliumHostInitialized = false | ||
usePerNodeRoutes = false | ||
auxPrefixes = []*net.IPNet{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since these are package variables (which is probably unintentional) and file variables, could you comment what/when/how they're to be used. In particular, what is mutex protecting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
log.WithError(err).Error("Unable to add nexthop route") | ||
} | ||
|
||
route := netlink.Route{LinkIndex: link.Attrs().Index, Dst: ip, Gw: via, Src: local} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We delete then add the same route object. Does this work because netlink.RouteDel matches only on some of the fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was worried that RouteReplace
does not have the correct semantics. I double checked and it does so I will be replacing this with a single netlink.RouteReplace()
call
pkg/node/manager.go
Outdated
func installHostRoutes() { | ||
if !ciliumHostInitialized { | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we went to all the effort to guard this (in InstallHostRoutes and here in installHostRoutes) we should log something here, or return an error that can be logged at the callers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The case where we might hit this is if the Kubernetes watcher is installed before we put the cilium_host
device in place in which case we will start collecting node information without being able to install the routes. They will be installed when we add the device. I'll add a debug statement to indicate that installation was deferred.
98afafe
to
c28d66d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
The route pointing packets from the host to IPs managed by other nodes has been covered by a single cluster wide route prefix which covered all nodes. This did not allow to have any non Cilium IPs unless the IPs were associated to the local host. * Merge node and nodeaddress package together as they depend on each other. * Move route and address addition from the init.sh script to golang native code in pkg/node to allow tiggering route additions based on events. * Add a per node route for each node discovered in the cluster * Per node routes are enabled by default when running on Kubernetes but can be disabled with --single-cluster-route. Fixes: #1846 Signed-off-by: Thomas Graf <[email protected]>
c28d66d
to
fcd2e39
Compare
The route pointing packets from the host to IPs managed by other nodes
has been covered by a single cluster wide route prefix which covered all
nodes. This did not allow to have any non Cilium IPs unless the IPs were
associated to the local host.
Merge node and nodeaddress package together as they depend on each
other.
Move route and address addition from the init.sh script to golang
native code in pkg/node to allow tiggering route additions based
on events.
Add a per node route for each node discovered in the cluster
Fixes: #1846
Signed-off-by: Thomas Graf [email protected]