-
Notifications
You must be signed in to change notification settings - Fork 368
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] Kube-proxy replacement for NodePort #2863
Conversation
Codecov Report
@@ Coverage Diff @@
## main #2863 +/- ##
==========================================
+ Coverage 60.32% 60.50% +0.17%
==========================================
Files 283 283
Lines 23603 23644 +41
==========================================
+ Hits 14239 14305 +66
+ Misses 7845 7808 -37
- Partials 1519 1531 +12
Flags with carried forward coverage won't be shown. Click here to find out more.
|
0400651
to
6c65f47
Compare
6c65f47
to
a31fdbe
Compare
For the reviewers, please notice that this PR is base on ClusterIP one which still changes from time to time. So just review the last commit is enough. Thank you. |
pkg/agent/openflow/pipeline.go
Outdated
// it cannot be 169.254.1.0 through 169.254.255.255. | ||
// So 169.254.0.253 is a valid one. | ||
ServiceNodePortVirtualIP = net.ParseIP("169.254.0.253").To4() | ||
ServiceNodePortVirtualIPNet = util.NewIPNet(ServiceNodePortVirtualIP) |
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 provide the referrence link why 169.254.0.253
is valid.
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.
Updated.
pkg/agent/openflow/pipeline.go
Outdated
c.pipeline[serviceClassifierTable].BuildFlow(priorityNormal). | ||
Cookie(c.cookieAllocator.Request(cookie.Service).Raw()). | ||
MatchProtocol(ipProtocol). | ||
MatchDstIP(ServiceNodePortVirtualIP). |
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.
Is it possible to use ServiceNodePortVirtualIP
on Linux, so that we could have a unique flow for both Linux and Window? @hongliangl @lzhecheng
5d8db89
to
e428019
Compare
pkg/agent/config/node_config.go
Outdated
VirtualServiceIPv4 = net.ParseIP("169.254.169.253") | ||
VirtualServiceIPv6 = net.ParseIP("fc01::aabb:ccdd:eeff") | ||
VirtualServiceIPv4 = net.ParseIP("169.254.169.253") | ||
VirtualServiceIPv4Net = util.NewIPNet(VirtualServiceIPv4) |
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 it is used in route_windows.go only, probably define a local variable there.
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.
Updated in the cluster ip 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.
forgot to update?
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.
Forgot to update after rebasing. It is correct now.
@@ -190,8 +197,30 @@ func (c *Controller) removeStaleGatewayRoutes() error { | |||
desiredPodCIDRs = append(desiredPodCIDRs, podCIDRs...) | |||
} | |||
|
|||
// TODO: This is not the best place to keep the ClusterIP Service routes. |
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, it is strange we reconcile Service routes here. Should we reconcile Service routes from proxier? @hongliangl @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 think we shouldn't use more than one reconcile functions. If so, they may delete the routes added by another function.
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 the current conclusion is that these code is needed for function before a refactor is conducted. Such refactor will be in another PR.
3bc578d
to
c8640e9
Compare
pkg/agent/route/route_windows.go
Outdated
vRoute := &util.Route{ | ||
LinkIndex: linkIndex, | ||
DestinationSubnet: virtualServiceIPv4Net, | ||
GatewayAddress: net.IPv4zero, | ||
RouteMetric: util.MetricHigh, | ||
RouteMetric: metric, |
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 change seems pointless.
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.
Updated. Originally I'd like to have 2 routes here so I defined a variable.
pkg/agent/config/node_config.go
Outdated
VirtualServiceIPv4 = net.ParseIP("169.254.169.253") | ||
VirtualServiceIPv6 = net.ParseIP("fc01::aabb:ccdd:eeff") | ||
VirtualServiceIPv4 = net.ParseIP("169.254.169.253") | ||
VirtualServiceIPv4Net = util.NewIPNet(VirtualServiceIPv4) |
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.
forgot to update?
pkg/agent/openflow/pipeline.go
Outdated
MatchProtocol(ipProtocol). | ||
MatchDstIP(config.VirtualServiceIPv4). | ||
Action().LoadRegMark(ToNodePortAddressRegMark). | ||
Done()) |
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.
Isn't this flow duplicated with the above one?
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.
Removed.
pkg/agent/route/route_windows.go
Outdated
@@ -36,6 +36,9 @@ import ( | |||
const ( | |||
inboundFirewallRuleName = "Antrea: accept packets from local Pods" | |||
outboundFirewallRuleName = "Antrea: accept packets to local Pods" | |||
|
|||
antreaNat = "antrea-nat" | |||
antreaNatStaticMapping = "antrea-natstaticmapping" |
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.
Is this nat specific for nodeport traffic? If yes, could we name it in a way that can be associated with NodePort?
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, updated.
pkg/agent/route/route_windows.go
Outdated
@@ -377,6 +389,7 @@ func (c *Client) DeleteSNATRule(mark uint32) error { | |||
} | |||
|
|||
func (c *Client) AddNodePort(nodePortAddresses []net.IP, port uint16, protocol binding.Protocol) error { | |||
util.AddNetNatStaticMapping(antreaNatStaticMapping, "0.0.0.0", port, config.VirtualServiceIPv4, port, string(protocol)) |
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 should handle the 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.
Updated.
pkg/agent/route/route_windows.go
Outdated
@@ -239,6 +244,13 @@ func (c *Client) addVirtualServiceIPRoute(isIPv6 bool) error { | |||
return err | |||
} | |||
klog.InfoS("Added virtual Service IP neighbor", "neighbor", vNeighbor) | |||
|
|||
// For NodePort Service, a new NetNat for NetNatStaticMapping is needed. | |||
err := util.NewNetNat(antreaNatStaticMapping, config.VirtualServiceIPv4Net) |
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.
VirtualServiceIPv4Net is the original IP or the translation IP?
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.
virtualServiceIPv4Net
is the translated: 169.254.0.253/32
c8640e9
to
4a5b8b4
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.
The code LGTM overall, why don't squash the commits and add the description to the PR description as well?
I think it doesn't respect nodePortAddresses
? Is it possible to support it? If yes, we should have an issue to track it. Regardless of whether it's possible, the comment of nodePortAddresses
should mention it doesn't work for Windows yet.
61e6258
to
a046131
Compare
a046131
to
39e6412
Compare
@tnqn I have squashed the commits and added a TODO for nodePortAddresses. I will create an issue for it later. Besides, I updated NetNatStaticMapping powershell 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.
Found two minor problems in the final review
pkg/agent/util/net_windows.go
Outdated
@@ -658,6 +657,67 @@ func CreateNetNatOnHost(subnetCIDR *net.IPNet) error { | |||
return nil | |||
} | |||
|
|||
func ReplaceNetNatStaticMapping(netNatName string, externalIPAddr string, externalPort uint16, internalIPAddr net.IP, internalPort uint16, proto string) 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.
- It's strange that
externalIPAddr
is a string butinternalIPAddr
isnet.IP
, can we unify it to string? - The function doesn't really do "replace": replace means it searchs the mapping based on the natName, externalIPAddress, externalPort, protocol, and overrides the mapping if the internalIPAddr, internalPort don't match. In current code, even if there is a mapping that have same external IP and port but different internal IP and port, it's not able to replace it.
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.
- Updated.
- Now
GetNetNatStaticMapping
doesn't filter with internal IP and Port. Instead inReplaceNetNatStaticMapping
, it checks if internal IP and Port match inputs.
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 don't see it's updated.
- It does not make sense to pass internalIPAddr, internalPort to
GetNetNatStaticMapping
and just ingore them in the body.
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, some git issue. Now it is correct.
- Removed these parameters.
pkg/agent/util/net_windows.go
Outdated
} | ||
|
||
// GetNetNatStaticMapping checks if a NetNatStaticMapping exists. | ||
func GetNetNatStaticMapping(netNatName string, externalIPAddr string, externalPort uint16, internalIPAddr net.IP, internalPort uint16, proto string) (string, 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.
ditto
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.
Updated
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.
ditto
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.
Updated this time.
39e6412
to
4856ad8
Compare
4856ad8
to
64dfd92
Compare
pkg/agent/util/net_windows.go
Outdated
@@ -658,6 +657,67 @@ func CreateNetNatOnHost(subnetCIDR *net.IPNet) error { | |||
return nil | |||
} | |||
|
|||
func ReplaceNetNatStaticMapping(netNatName string, externalIPAddr string, externalPort uint16, internalIPAddr net.IP, internalPort uint16, proto string) 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 don't see it's updated.
- It does not make sense to pass internalIPAddr, internalPort to
GetNetNatStaticMapping
and just ingore them in the body.
pkg/agent/util/net_windows.go
Outdated
} | ||
parsed := parseGetNetCmdResult(staticMappingStr, 6) | ||
if len(parsed) > 1 { | ||
return fmt.Errorf("when ReplaceNetNatStaticMapping, number of parsed result of Get-NetNatStaticMapping is larger than 1, %v", parsed) |
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 tested get-netnatstaticmapping, it's not possible to install two mapping with same externalIPAddr+externalPort and different internalIPAddr+internalPort, and it makes sense from the API's perspective. So let's don't add code to handle something that won't happen.
It could just handle found case:
if len(parsed) > 0 {
items := parsed[0]
...
}
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.
Updated.
pkg/agent/util/net_windows.go
Outdated
if err != nil { | ||
return err | ||
} | ||
if err := RemoveNetNatStaticMappingDirect(netNatName, id); err != nil { |
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.
Why Direct
? Maybe you mean RemoveNetNatStaticMappingByID
?
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.
Originally I'd like to emphasize that it runs Remove-NetNatStaticMapping
command directly. But ByID
is good. Updated.
pkg/agent/util/net_windows.go
Outdated
} | ||
|
||
// GetNetNatStaticMapping checks if a NetNatStaticMapping exists. | ||
func GetNetNatStaticMapping(netNatName string, externalIPAddr string, externalPort uint16, internalIPAddr net.IP, internalPort uint16, proto string) (string, 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.
ditto
64dfd92
to
789a7e7
Compare
pkg/agent/util/net_windows.go
Outdated
return err | ||
} | ||
|
||
func RemoveNetNatStaticMapping(netNatName string, externalIPAddr string, externalPort uint16, internalIPAddr string, internalPort uint16, proto string) 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.
Similarly, it doesn't make sense to pass internalIPAddr and internalPort but ignore them in the function, which could give people a pression that it will only remove the mapping when all parameters match.
I understand we want to share some code between ReplaceNetNatStaticMapping
and RemoveNetNatStaticMapping
, then maybe we don't need RemoveNetNatStaticMappingByID
and RemoveNetNatStaticMapping
could have all arguments. In ReplaceNetNatStaticMapping
, it could call RemoveNetNatStaticMapping
with the given externalIPAddr and externalPort and the got internalIPAddr
and internalPort
.
Another approach is to remove internalIPAddr
and internalPort
from the arguments.
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.
Go with the second approach.
I think only if calling NewNetNatStaticMapping
needs internalIPAddr
and internalPort
soRemoveNetNatStaticMapping
just doesn't need it. I am not sure why
In ReplaceNetNatStaticMapping, it could call RemoveNetNatStaticMapping
Since ReplaceNetNatStaticMapping
calls RemoveNetNatStaticMapping
means calling GetNetNatStaticMapping
twice.
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 forgot to mention in the first approach RemoveNetNatStaticMapping
should call the command directly without calling GetNetNatStaticMapping
first. The function should check if the returned error is "mapping not exist" and ignore it if yes.
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 bit confused. Without GetNetNatStaticMapping
, StaticMappingID
is unknown for Remove-NetNatStaticMapping
.
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 thought Remove-NetNatStaticMapping
supports removing it by other arguments like ExternalIPAddress
. But it seems not, so 1st approach can't work
789a7e7
to
36f2e6b
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.
LGTM
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.
Just a minor comment.
pkg/agent/config/node_config.go
Outdated
@@ -52,7 +52,10 @@ var ( | |||
// - Use the virtual IP as onlink routing entry gateway in host routing entry. | |||
// - Use the virtual IP as destination IP in host routing entry. It is used to forward DNATed NodePort packets | |||
// or replied SNATed Service packets back to Antrea gateway. | |||
VirtualServiceIPv4 = net.ParseIP("169.254.169.253") | |||
// - Use the virtual IP for InternalIPAddress parameter of Add-NetNatStaticMapping. | |||
// For Antrea, it cannot be an IP used by users but for Add-NetNatStaticMapping it cannot be 169.254.1.0 |
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 IP cannot be one used in the network, and cannot to be within the 169.254.1.0 - 169.254.254.255 range according to IETF."?
Probably remove "So 169.254.0.253 is a valid one"
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.
Updated.
Create "antrea-nat-nodeport" NetNat and the NetNatStaticMapping. Then destination IP of a packet with NodePort will be DNATed to VirtualServiceIPv4 at the Windows host network. Signed-off-by: Zhecheng Li <[email protected]>
36f2e6b
to
5622c95
Compare
/test-integration |
/test-all /test-windows-all |
/test-windows-networkpolicy |
No description provided.