-
Notifications
You must be signed in to change notification settings - Fork 373
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
[Windows] Implement Windows host configuration #373
[Windows] Implement Windows host configuration #373
Conversation
Thanks for your PR. The following commands are available:
These commands can only be run by members of the vmware-tanzu organization. |
20eed21
to
0fe9324
Compare
/test-all |
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 merged the noencap PR today. I guess you need to rebase your branch and adjust the files for your two PRs.
} | ||
|
||
// prepareHostNetworking returns immediately on Linux. | ||
func (i *Initializer) prepareHostNetworking() 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.
Do you think it makes sense to create a separate interface for OS specific funcs which have different implementations for different OSes, rather than reusing Initializer?
The benefit is reader can easily figure out the OS specific funcs. I am not very sure if it is right way in Go or not.
@tnqn
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 far I see a lot of such cases in K8s are done via _OS.go approach, the reason in my mind is:
-
clean code, no need to have branch/options to switch implementation
-
bit size saving (even in interface way, we shouldn't and can't compile windows impl in linux bit, so there's going to be _OS.go anyway, then why it needs to have an option to select OS based implementation?)
-
it can do more and has less requirement (the different part can be a function, a variable, a struct) while interface way requires well-designed interfaces and strongly consistent code on interface consumer side.
But I haven't experienced this before, I will take a look at more Go projects and suggest.
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 sure if I got all your mean. But even we have an interface, we can still achieve what you said (no extra branch/option, the interface implementation can still be in _OS.go)? If the interface implementation is in the same package then almost no difference from convenience perspective?
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.
Yes, but having this interface or not is not related to OS implementation but whether we want to make it abstract. I'm not against abstracting interface, just prefer not calling platform specific functions with platform specific names on main path.
For example, having a generic function setupExternalNetworking
to call i.iptablesClient.Initialize
in host_configuration_linux.go looks better to me than calling i.iptablesClient.Initialize
directly with a dummy implementation on main path.
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.
Agreed on what you said, we should define generic interface/funcs rather than OS specific ones like iptablesXYZ.
0fe9324
to
87b0a77
Compare
fcccd93
to
04bcf44
Compare
/test-all |
04bcf44
to
89f7989
Compare
89f7989
to
1129c1b
Compare
/test-all |
1129c1b
to
5389252
Compare
/test-all |
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.
Overall LGTM, some comments inline
5389252
to
9c948b5
Compare
/test-all |
9c948b5
to
efb8384
Compare
/test-all |
efb8384
to
c66ba1c
Compare
/test-all |
"k8s.io/klog" | ||
) | ||
|
||
func (c *Controller) reconcileIPTables() 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.
This is the single remaining IPTables logic in main path, could we replace it with a generic function name like others
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.
+1.
To make the code simpler, do you think we can keep the loop for Windows as well, but just change c.iptablesClient.AddPeerCIDR to allowTrafficToPeerCIDR? And then we could even remove node_route_controller_os.go and put allowTrafficToPeerCIDR to host_configuration_os.go?
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.
Actually, the two functions in node_route_controller_os are both to call iptables. If we only keep a single file without any OS suffix, the code would be simpler(it is also the previous version of this PR), but iptables functions will be invoked on Windows. Althought it would be no error returned since I have implemented a dummy implementation on Windows, but it still needs an extra invocation. So I think it should be a trade-off. What's your opinion, @jianjuns @tnqn ?
"k8s.io/klog" | ||
) | ||
|
||
func (c *Controller) reconcileIPTables() 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.
+1.
To make the code simpler, do you think we can keep the loop for Windows as well, but just change c.iptablesClient.AddPeerCIDR to allowTrafficToPeerCIDR? And then we could even remove node_route_controller_os.go and put allowTrafficToPeerCIDR to host_configuration_os.go?
} | ||
|
||
// allowTrafficToPeerCIDR adds iptables rules relevant to peerPodCIDR. | ||
func (c *Controller) allowTrafficToPeerCIDR(peerPodCIDR *net.IPNet, peerNodeIP net.IP) 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.
How about name it allowNodeToPeerCIDRTraffic?
Another question - do you think we should change Linux to SNAT in OVS too, so to unify Windows and Linux? @tnqn
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 will rename the function.
@@ -0,0 +1,30 @@ | |||
package iptables |
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 would agree with what @tnqn said - do not create dummy funcs if they are not needed for an OS.
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 now feel we should create an interface like TrafficFilterClient:
- put the New() func in agent_os.go
- move allowNodeToPeerCIDRTraffic to this interface.
- let iptablesClient implements the interface.
Then we can remove iptables_windows.go (change it to traffic_filter_windows.go).
What you think?
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.
@jianjuns I don't think we could remove iptables_windows.go(or traffic_filter_windows.go) even if we define an interface. Since "iptables" is a Linux specific library, all functions calling this library should be placed in file with _linux suffix, otherwise it should break compiling on Windows. If so, function "allowNodeToPeerCIDRTraffic" must have separate implementations with different OS type, and the WIndows implementation might be an empty function. So do other functions we plan to in the interface.
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.
No, I am not saying we can remove traffic_filter_windows.go. I am just saying we should not call it iptables_windows.go, and if we have an interface, it just includes a single func of allowNodeToPeerCIDRTraffic().
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.
traffic_filter_windows.go should include the implementation of allowNodeToPeerCIDRTraffic().
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 could rename the file as 'traffic_filter_windows.go'.
allowNodeToPeerCIDRTraffic()
should not be the single method of the interface. These methods are required outside package "iptables" on Linux Node: 1) NewClient(), 2) Initialize, 3) Reconcile, 4) AllowNodeToPeerCIDRTraffic. If we define an interface and return it in function "NewClient", all above functions should be defined in the interface, and the OS specific implementations must be privoded.
We have no such functions in current _windows.go file is because we returned the struct directly, and no other functions except for "NewClient" are called outside "iptables" on Windows .
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.
Yes, you need Initialize() at least. NewClient() should not be defined in the interface, but could be in agent_os.go.
For Reconcile() I was thinking you might convert the trafficFilter interface to iptablesClient in node_route_controller_windows.go, and call iptablesClient.reconcile() directly. But if you think that is strange, and not many other funcs, we might add Reconcile() to the interface.
pkg/agent/host_configuration_unix.go
Outdated
} | ||
|
||
// setupExternalNetworking setups iptables chains and rules. | ||
func (i *Initializer) setupExternalNetworking() 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.
Do you think can be merged into prepareHostNetworking()?
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.
It can't be merged into prepareHostNetworking()
if we planned to do SNAT with OpenFlow, for the OVS is not ready when preparing Host Networking on Windows.
But if we could change to use Windows NAT utilities to provide SNAT, it would be OK to merge them.
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. Do you think it can be a good idea to make SNAT by OVS a separate option if it works on Linux as well? But I guess let us keep your current implementation first.
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package util |
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.
@tnqn: do you think we can mvoe files in util/ethtool/ and net_os.go to a single pkg util/net/?
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.
Yes, they sounds close.
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 now feel stronger we should put net_os.go to util/net, and maybe move ethtool files there too. We added more and more funcs 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.
Yes, I plan to move them after this PR and policy only PR is checked in, don't want to make them have to solve conflicts again.
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.
Sounds good.
c66ba1c
to
15b3ca5
Compare
3331efe
to
a33e952
Compare
/test-all |
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.
A minor comment
} | ||
|
||
// PrepareHostNetworking creates HNS Network for containers. | ||
func PrepareHostNetworking(subnetCIDR *net.IPNet, nodeIPNet *net.IPNet) 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.
I am not sure this one and enableHNSOnOVS() should be put inside package util. They sound like some application logics but not utilities?
Should we still have the agent_windows.go? @tnqn
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.
According to the offline disscussion we had last week, I remove the call of function PrepareHostNetworking
from agent.go, and plan to move it to Antrea-Service, that's why I move the function to utils(If it is still not proper, I think a choice is to move it to Antrea-Service). Then the only function differentiates OS in agent should be SNAT. Quan has moved iptables-SNAT to routeClient initialization. Windows is using OpenFlow to provide this feature, and I didn't want to add OFClient as a property of routeClient. So agent_window might be added back in "SNAT" PR.
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, you mean you want to move PrepareHostNetworking() to Service later, or keep it in Agent? If we keep it Agent, I feel it should not be in util, and agent_windows.go is better.
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.
It is planned to move to Service.
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.
Do we have other similar funcs in service code?
In dev env, if we do not have a service, how could we prepare the network before Agent runs?
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.
Got it. I now feel from convenience perspective, seems the logic in agent is more convenient. So, I wonder do we have similar cases in service now (I remember no).
If we anyway will have agent_windows.go for other funcs like NAT, we might put this one there too?
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.
Currently, we only have three functions planned to be in Service: 1) Start/Monitor Agent, 2) Prepare environment including HNS Network; 3) Monitoring ovs-vswitchd service, and recover host network when OVS is down.
No other funcs like PrepareHostNetworking
are in Service.
A bad effect for placing PrepareHostNetworking in Agent is, it will make Agent behavior on Windows different from Linux.
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 assume 2) and 3) (recover host network when OVS is down) are not really relevant right, or 3) is to recover what are changed in 2)?
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.
In my opinion, the latter is a correct relation between 2) and 3), as OVS takes over Windows host network is because of 2), and when OVS is down, the host network should be controlled by Windows system.
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. Then it makes to move them to service.
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package util |
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 now feel stronger we should put net_os.go to util/net, and maybe move ethtool files there too. We added more and more funcs here.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
a33e952
to
ebd18aa
Compare
/test-all |
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage.
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage. Signed-off-by: Rui Cao <rcao@vmware.com>
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage. Signed-off-by: Rui Cao <rcao@vmware.com>
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage. Signed-off-by: Rui Cao <rcao@vmware.com>
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage. Signed-off-by: Rui Cao <rcao@vmware.com>
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage. Signed-off-by: Rui Cao <rcao@vmware.com>
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage. Signed-off-by: Rui Cao <rcao@vmware.com>
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage. Signed-off-by: Rui Cao <rcao@vmware.com>
1. Create Transarent HNS Network in agent initialization. 2. Use netroute to configure routing rules when new Node join the cluster. 3. Extract OS specific functions under pkg/agent to seperate files. 4. Move iptables configuraitons to prepare host networking stage, and Windows create HNS Network at the same stage. Signed-off-by: Rui Cao <rcao@vmware.com>
cluster on Windows.
and Windows creates HNS Network at the same stage.