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 knobs on LB sandbox #2154

Merged
merged 1 commit into from
Jul 3, 2018
Merged

Add knobs on LB sandbox #2154

merged 1 commit into from
Jul 3, 2018

Conversation

fcrisciani
Copy link

Refactored the ostweaks file and made it more generic to be reused.

Related to moby/moby#8795

@codecov-io
Copy link

codecov-io commented May 18, 2018

Codecov Report

❗ No coverage uploaded for pull request base (master@9e422a6). Click here to learn what that means.
The diff coverage is 9.47%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #2154   +/-   ##
=========================================
  Coverage          ?   40.33%           
=========================================
  Files             ?      141           
  Lines             ?    22550           
  Branches          ?        0           
=========================================
  Hits              ?     9096           
  Misses            ?    12120           
  Partials          ?     1334
Impacted Files Coverage Δ
store.go 60.43% <0%> (ø)
osl/namespace_linux.go 34.59% <0%> (ø)
osl/kernel/knobs.go 0% <0%> (ø)
endpoint_info.go 59.33% <0%> (ø)
drivers/overlay/ostweaks_linux.go 0% <0%> (ø)
service_common.go 4.16% <0%> (ø)
default_gateway.go 26.08% <0%> (ø)
service_linux.go 1.31% <1.13%> (ø)
sandbox.go 45.69% <20%> (ø)
network.go 62.6% <21.42%> (ø)
... and 2 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9e422a6...43e2b5c. Read the comment docs.

@fcrisciani fcrisciani force-pushed the ipvs-sysctl branch 4 times, most recently from 9d30cc8 to cb50c90 Compare May 19, 2018 00:31
Copy link
Contributor

@ctelfer ctelfer left a comment

Choose a reason for hiding this comment

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

There are some issues w/ CI that I think are just a matter of including the wrong package in a few places.

Aside from that my only major concern is with the ApplyOSTweaks() interface method added to osl/sandbox.go. See comment for details.

"Indicates if the test is running in a container")
// this takes care of the incontainer flag
_ "github.com/docker/libnetwork/netutils"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be "github.com/docker/libnetwork/testutils" instead of "...netutils"? Would explain why Circle-CI is failing.

Copy link
Author

Choose a reason for hiding this comment

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

totally, I'm not sure how did I put the wrong package there.

var (
dbPort int32 = 10000
runningInContainer = flag.Bool("incontainer", false, "Indicates if the test is running in a container")
_ "github.com/docker/libnetwork/netutils"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

same here?

Copy link
Author

Choose a reason for hiding this comment

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

yep in all the tests

continue
}
logrus.Debugf("updated kernel parameter %s = %s (was %s)", k, v.Value, oldv)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

As long as we are touching this ... do we want to add a debug log when we don't update a property to indicate why? Something like:

} else if oldv != v.Value {
        logrus.Debugf("leaving kernel parameter %s as %s instead of updating to %s", k, oldv, v.Value)
}

Just a thought.

"github.com/stretchr/testify/assert"

_ "github.com/docker/libnetwork/netutils"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

here again for testutils instead of netutils?


var runningInContainer = flag.Bool("incontainer", false, "Indicates if the test is running in a container")
_ "github.com/docker/libnetwork/netutils"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

last one for testutils?

osl/sandbox.go Outdated
@@ -70,6 +70,9 @@ type Sandbox interface {

// restore sandbox
Restore(ifsopt map[string][]IfaceOption, routes []*types.StaticRoute, gw net.IP, gw6 net.IP) error

// ApplyOSTweaks applies operating system specific knobs on the sandbox
ApplyOSTweaks()
Copy link
Contributor

Choose a reason for hiding this comment

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

It would probably be good to flesh this interface out a bit. As written, I don't get what this function actually means. If there are special OS tweaks that apply to all sandboxes, then why not do it in NewSandbox(). If it only applies to some sandboxes (which is what we really want here) how does the sandbox determine whether it is special? Right now, we just have this optionally called in createLoadBalancerSandbox(), but what if there are other types of sandboxes that need OS tweaks down the road? Do they all get the same sets of tweaks?

There are at least two two general paths forward that have better "code hygiene".

  1. Rename this to ApplyLoadBalancerOSTweaks() -- that makes it clear that this is just for tweaking that particular special type of sandbox.
  2. Change the method signature to receive some kind of parameters indicating what kinds of tweaks to apply. A simplistic view would be a bool parameter indicating the LB sandbox status. But a more generic approach would be a map[string]string parameter which indicates some kind of OS-specific setting that should be applied. In the case of load balancer sandboxes it would likely be something as simple as map[string]string{"loadBalancer":"true"}. The OS specific sandbox could would then look through the keys to see which of key's it might have a tweak perhaps modulating how to apply it based on the value. Then it would know what to try to apply.

Option 1 is the simplest and its reasonably clean. I would go with this if we really don't foresee any other types of sandbox tweaks down the road ever.

Option 2 may be over-engineering a bit for the purpose. But it is the better long term interface IMHO. If we imagine that there could be other OS-specific tweaks, then we'd have to change the sandbox interface again down the road with Option 1. Option 2, by contrast would require changes only to the backend code for those OSes affected by the new option and nothing to the interface at all.

BTW, with Option 2 controller.go code above would then change to:

sb.osSbox.ApplyOSTweaks(map[string]string{"loadBalancer": fmt.Sprintf("%v", sb.loadBalancer)})

Come to think of it, it would be good to options well documented so, we might want to put the key ("loadBalancer") as a constant in osl/sandbox.go.

There may well be other options. That's just what has occurred to me so far.

Copy link
Author

Choose a reason for hiding this comment

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

I was trying to keep it simple because I'm not sure which is going to be the next use of it, so did not want to push into a direction that makes it less flexible when the next purpose will be found.
Anyway I agree with the general POV that this is a too simplistic and not power approach.
I personally don't like the option 1, only because will put assumption on the sandbox interface, that not necessarily reflects a generic sandbox implementation.
I like more the second option, so my proposal is to change the interface of the sandbox method like:

ApplyOSTweaks(tweaks map[string]*kernel.OSValue)

WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Option 2 sounds sounds cleaner way for long run .

Copy link
Contributor

Choose a reason for hiding this comment

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

Was the idea that each OSL would declare something like:

var SandboxLoadBalancerTweaks = map[string]*kernel.OSValue{...}  // possibly empty

and then the createLoadBalancerSandbox() function would do something like:
sb.ApplyOSTweaks(osl.SandboxLoadBalancerTweaks)?

This could be a reasonable approach. I think that means less complexity in the solution with the cost of requiring changes in all (ok: all 2-3 of them :) ) OSLs whenever we add a sandbox tweak.

@fcrisciani fcrisciani force-pushed the ipvs-sysctl branch 3 times, most recently from 11cf211 to 8ebae36 Compare May 21, 2018 20:15
@ctelfer
Copy link
Contributor

ctelfer commented May 21, 2018

Overall, I like the new approach @fcrisciani just posted much better. My one suggestion (which I'd love to hear other's opinions on as well) would be to remove the loadBalancer bool from sandbox.go and replace it with oslTypes []osl.SandboxType. If we do that then OptionLoadBalancer becomes:

func OptionLoadBalancer() SandboxOption {
	return func(sb *sandbox) {
		sb.oslTypes = append(sb.oslTypes, osl.SandboxTypeLoadBalancer)
	}
}

and the controller.go simply becomes:

sb.osSbox.ApplyOSTweaks(sb.oslTypes...)

This makes NewSandbox() stop testing for special cases and it allows adding different types of tweaks w/o necessarily having to change the sandbox data structure down the road.

@fcrisciani
Copy link
Author

@ctelfer yep makes sense the only think that stopped me to follow such approach was that at this point Ingress should follow the same approach of being a sandbox property, but then now being a slice of properties will make it more difficult to identify it, pushing the need to have it as a map, but that will make it more complex for the real objective of this patch. Thoughts?

@ctelfer
Copy link
Contributor

ctelfer commented May 21, 2018

Agree that this change would suggest folding 'ingress' into the other types .... So I guess that points to two possible questions:

  1. Is ingress special enough that it clearly should be treated differently than other possible 'types'?
  2. Is loadBalancer special enough that it clearly needs to be called out as its own property?

Re: 1 -- I think the answer is "yes". We can only have 1 ingress sandbox per controller and being ingress affects the redirect rules programmed into the sandbox. So I don't think we want to remove this field.

Re: 2 -- I could see it being state that we want to return in a query. But it has no real impact to the logic of the OSL code at the moment. So ... dunno ... could go either way with its inclusion. It's not currently that useful, but conceptually it seems correct.

We could also keep the two ideas (OSL tweaks and load-balancer-ness) orthogonal/separate. In that model we have the loadBalancer bool as well as the oslTypes []osl.SandboxType fields. The load balancer option would set both of them. The former would be used to answer queries as well and be something we key off of for any non-OS-specific libnetwork code pertaining to load-balancer sandboxes. The latter is purely for OSL bringup/tuning. Intersection is only conceptually because the option ties them together.

@fcrisciani fcrisciani force-pushed the ipvs-sysctl branch 2 times, most recently from 3edf68c to 43e2b5c Compare May 23, 2018 21:16
@fcrisciani
Copy link
Author

@ctelfer fair enough, at the moment I removed the bool for the load balancer and I added the type Ingress and LB

Copy link
Contributor

@ctelfer ctelfer left a comment

Choose a reason for hiding this comment

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

Thanks! LGTM

Refactor the ostweaks file to allows a more easy reuse
Add a method on the osl.Sandbox interface to allow setting
knobs on the sandbox

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
@fcrisciani
Copy link
Author

cc @ctelfer this was already been approved, but can you LGTM again if your opinion did not change about it?

@fcrisciani
Copy link
Author

lint failed because of no engine available but the re run passed, merging it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants