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

node: Install individual per node routes #1888

Merged
merged 1 commit into from
Oct 30, 2017
Merged

node: Install individual per node routes #1888

merged 1 commit into from
Oct 30, 2017

Conversation

tgraf
Copy link
Member

@tgraf tgraf commented Oct 29, 2017

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]

@tgraf tgraf added the wip label Oct 29, 2017
@tgraf tgraf requested review from a team October 29, 2017 17:40
@tgraf tgraf requested a review from a team as a code owner October 29, 2017 17:40
@tgraf tgraf requested a review from a team October 29, 2017 17:40
@tgraf tgraf requested a review from a team as a code owner October 29, 2017 17:40
@cilium cilium deleted a comment from houndci-bot Oct 29, 2017
@tgraf tgraf force-pushed the individual-routes branch 2 times, most recently from 0f7da8d to 535d68d Compare October 29, 2017 21:06
@tgraf tgraf added pending review area/daemon Impacts operation of the Cilium daemon. sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. sig/k8s Impacts the kubernetes API, or kubernetes -> cilium internals translation layers. and removed wip labels Oct 29, 2017
@tgraf tgraf force-pushed the individual-routes branch 2 times, most recently from 6b75af5 to 24e9319 Compare October 30, 2017 08:32
package node

const (
fieldRoute = "route"
Copy link
Member

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

Copy link
Member Author

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

Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved to logfields

}

func replaceNodeRoute(ip *net.IPNet) {
link, err := netlink.LinkByName("cilium_host")
Copy link
Member

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

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

if err := netlink.RouteAdd(&route); err != nil {
scopedLog.WithError(err).Error("Unable to add node route")
} else {
scopedLog.Info("Installed node route")
Copy link
Member

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?

Copy link
Member Author

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.

return nil
}

func replaceNodeRoute(ip *net.IPNet) {
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

IP4_SVC_RANGE=$8
IP6_SVC_RANGE=$9
MODE=${10}
IP4_HOST=$3
Copy link
Contributor

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.

Copy link
Member Author

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)
Copy link
Contributor

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.

Copy link
Contributor

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)
Copy link
Contributor

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.

Copy link
Contributor

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)
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

package node

const (
fieldRoute = "route"
Copy link
Contributor

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.

nodes = map[Identity]*Node{}
ciliumHostInitialized = false
usePerNodeRoutes = false
auxPrefixes = []*net.IPNet{}
Copy link
Contributor

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?

Copy link
Member Author

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}
Copy link
Contributor

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?

Copy link
Member Author

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

func installHostRoutes() {
if !ciliumHostInitialized {
return
}
Copy link
Contributor

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.

Copy link
Member Author

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.

@tgraf tgraf force-pushed the individual-routes branch 2 times, most recently from 98afafe to c28d66d Compare October 30, 2017 12:35
Copy link

@manalibhutiyani manalibhutiyani left a 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]>
@tgraf tgraf added the release-note/minor This PR changes functionality that users may find relevant to operating Cilium. label Oct 30, 2017
@tgraf tgraf merged commit 2b3301f into master Oct 30, 2017
@tgraf tgraf deleted the individual-routes branch October 30, 2017 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/daemon Impacts operation of the Cilium daemon. release-note/minor This PR changes functionality that users may find relevant to operating Cilium. sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. sig/k8s Impacts the kubernetes API, or kubernetes -> cilium internals translation layers.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cilium agent drops all DNS requests host is trying to make
5 participants