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

Endpoint Slice support for ServiceImport #1947

Merged
merged 2 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions internal/gatewayapi/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,18 @@ func (r *Resources) GetSecret(namespace, name string) *v1.Secret {
return nil
}

func (r *Resources) GetEndpointSlicesForService(svcNamespace, svcName string) []*discoveryv1.EndpointSlice {
func (r *Resources) GetEndpointSlicesForBackend(svcNamespace, svcName string, backendKind string) []*discoveryv1.EndpointSlice {
endpointSlices := []*discoveryv1.EndpointSlice{}
for _, endpointSlice := range r.EndpointSlices {
var backendSelectorLabel string
switch backendKind {
case KindService:
backendSelectorLabel = discoveryv1.LabelServiceName
case KindServiceImport:
backendSelectorLabel = mcsapi.LabelServiceName
}
if svcNamespace == endpointSlice.Namespace &&
endpointSlice.GetLabels()[discoveryv1.LabelServiceName] == svcName {
endpointSlice.GetLabels()[backendSelectorLabel] == svcName {
endpointSlices = append(endpointSlices, endpointSlice)
}
}
Expand Down
74 changes: 47 additions & 27 deletions internal/gatewayapi/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
"time"

corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/discovery/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/gateway-api/apis/v1beta1"
mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"

"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils/ptr"
Expand Down Expand Up @@ -1009,14 +1011,26 @@

var endpoints []*ir.DestinationEndpoint
switch KindDerefOr(backendRef.Kind, KindService) {
// TODO: Use EndpointSlice for ServiceImport
case KindServiceImport:
backendIps := resources.GetServiceImport(backendNamespace, string(backendRef.Name)).Spec.IPs
for _, ip := range backendIps {
ep := ir.NewDestEndpoint(
ip,
uint32(*backendRef.Port))
endpoints = append(endpoints, ep)
serviceImport := resources.GetServiceImport(backendNamespace, string(backendRef.Name))
var servicePort mcsapi.ServicePort
for _, port := range serviceImport.Spec.Ports {
if port.Port == int32(*backendRef.Port) {
servicePort = port
break
}
}
if !t.EndpointRoutingDisabled {
endpointSlices := resources.GetEndpointSlicesForBackend(backendNamespace, string(backendRef.Name), KindDerefOr(backendRef.Kind, KindService))
endpoints = getIREndpointsFromEndpointSlice(endpointSlices, servicePort.Name, servicePort.Protocol)
} else {
backendIps := resources.GetServiceImport(backendNamespace, string(backendRef.Name)).Spec.IPs
for _, ip := range backendIps {
ep := ir.NewDestEndpoint(
ip,
uint32(*backendRef.Port))
endpoints = append(endpoints, ep)
}

Check warning on line 1033 in internal/gatewayapi/route.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/route.go#L1027-L1033

Added lines #L1027 - L1033 were not covered by tests
}
case KindService:
service := resources.GetService(backendNamespace, string(backendRef.Name))
Expand All @@ -1030,26 +1044,8 @@

// Route to endpoints by default
if !t.EndpointRoutingDisabled {
endpointSlices := resources.GetEndpointSlicesForService(backendNamespace, string(backendRef.Name))

for _, endpointSlice := range endpointSlices {
for _, endpoint := range endpointSlice.Endpoints {
for _, endpointPort := range endpointSlice.Ports {
// Check if the endpoint port matches the service port
// and if endpoint is Ready
if *endpointPort.Name == servicePort.Name &&
*endpointPort.Protocol == servicePort.Protocol &&
*endpoint.Conditions.Ready {
for _, address := range endpoint.Addresses {
ep := ir.NewDestEndpoint(
address,
uint32(servicePort.TargetPort.IntVal))
endpoints = append(endpoints, ep)
}
}
}
}
}
endpointSlices := resources.GetEndpointSlicesForBackend(backendNamespace, string(backendRef.Name), KindDerefOr(backendRef.Kind, KindService))
endpoints = getIREndpointsFromEndpointSlice(endpointSlices, servicePort.Name, servicePort.Protocol)
} else {
// Fall back to Service CluserIP routing
ep := ir.NewDestEndpoint(
Expand Down Expand Up @@ -1135,3 +1131,27 @@
}
return relevantRoute
}

func getIREndpointsFromEndpointSlice(endpointSlices []*v1.EndpointSlice, portName string, portProtocol corev1.Protocol) []*ir.DestinationEndpoint {
endpoints := []*ir.DestinationEndpoint{}
for _, endpointSlice := range endpointSlices {
for _, endpoint := range endpointSlice.Endpoints {
for _, endpointPort := range endpointSlice.Ports {
// Check if the endpoint port matches the service port
// and if endpoint is Ready
if *endpointPort.Name == portName &&
*endpointPort.Protocol == portProtocol &&
*endpoint.Conditions.Ready {
for _, address := range endpoint.Addresses {
ep := ir.NewDestEndpoint(
address,
uint32(*endpointPort.Port))
endpoints = append(endpoints, ep)
}
}
}
}
}

return endpoints
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,23 @@ serviceImports:
- 7.7.7.7
ports:
- port: 8080
name: http
protocol: TCP
endpointSlices:
- apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: service-import-1
namespace: default
labels:
multicluster.kubernetes.io/service-name: service-import-1
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 8080
endpoints:
- addresses:
- "8.8.8.8"
conditions:
ready: true
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ xdsIR:
name: httproute/default/httproute-1/rule/0
settings:
- endpoints:
- host: 7.7.7.7
- host: 8.8.8.8
port: 8080
weight: 1
hostname: '*'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,26 @@ serviceImports:
- 7.7.7.7
ports:
- port: 8080
name: http
protocol: TCP
endpointSlices:
- apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: service-import-1
namespace: backends
labels:
multicluster.kubernetes.io/service-name: service-import-1
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 8080
endpoints:
- addresses:
- "8.8.8.8"
conditions:
ready: true
referenceGrants:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: ReferenceGrant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ xdsIR:
name: httproute/default/httproute-1/rule/0
settings:
- endpoints:
- host: 7.7.7.7
- host: 8.8.8.8
port: 8080
weight: 1
hostname: '*'
Expand Down