-
Notifications
You must be signed in to change notification settings - Fork 879
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 a network option to disable default gateway #778
Conversation
@@ -521,6 +527,13 @@ func NetworkOptionDeferIPv6Alloc(enable bool) NetworkOption { | |||
} | |||
} | |||
|
|||
// NetworkOptionDefaultGW returns an option setter to set if a network needs default gateway | |||
func NetworkOptionDefaultGW(defaultGW bool) NetworkOption { |
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 we call it something like NetworkOptionIsolatedNetwork
As a network property, we do not need to talk about default gw network, that is an implementation detail.
I think I read it somewhere people asking for this feature to refer to it as isolated
network.
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 think I may have mentioned it a few times at DockerCon EU 😀
And +1 on calling it "Isolated"
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.
ok, updated
@@ -347,6 +347,7 @@ func (c *controller) NewNetwork(networkType, name string, options ...NetworkOpti | |||
ctrlr: c, | |||
persist: true, | |||
drvOnce: &sync.Once{}, | |||
isolated: true, |
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.
Default behavior is that the network has or will be provided outside connectivity.
This line can be removed
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.
Sorry for the mistake.
@chenchun I think the PR needs more code changes. If we now allow UI to specify a network to be isolated, I am assuming drivers which naturally provide external connectivity (like bridge) need more changes to block the external connectivity if flag is set, or to reject the network creation if they cannot guarantee no external connectivity |
@aboch Should we add an |
@@ -35,6 +35,17 @@ func (ind ErrInvalidNetworkDriver) Error() string { | |||
// BadRequest denotes the type of this error | |||
func (ind ErrInvalidNetworkDriver) BadRequest() {} | |||
|
|||
// ErrNetworkNotSupportIsolation is returned if attempts to create an isolated | |||
// network, but the driver of that cannot guarantee no external connectivity. | |||
type ErrNetworkNotSupportIsolation string |
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.
Let's not define new errors.
Please see #269
How about adding an |
@chenchun @aboch The change being discussed in this PR is required if someone wants to isolate the containers on a overlay network because overlay driver by default doesn't set the ep's Gateway thus triggering libnetwork to provide an endpoint in the default gateway network. But I am not sure if this the right fix for #775. I left a comment for @jc-m to try setting the Gateway in the JoinResponse |
I can see the current libnetwork default behavior/expectation: By default any libnetwork network provides its containers with external connectivity. Either natively (ex. bridge network), or with the help of libnetwork default gw network (for ex. overlay network).
As of now, libnetwork infer whether or not to connect the container to the default gw network from whether the network driver set or does not set the default gateway in the Join JoinInfo interface. Libnetwork could be changed to also check for static route set in JoinInfo when deciding whether to plug the container to the default gw network. But I don't know if that is enough for any sort of remote drivers. If not, then we may need the network driver to tell libnetwork if it needs libnetwork's support to provide external connectivity to the containers on its networks. If the |
Consider this... A plugin that is doing VLAN only (plain linux bridge) and uses a So IMO, we need both:
|
In addition to point 2, I would argue that all networking setup should be delegated to the remote driver, and perhaps provide it with enough information to completely setup the network connectivity. This in my mind is the most flexible way and should enable most use cases. Is there a specific use case to have this partial delegation without full control ? |
Updated PR to add |
I am not sure that have a flag name ExternalConnectivity reflects what is being done. Why not simply name it "NeedGateway" ? I'm sure that external connectivity would require more than just a default gateway. |
@@ -97,11 +97,14 @@ func (sb *sandbox) needDefaultGW() bool { | |||
var needGW bool | |||
|
|||
for _, ep := range sb.getConnectedEndpoints() { | |||
if !ep.getNetwork().ctrlr.drivers[ep.getNetwork().Type()].capability.ExternalConnectivity { |
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.
Please use
ep.getNetwork().driver().capability.ExternalConnectivity
instead
@jc-m Sure we can think of better names for the flag. |
@chenchun
a) Libnetwork fix for (#775): Libnetwork should not connect the container to the default gw network when the network driver has added the default static route (0.0.0.0/0) in the b) Network driver does not want default gateway network for its container (#759): Libnetwork will not connect the container to the default gw network when the network driver sets 2.b) is preferable to the driver capability option because fits in the current protocol and allows a per-container granularity option. |
With regard to the capability to have a per container choice, I agree this is a good call. However, it seems that deriving the intent from returned values is likely less optimal. Why not have options for network drivers like there is for storage drivers and have this be an option (label) passed to the driver at run time ? It would give more flexibility to the user and the driver without having side effect being implemented by the daemon. |
This behavior cannot be left to driver specific options. There is a protocol the network driver has to adhere to during container Join. Libnetwork defines and control this protocol in order to provide the same user experience regardless of the network driver in use. Per container IP allocation is a first class configuration that will be provided via IPAM configuration during endpoint creation (See #707). |
@aboch I don't understand how this is breaking the protocol. Are you saying that you cannot have per driver options ? I did not see anywhere the specification/documentation that libnetwork will create a default route or a an interface and route on bridged network in addition to what is specified in the response. Can you point out where this is documented as I don't see it here. In addition, leaving the ip allocation to the IPAM driver is fine, but there is no way using the IPAM driver to accept or deny an IP address requested by at container creation time. IP allocation is not always dynamic, and not always initiated by a host at the time of instantiation, but maybe implemented by a scheduler requesting the launch of a container allocating the address based on global state. |
@aboch I'm confused. Currently
And how can it be a |
Yes, the driver can't set a valid gateway for some containers and set 0.0.0.0 for some other containers on a given network. But during the network create one can pass an option using -opt to tell the driver if Default GW should be provided by libnetwork for containers on that network. So using on the Join response gives the driver granularity at a per network level than the capability exchange, which is fixed. |
Network create has the provision to pass driver specific options using -opt. But its not interpreted or used by libnetwork all. That is why the protocol between libnetwork and driver has to be used to decide when libnetwork should provide Default GW for the container. Please see my previous reply to @chenchun on this. Instead of using the Gateway IP 0.0.0.0 in the Join response we can add a new boolean (something like NeedDefaultGW) if that makes the interaction more explicit/clear. |
I agree with this. setting gateway ip as 0.0.0.0 is very confusing. Actually, I googled it and it means _that the network is locally connected on that interface and no more hops are needed to get to it_. http://unix.stackexchange.com/questions/94018/what-is-the-meaning-of-0-0-0-0-as-a-gateway |
The suggestion was to use 0.0.0.0 in the Joininfo only as an indication to libnetwork that the driver isn't providing a valid Gateway IP and libnetwork has to provide the Default gw. I think its probably better to add a new boolean. @aboch WDYT ? |
@aboch @chenchun @jc-m @sanimej I agree that having an explicit flag makes it cleaner and easier for drivers to make a more explicit request. But, the flag must be backward compatible to make sure any existing drivers (that may not even use this flag) should work unaffected. Hence, the flag should be named and behave something like : Also, I agree with @aboch & @mrjana that we should pull another PR to address the case of user controlling the functionality. There are more things to consider & we dont this PR to be blocked because of unrelated issues. |
@chenchun i just observed that you already have 2 commits for that :) just split them into 2 different PRs. Also, if you agree with my suggestion of the flag name as Also, any changes to the driver api needs a doc update for the remote drivers. |
Yes, I'll update PR shortly. |
@@ -92,6 +92,8 @@ func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, | |||
return nil | |||
} | |||
|
|||
func (ep *endpoint) DisableGatewayService(diableGatewayService bool) {} |
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.
minor spell check nit : diableGatewayService
… to disable default gateway Signed-off-by: Chun Chen <ramichen@tencent.com>
Thanks @chenchun for making all the changes. LGTM |
Docs needs to be changed. I'll update docs after #796 getting merged. |
@@ -103,6 +103,9 @@ func (sb *sandbox) needDefaultGW() bool { | |||
if ep.getNetwork().Type() == "null" || ep.getNetwork().Type() == "host" { | |||
continue | |||
} | |||
if ep.joinInfo.disableGatewayService { | |||
return false | |||
} |
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 a container has endpoints on two networks with one driver setting disableGatewayService to true and the other one setting to false (default case) what should be the behavior ? If we want to provide the default gateway service in that case it has to be a 'continue' here to loop through the other endpoints.
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.
disableGatewayService
is more like a per sandbox property. If you enable such service during joining one of its endpoints, others will be infected. Since disableGatewayService
is false by default and it becomes true if drivers explicitly setting it to true, I suggest we return false
here.
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.
When a driver sets disableGatewayService
, i assume that the driver is capable of providing the default route for that container. Hence even if 1 endpoint suggests it can provide the default route for the sandbox, then this function must return false as it is implemented now.
Hence, the current change of returning false looks appropriate.
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.
When a driver sets disableGatewayService, i assume that the driver is capable of providing the default route for that container.
Not necessarily. Earlier this assumption was ok because the check was specifically for Gateway IP. Now a driver can set disableGatewayService and doesn't provide gateway IP or static default route.
I am not against this change. But want to make sure there is agreement on the behavior with this change.
@sanimej @chenchun The disable flag does not fit in the @chenchun @jc-m If you agree this is a sandbox property, if that was the original intent, WDYT about moving the flag to Not as part of this PR, this one can go in as is to me. It would be an incremental change. |
LGTM |
Add a network option to disable default gateway
* Update kuryr-libnetwork from branch 'master' - Merge "Handle subnet without gateway" - Handle subnet without gateway * When libnetwork requests the IP address of the gateway (via /IpamDriver.RequestAddress) and the neutron subnet has gateway as None, return '0.0.0.0/0' as a placeholder. * Disable default docker gateway via the 'DisableGatewayService' flag (see moby/libnetwork#778). Change-Id: I3033d28eb268a01de8cf038b1ed20110ca9a31ea Closes-Bug: #1881910
* When libnetwork requests the IP address of the gateway (via /IpamDriver.RequestAddress) and the neutron subnet has gateway as None, return '0.0.0.0/0' as a placeholder. * Disable default docker gateway via the 'DisableGatewayService' flag (see moby/libnetwork#778). Change-Id: I3033d28eb268a01de8cf038b1ed20110ca9a31ea Closes-Bug: #1881910
* When libnetwork requests the IP address of the gateway (via /IpamDriver.RequestAddress) and the neutron subnet has gateway as None, return '0.0.0.0/0' as a placeholder. * Disable default docker gateway via the 'DisableGatewayService' flag (see moby/libnetwork#778). Change-Id: I3033d28eb268a01de8cf038b1ed20110ca9a31ea Closes-Bug: #1881910 (cherry picked from commit 9609936)
* When libnetwork requests the IP address of the gateway (via /IpamDriver.RequestAddress) and the neutron subnet has gateway as None, return '0.0.0.0/0' as a placeholder. * Disable default docker gateway via the 'DisableGatewayService' flag (see moby/libnetwork#778). Change-Id: I3033d28eb268a01de8cf038b1ed20110ca9a31ea Closes-Bug: #1881910 (cherry picked from commit 9609936)
* When libnetwork requests the IP address of the gateway (via /IpamDriver.RequestAddress) and the neutron subnet has gateway as None, return '0.0.0.0/0' as a placeholder. * Disable default docker gateway via the 'DisableGatewayService' flag (see moby/libnetwork#778). Change-Id: I3033d28eb268a01de8cf038b1ed20110ca9a31ea Closes-Bug: #1881910 (cherry picked from commit 9609936)
* When libnetwork requests the IP address of the gateway (via /IpamDriver.RequestAddress) and the neutron subnet has gateway as None, return '0.0.0.0/0' as a placeholder. * Disable default docker gateway via the 'DisableGatewayService' flag (see moby/libnetwork#778). Change-Id: I3033d28eb268a01de8cf038b1ed20110ca9a31ea Closes-Bug: #1881910 (cherry picked from commit 9609936)
Signed-off-by: Chun Chen ramichen@tencent.com
Fixes #759 #775