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

Support EndpointSlice API for ServiceExport controller #4895

Merged
merged 1 commit into from
May 24, 2023

Conversation

luolanzone
Copy link
Contributor

@luolanzone luolanzone commented Apr 25, 2023

  1. Process EndpointSlice API by default for exported Service's endpoint change.
  2. Validate endpointIPType to allow 'PodIP' or 'ClusterIP' only.
  3. Fix a typo

For #4730

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

@luolanzone luolanzone added the area/multi-cluster Issues or PRs related to multi cluster. label Apr 25, 2023
@luolanzone
Copy link
Contributor Author

/test-all

@luolanzone
Copy link
Contributor Author

/test-all

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

@luolanzone luolanzone force-pushed the mc-endpointslice branch 2 times, most recently from 6ecaaf3 to 005a952 Compare May 12, 2023 06:31
@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

@@ -579,7 +627,9 @@ func (r *ServiceExportReconciler) refreshResourceExport(resName, kind string,
case constants.ServiceKind:
re.ObjectMeta.Name = resName
re.Spec.Service = &mcsv1alpha1.ServiceExport{
ServiceSpec: svc.Spec,
ServiceSpec: corev1.ServiceSpec{
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should redefine ResourceExport for a Service, not to use the ServiceExport/Service.Spec, if we just need Ports. We can revisit this later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, will create a new PR for this.

Copy link
Contributor

@jianjuns jianjuns left a comment

Choose a reason for hiding this comment

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

LGTM. Two nits.

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

jianjuns
jianjuns previously approved these changes May 16, 2023
@@ -57,6 +57,9 @@ type MultiClusterConfig struct {
// ClusterSet and allow Antrea-native policies to select peers from other clusters
// in a ClusterSet.
EnableStretchedNetworkPolicy bool `json:"enableStretchedNetworkPolicy,omitempty"`
// Enable EndpointSlice to watch EndpointSlice changes only for exported Service, this is required
// when EndpointIPType is PodIP and CNI's EndpointSlice feature is enabled.
EnableEndpointSlice bool `json:"enableEndpointSlice,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

I wonder why a configuration parameter is needed but not use the feature gate like AntreaProxy? Ideally EndpointSlice should be the default API we use to get Endpoints as it's GA and more efficient. User shouldn't care whether we use which API we are using.

In AntreaProxy, we use EndpointSlice when the feature gate is enabled (the current default value) and will fall back to Endpoint API if the EndpointSlice API is not available (K8s <1.21)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Make sense, we didn't introduce feature gate in MC, but I guess it's better to follow AntreaProxy way to check EndpointSlice API and fall back to Endpoint if it's not available. I will refine this part. thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I addressed the comment in a new commit, since Antrea MC didn't provide feature gate for EndpointSlice, the current behavior is to use EndpointSlice by default as long as the API is available and fall back to Endpoint when it's not available. @jianjuns any thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have a way to know if Endpoints are also created? In the current implementation, watching/exporting Endpoints is more efficient than exporting EndpointSlice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

EndpointSlice will be created automatically if Endpoint is created, but I doubt Endpoint controller will do the same if EndpointSlice is created for a Service. @tnqn any idea?

Copy link
Member

Choose a reason for hiding this comment

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

Since Endpoints will be mirrored to EndpointSlice and exporting Exporting Endpoints is more efficient in Multicluster, why do we need this new patch? I guess there is no EndpointSlice -> Endpoints mirroring, but you can test it by creating an EndpointSlice.

Copy link
Member

Choose a reason for hiding this comment

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

I tested there is automatic Endpoints -> EndpointSlice mirroring and no EndpointSlice -> Endpoints mirroring. And the official doc about Services without selector guides users to create EndpointSlice manually now. If we want to support Services without selector, the best choice seems listening to EndpointSlice API when it's available because:

  1. If user create EndpointSlice manually, it can be exported.
  2. If user create Endpoints manually, it will be mirrored to EndpointSlice and be exported.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok. Got it.

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

Comment on lines +458 to +453
newCondition.Reason = getStringPointer("Succeed")
newCondition.Message = getStringPointer("The Service is exported successfully")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: Reason and Message are required fields in upstream ServiceExport definition, so recover it to fix the bug which is introduced by #4814.

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

1 similar comment
@hjiajing
Copy link
Contributor

/test-multicluster-e2e

@luolanzone
Copy link
Contributor Author

@jianjuns @tnqn could you help to review the PR again? I addressed the comment to watch EndpointSlice API in the top commit. thanks.

ports = convertEndpointPorts(eps.Ports)
}
for _, ep := range eps.Endpoints {
if *ep.Conditions.Ready {
Copy link
Member

Choose a reason for hiding this comment

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

The explanation of the field says it could be nil, indicating an unknown state. If it happens, the program would panic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Comment on lines 706 to 710
subset := corev1.EndpointSubset{}
readyAddresses := ipsToEndpointAddresses(ep.Addresses)
subset.Addresses = append(subset.Addresses, readyAddresses...)
subset.Ports = ports
subsets = append(subsets, subset)
Copy link
Member

Choose a reason for hiding this comment

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

It generates one subset per Endpoint, but I think the relationship between EndpointSlice and Endpoints is one EndpointSlice maps to one subset in Endpoints?

// EndpointSubset is a group of addresses with a common set of ports. The
// expanded set of endpoints is the Cartesian product of Addresses x Ports.

Otherwise the ports field is rather redundant as there is a duplicate in each subset.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refined.

Comment on lines 297 to 284
if r.endpointSliceEnabled {
newSubsets = eps.Subsets
} else {
newSubsets = filterEndpointSubsets(eps.Subsets)
Copy link
Member

Choose a reason for hiding this comment

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

Can we process Endpoints in one place and stick to use newSubsets to cache the new subsets? The current logic is distributed at L242-L268 and here, and somestimes use eps.Subsets to cache the result but sometimes set newSubsets to eps.Subsets.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

}
} else {
if !apierrors.IsNotFound(err) {
hasReadyEndpoints, err = r.checkSubsetsFromEndpoint(ctx, req, eps)
Copy link
Member

Choose a reason for hiding this comment

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

why don't return newSubsets from checkSubsetsFromEndpoint and remove filterEndpointSubsets? They seems to do same work.

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 point, refined, thanks.

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

tnqn
tnqn previously approved these changes May 23, 2023
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.

Code LGTM, but the PR description and commit message are out-of-date.

CONTRIBUTING.md Outdated
@@ -188,7 +188,7 @@ Here are the trigger phrases for individual checks:
Here are the trigger phrases for groups of checks:

* `/test-all`: Linux IPv4 tests
* `/test-windows-all`: Windows IPv4 tests, including e2e tests with proxyAll enabled. It also includes all Containderd runtime based Windows tests since 1.10.0.
* `/test-windows-all`: Windows IPv4 tests, including e2e tests with proxyAll enabled. It also includes all Containerd runtime based Windows tests since 1.10.0.
Copy link
Contributor

Choose a reason for hiding this comment

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

Containerd -> containerd

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated

1. Process EndpointSlice API by default for exported Service's endpoint change.
2. Validate `endpointIPType` to allow 'PodIP' or 'ClusterIP' only.
3. Fix a typo.

Signed-off-by: Lan Luo <luola@vmware.com>
@luolanzone
Copy link
Contributor Author

/test-multicluster-e2e

@luolanzone
Copy link
Contributor Author

Updated the messages and squashed them into one commit.

@tnqn
Copy link
Member

tnqn commented May 24, 2023

/skip-all

@tnqn
Copy link
Member

tnqn commented May 24, 2023

@jianjuns do you have other comments?

@jianjuns
Copy link
Contributor

@jianjuns do you have other comments?

No

@tnqn tnqn merged commit 042e772 into antrea-io:main May 24, 2023
ceclinux pushed a commit to ceclinux/antrea that referenced this pull request Jun 5, 2023
1. Process EndpointSlice API by default for exported Service's endpoint change.
2. Validate `endpointIPType` to allow 'PodIP' or 'ClusterIP' only.
3. Fix a typo.

Signed-off-by: Lan Luo <luola@vmware.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/multi-cluster Issues or PRs related to multi cluster.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants