-
Notifications
You must be signed in to change notification settings - Fork 367
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
Controller support for ExternalEntity in Antrea NetworkPolicy #1084
Conversation
Thanks for your PR. The following commands are available:
|
ace946b
to
c52a330
Compare
5d816d0
to
0f1e8fb
Compare
/test-all /test-hw-offload |
} | ||
internalNetworkPolicy := &antreatypes.NetworkPolicy{ | ||
Name: np.Name, | ||
Namespace: np.Namespace, |
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 thought of this when I was trying to support metrics for all 3 kinds of NetworkPolicies: How did we differentiate K8s NetworkPolicy and Antrea NetworkPolicy that have same names? I know their UIDs are different but in most places we are assuming namespace+name can identify an object at any point of time like K8s does.
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.
Antrea NetworkPolicy will have a float Priority value while for K8s NetworkPolicy that field will be 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.
The main problem is when they are converted to internal NetworkPolicies they will override each other and generate update event instead of a new ADD event.
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.
given k8s NP is subset of ANP and if we cannot resolve this naming conflict easily via implementation, perhaps we could have a feature flag that let controller listens to KNP or ANP, but not both?
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 internal network policies keys are UIDs no?
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 Yes.
For cloud VM and BM case, I assume a Node is associated to a Namespace and do not require configuration of other Namespaces, at least for internal NetworkPolicies, right? If this is the case, we may keep the original Namespace.
I don't know other ways to isolate a Node when RBAC is used, as the authorization review is done by K8s API, we only know the result that whether a client is permitted to access a resource and don't know its association with Nodes or Namespaces.
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 may have discussed this on one of the meetings, on read/watch, any node can retrieve all NP in the same namespace, this is because NP CRD are shared across multiple nodes, and is computed at run-time.
on the other hand, each node will be given a unique role with which the node may use to access CRDs specific to itself, such as VIrtualMachine, VirtualMachineStatus, etc.
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 I think you meant internal network policy and group resources will not be Namespaced? Then how we controller agent to access the resources, unless we introduce some filtering in controller itself?
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.
agree.. i don't think we should eliminate the Namespace for internal network policy.. setting the name
field of networkpolicy with UID should suffice.. and still be able to use the same keyFunc .. no? .. of course need some additional reference to store the name for other purposes.. also this reminds me our AddressGroups and AppliedToGroups are not namespaced .. same issue for agents in BM/VM?
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. I think let us discuss the namespace/RBAC problems separately. It is mainly that the cloud use case increases our complexity; otherwise, ExternalEntity/Node and internal policy/group should just be cluster scope.
e109aa4
to
29c8898
Compare
29c8898
to
79a2a24
Compare
49df296
to
fd3d0de
Compare
/test-all /test-hw-offload |
fd3d0de
to
8781e7e
Compare
/test-all /test-hw-offload |
/test-hw-offload /test-networkpolicy /test-windows-networkpolicy |
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.
comments have been addressed
@@ -749,7 +748,7 @@ func groupPodsByServices(services []v1beta1.Service, pods v1beta1.GroupMemberPod | |||
resolvedServices := make([]v1beta1.Service, len(services)) | |||
for podKey, pod := range pods { | |||
for i := range services { | |||
resolvedServices[i] = *resolveService(&services[i], pod) | |||
resolvedServices[i] = *resolveService(&services[i], *pod.ToGroupMember()) |
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.
could we keep the original function for performance consideration? creating a new GroupMember struct when resolving every service with every pod and making a copy (because it uses struct as the argument instead of its pointer) might introduce some overhead.
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.
Switched to use pointer in resolveService. As for the comment about extra struct, do you think we need to make separate functions for groupMember and groupMemberPod? Or the current code is good
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 used the benchmark test BenchmarkGroupPodsByServicesWithNamedPort
to measure the difference.
# Convert Pod to GroupMember first, then call resolveService
BenchmarkGroupPodsByServicesWithNamedPort-4 26 43131306 ns/op 13643059 B/op 401963 allocs/op
# A separate resolveService for Pod
BenchmarkGroupPodsByServicesWithNamedPort-4 34 34344858 ns/op 8844193 B/op 301968 allocs/op
I think it's worth to avoid the conversion as this function is called quite frequently for named port case.
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.
Thanks for the benchmarking result. Updated.
|
||
klog.V(2).Infof("Processing ExternalEntity %s/%s DELETE event, labels: %v", ee.Namespace, ee.Name, ee.Labels) | ||
// Find all AppliedToGroup keys which match the Pod's labels. | ||
appliedToGroupKeys := n.filterAddressGroupsForPodOrExternalEntity(ee) |
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.
missed updating this?
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. Thanks for the catch.
} | ||
} | ||
} else if groupSelector.NamespaceSelector != nil { | ||
// All the Pods and EEs from Namespaces matching the nsSelector must be selected. |
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 correct? If I create a K8s NetworkPolicy that allows to all Pods in all Namespaces, both PodSelector and ExternalEntitySelector will be nil, but EEs shouldn't be selected?
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.
Thanks for spotting this. Discussed with @abhiraut and agreed the selector semantics should be compatible with K8s. So for any clause that has a namespaceSelector and nothing else, it will select all PODS in that namespace. If the intent is indeed to select all externalEntities in namespace, user need to explicitly specify something like
- namespaceSelector:
matchLabels:
project: myproject
externalEntitySelector: {}
The code is updated accordingly. @suwang48404 FYI.
0a7e938
to
ad6f84a
Compare
ad6f84a
to
def5aed
Compare
def5aed
to
e0b53a9
Compare
/test-all |
/test-hw-offload |
1 similar comment
/test-hw-offload |
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.
have a question about the inconsistency between API schema and implementation, otherwise LGTM.
} | ||
for _, ep := range member.Endpoints { | ||
for _, port := range ep.Ports { | ||
if port.Name == service.Port.StrVal && port.Protocol == *service.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.
This implementation reminds me the discussion #774 (comment).
Apparently we treat a member as the unit of resolving named ports, then does it still make sense to have separate namedPorts for each endpoint? Asking because the struct GroupMember
is also inconvenient to reuse for dual stack case as there will be two IPs, it doesn't sound proper to only set namedports to one of them while setting both will be redundant. Since in implementation we assume the namedPorts are shared for all endpoints, should we just make the struct like the following?
type GroupMember struct {
Pod *PodReference
ExternalEntity *ExternalEntityReference
IPs []IPAddress
Ports []NamedPort
}
I don't mean to address it in this PR but want to make the struct and implementation consistent before it's released.
@jianjuns @suwang48404 @abhiraut @Dyanngg @wenyingd
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 your proposal is simpler.
Do you think one Pod/VM can have multiple interfaces that have different namedPort?
Maybe it does not make sense.
Question - does this change (GroupMember) break API compatibility? Will it impact K8s NetworkPolicy of an existing cluster?
If we need to make further changes, let us do it in one release.
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 do not know if for VMs it makes sense to have multiple interfaces that have different namedPort. However, with the current externalEntity CRD, each endpoint does have its own list of ports specifications. Using single list of namedPort means we need to somehow flatten the lists, or simply use the first endpoint's ports as the port spec fotrthe group member? @suwang48404 for more insights 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.
@jianjuns
my 2 cents,
- I feel the current declaration is more flexible in dealing with niche requirements.
- my understanding is that group member is already part of internal ANP between controller and agent, so agent should understand group members in internal AP OK. In what aspect do u envision this would break k8s NP on existing cluster? Mismatch controller/agent version? Upgraded controller/agent cannot execute K8s NetworkPolicy? ...
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.
looks like i missed that conversation during my PTO at that time. I initially wanted to keep it flexible, but i really did not find a good use case to keep it that way. @suwang48404 do you find a use case for named port per interface? if not, then may be lets switch the use of named port in both GroupMember and the ExternalEntity type and in this release itself.
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.
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.
- But if one VM always has the same namedports, we will have to always duplicate them for all interfaces.
- Yes, in upgrade, controller and agent can be at different versions. We need to make sure the API is compatible between controller and agent, or support multiple versions of API.
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.
Regarding to upgrade, considering,
- This PR does not change groupmembership in AddressGrp/AppliedTogroup as it is already merged, so it won't have impact on CRD wire format compatibility.
- My understanding is that group member is not processed by agent at all, so even if group member is sent to agent, it won't have impact on agent.
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 regarding to namedPort, I feel like this is personal preference, and one can argue both ways. I hope it is not show stopper as the impact could be far reaching because it does change the on wire CRD format.
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 PR does not change groupmembership in AddressGrp/AppliedTogroup as it is already merged, so it won't have impact on CRD wire format compatibility.
My question is not for this PR. I know the change is made earlier. But we must handle it if it affects upgrade from a previous version or to a future version.
I think no one wants to stop this PR for multiple design questions discussed over review. But I hope to get the decided changes in Controller API done in this release, to avoid upgrade issues later. @Dyanngg @abhiraut: please collect all suggestions discussed.
@Dyanngg : I assume this PR is ready to merge? But please collect all suggestions and we can have a followup PR to address them. |
…-io#1084) * Agent supports ExternalEntity. This commit moves ToAddresses/FromAddresses in CompletedRule and AddressSetByGroup in ruleCache to use GroupMemberSet instead of GroupMmeberPodSet. Thus both Pods and ExternalEntities are expressed as GroupMember when in these fields. Pods in appliedTo field continue be expressed by existing GroupMemberPod, and migration to GroupMember shall be done in a subsequent PR. * Add support for ANP and externalEntities in controller * Unify functions for Pod and ExternalEntity in networkpolicy controller * Improve UT coverage * Address comments * Resolve more comments Co-authored-by: Su Wang <suw@vmware.com>
…-io#1084) * Agent supports ExternalEntity. This commit moves ToAddresses/FromAddresses in CompletedRule and AddressSetByGroup in ruleCache to use GroupMemberSet instead of GroupMmeberPodSet. Thus both Pods and ExternalEntities are expressed as GroupMember when in these fields. Pods in appliedTo field continue be expressed by existing GroupMemberPod, and migration to GroupMember shall be done in a subsequent PR. * Add support for ANP and externalEntities in controller * Unify functions for Pod and ExternalEntity in networkpolicy controller * Improve UT coverage * Address comments * Resolve more comments Co-authored-by: Su Wang <suw@vmware.com>
This PR adds the following: