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

Improve multi-protocol support for NPL #2903

Merged

Conversation

antoninbas
Copy link
Contributor

There is an edge case, which is not handled well by the current NPL
controller implementation: if a given Pod port needs to be exposed for
both TCP and UDP, and the first available Node port is only available
for TCP, it will be still be selected and NPL rule installation will
succeed for TCP but not for UDP.

We have 2 options:

  1. reserve the port for both protocols ahead of time, even if the port
    is only needed for one protocol initially.
  2. support using different Node ports for different protocols, even when
    the Pod port is the same.

In this patch, we go with option 1) to preserve the "nice" property that
a give Pod port maps to a unique Node port.

Fixes #2894

Signed-off-by: Antonin Bas [email protected]

@antoninbas antoninbas added this to the Antrea v1.4 release milestone Oct 19, 2021
@codecov-commenter
Copy link

codecov-commenter commented Oct 19, 2021

Codecov Report

Merging #2903 (ce6bd11) into main (110e9f6) will decrease coverage by 9.12%.
The diff coverage is 58.59%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2903      +/-   ##
==========================================
- Coverage   61.55%   52.42%   -9.13%     
==========================================
  Files         283      283              
  Lines       23644    23693      +49     
==========================================
- Hits        14555    12422    -2133     
- Misses       7511     9882    +2371     
+ Partials     1578     1389     -189     
Flag Coverage Δ
kind-e2e-tests 31.36% <58.59%> (-17.85%) ⬇️
unit-tests 40.60% <20.80%> (-0.25%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
pkg/agent/nodeportlocal/portcache/port_table.go 61.36% <55.08%> (-2.97%) ⬇️
pkg/agent/nodeportlocal/k8s/npl_controller.go 60.97% <100.00%> (ø)
pkg/agent/nodeportlocal/rules/iptable_rule.go 54.09% <100.00%> (ø)
pkg/controller/types/networkpolicy.go 0.00% <0.00%> (-100.00%) ⬇️
...g/agent/apiserver/handlers/featuregates/handler.go 0.00% <0.00%> (-82.36%) ⬇️
pkg/agent/controller/networkpolicy/packetin.go 4.50% <0.00%> (-67.50%) ⬇️
pkg/apis/controlplane/v1beta2/helper.go 33.33% <0.00%> (-66.67%) ⬇️
...formers/externalversions/security/v1alpha1/tier.go 0.00% <0.00%> (-64.29%) ⬇️
...ers/externalversions/core/v1alpha2/clustergroup.go 0.00% <0.00%> (-64.29%) ⬇️
...s/externalversions/core/v1alpha2/externalentity.go 0.00% <0.00%> (-64.29%) ⬇️
... and 97 more

pkg/agent/nodeportlocal/portcache/port_table.go Outdated Show resolved Hide resolved
pkg/agent/nodeportlocal/portcache/port_table.go Outdated Show resolved Hide resolved
pkg/agent/nodeportlocal/portcache/port_table.go Outdated Show resolved Hide resolved
for _, npData := range pt.NodePortTable {
protocols := make([]string, 0, len(supportedProtocols))
for _, protocol := range npData.Protocols {
protocols = append(protocols, protocol.Protocol)
Copy link
Member

Choose a reason for hiding this comment

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

Should it only append the protocol when it's in use? otherwise pt.PodPortRules.AddAllRules would always install an iptables rule for it even it's not used and cause inconsistency between the protocolSocketState and the actual state?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch, let me fix that

@antoninbas antoninbas force-pushed the fix-multi-protocol-implementation-for-NPL branch from d490051 to f80873c Compare October 19, 2021 17:33
@antoninbas
Copy link
Contributor Author

@tnqn thanks for the attentive review, I addressed your comments in a new commit

}
nplPorts = append(nplPorts, rules.PodNodePort{
NodePort: npData.NodePort,
PodPort: npData.PodPort,
PodIP: npData.PodIP,
Protocols: protocols,
})
protocols = protocols[:0] // reuse slice
Copy link
Member

Choose a reason for hiding this comment

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

I suspected this will impact the protocols that are already stored in previous PodNodePort as they will share the array and I did a test to verify:
(play.golang.org removed share function so I'm pasting the test code):

package main

import (
	"fmt"
)

type Collection struct {
	strs []string
}

func main() {
	var collections []Collection
	strs := make([]string, 0, 2)
	for i:=0;i<3;i++ {
		strs = append(strs, fmt.Sprintf("%d", i))
		collections = append(collections, Collection{strs: strs})
		strs = strs[:0]
	} 
	fmt.Println(collections)
}

It got [{[2]} {[2]} {[2]}].

I think this is not expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you are right, this is definitely incorrect.

I fixed it and I also added one unit test, as I feel this code (rule restoration) is a bit under-tested. I confirmed that the test was failing when re-using the array.

There is an edge case, which is not handled well by the current NPL
controller implementation: if a given Pod port needs to be exposed for
both TCP and UDP, and the first available Node port is only available
for TCP, it will be still be selected and NPL rule installation will
succeed for TCP but not for UDP.

We have 2 options:

1. reserve the port for both protocols ahead of time, even if the port
is only needed for one protocol initially.
2. support using different Node ports for different protocols, even when
the Pod port is the same.

In this patch, we go with option 1) to preserve the "nice" property that
a give Pod port maps to a unique Node port.

Fixes antrea-io#2894

Signed-off-by: Antonin Bas <[email protected]>
Signed-off-by: Antonin Bas <[email protected]>
@antoninbas antoninbas force-pushed the fix-multi-protocol-implementation-for-NPL branch 2 times, most recently from c0e63ae to b25bbde Compare October 20, 2021 22:45
@antoninbas antoninbas force-pushed the fix-multi-protocol-implementation-for-NPL branch from b25bbde to ce6bd11 Compare October 20, 2021 23:02
Copy link
Member

@tnqn tnqn left a comment

Choose a reason for hiding this comment

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

LGTM

@antoninbas
Copy link
Contributor Author

/test-all

@tnqn tnqn merged commit 2abf457 into antrea-io:main Oct 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants