@@ -15,9 +15,11 @@ import (
1515 "strings"
1616
1717 corev1 "k8s.io/api/core/v1"
18+ discoveryv1 "k8s.io/api/discovery/v1"
1819 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1920 "k8s.io/apimachinery/pkg/runtime"
2021 corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
22+ discoveryv1client "k8s.io/client-go/kubernetes/typed/discovery/v1"
2123 "k8s.io/client-go/rest"
2224 "k8s.io/client-go/tools/clientcmd"
2325 "k8s.io/client-go/tools/remotecommand"
@@ -44,7 +46,7 @@ const (
4446const (
4547 // nbdb and sbdb local socket file path and protocol string which are
4648 // used by ovnkube-trace for establishing the connection when node
47- // runs on its own zone in an interconnect environment.
49+ // runs on its own zone in an interconnect environment
4850 nbdbServerSock = "unix:/var/run/ovn/ovnnb_db.sock"
4951 sbdbServerSock = "unix:/var/run/ovn/ovnsb_db.sock"
5052 sockProtocol = "unix"
@@ -364,72 +366,90 @@ func getSvcInfo(coreclient *corev1client.CoreV1Client, restconfig *rest.Config,
364366 ClusterIP : clusterIPStr ,
365367 }
366368
367- ep , err := coreclient . Endpoints ( namespace ). Get ( context . TODO (), svcName , metav1. GetOptions {} )
369+ discoveryClient , err := discoveryv1client . NewForConfig ( restconfig )
368370 if err != nil {
369- return nil , fmt .Errorf ("endpoints for service %s in namespace %s not found, err : %v" , svcName , namespace , err )
371+ return nil , fmt .Errorf ("failed to create discovery client : %w" , err )
370372 }
371- klog .V (5 ).Infof ("==> Got Endpoint %v for service %s in namespace %s\n " , ep , svcName , namespace )
372373
373- err = extractSubsetInfo (coreclient , restconfig , ep .Subsets , svcInfo , ovnNamespace , addressFamily )
374+ es , err := discoveryClient .EndpointSlices (namespace ).List (context .TODO (), metav1.ListOptions {
375+ LabelSelector : fmt .Sprintf ("kubernetes.io/service-name=%s" , svcName ),
376+ })
377+ if err != nil {
378+ return nil , fmt .Errorf ("EndpointSlices for service %s in namespace %s not found, err: %w" , svcName , namespace , err )
379+ }
380+ klog .V (5 ).Infof ("==> Got EndpointSlices %v for service %s in namespace %s\n " , es , svcName , namespace )
381+
382+ err = extractEndpointSliceInfo (coreclient , restconfig , es .Items , svcInfo , ovnNamespace , addressFamily )
374383 if err != nil {
375384 return nil , err
376385 }
377386
378387 return svcInfo , err
379388}
380389
381- // extractSubsetInfo copies information from the endpoint subsets into the SvcInfo object.
390+ // extractEndpointSliceInfo copies information from the endpoint slices into the SvcInfo object.
382391// Modifies the svcInfo object the pointer of which is passed to it.
383- func extractSubsetInfo (coreclient * corev1client.CoreV1Client , restconfig * rest.Config , subsets []corev1.EndpointSubset , svcInfo * SvcInfo , ovnNamespace , addressFamily string ) error {
384- for _ , subset := range subsets {
385- klog .V (5 ).Infof ("==> Trying to extract information for service %s in namespace %s from subset %v" ,
386- svcInfo .SvcName , svcInfo .SvcNamespace , subset )
392+ // slice is *discoveryv1.EndpointSlice slices is
393+ func extractEndpointSliceInfo (coreclient * corev1client.CoreV1Client , restconfig * rest.Config , slices []discoveryv1.EndpointSlice , svcInfo * SvcInfo , ovnNamespace , addressFamily string ) error {
394+
395+ for _ , slice := range slices {
396+ klog .V (5 ).Infof ("==> Trying to extract information for service %s in namespace %s from slice %v" ,
397+ svcInfo .SvcName , svcInfo .SvcNamespace , slice )
387398
388- // Find a port for the subset .
399+ // Find a port for the endpoint slice .
389400 var podPort string
390- for _ , port := range subset .Ports {
391- podPort = strconv .Itoa (int (port .Port ))
401+ for _ , epPort := range slice .Ports {
402+ if epPort .Port == nil {
403+ klog .V (5 ).Infof ("==> Endpoint Port is nil, skipping." )
404+ continue // with the next port
405+ }
406+ podPort = strconv .Itoa (int (* epPort .Port ))
392407 if podPort == "" {
393- klog .V (5 ).Infof ("==> Could not parse port %v, skipping." , port )
408+ klog .V (5 ).Infof ("==> Could not parse port %v, skipping." , epPort )
394409 continue // with the next port
395410 }
396411 }
397- // Continue with the next subset if podPort is empty.
412+ // Continue with the next slice if podPort is empty.
398413 if podPort == "" {
399- continue // with the next subset
414+ continue // with the next slice
400415 }
401416
402- // Parse pod information from the subset addresses. One of the subsets must have a valid address which does not belong
417+ // Parse pod information from the endpoint slice addresses. One of the slices must have a valid address which does not belong
403418 // to a host networked pod.
404- for _ , epAddress := range subset .Addresses {
419+ for _ , endpoint := range slice .Endpoints {
420+ epAddress := endpoint .Addresses
421+ if len (epAddress ) == 0 {
422+ klog .V (5 ).Infof ("Address is empty for endpoint. Skipping." )
423+ continue
424+ }
405425 // This is nil for host networked services.
406- if epAddress .TargetRef == nil {
426+ if endpoint .TargetRef == nil {
407427 klog .V (5 ).Infof ("Address %v belongs to a host networked pod. Skipping." , epAddress )
408428 continue // with the next address
409429 }
410- if epAddress .TargetRef .Name == "" || epAddress .TargetRef .Namespace == "" || epAddress . IP == "" {
411- klog .V (5 ).Infof ("Address %v contains invalid data. podName %s, podNamespace %s, podIP %s . Skipping." ,
412- epAddress , epAddress .TargetRef .Name , epAddress .TargetRef .Namespace , epAddress . IP )
430+ if endpoint .TargetRef .Name == "" || endpoint .TargetRef .Namespace == "" {
431+ klog .V (5 ).Infof ("Address %v contains invalid data. podName %s, podNamespace %s. Skipping." ,
432+ epAddress , endpoint .TargetRef .Name , endpoint .TargetRef .Namespace )
413433 continue // with the next address
414434 }
415435
416436 // Get info needed for the src Pod
417- svcPodInfo , err := getPodInfo (coreclient , restconfig , epAddress .TargetRef .Name , ovnNamespace , epAddress .TargetRef .Namespace , addressFamily )
437+ svcPodInfo , err := getPodInfo (coreclient , restconfig , endpoint .TargetRef .Name , ovnNamespace , endpoint .TargetRef .Namespace , addressFamily )
418438 if err != nil {
419- klog .Exitf ("Failed to get information from pod %s: %v" , epAddress .TargetRef .Name , err )
439+ klog .Exitf ("Failed to get information from pod %s: %v" , endpoint .TargetRef .Name , err )
420440 }
421441 klog .V (5 ).Infof ("svcPodInfo is %s\n " , svcPodInfo )
422442
423443 // At this point, we should have found valid pod information + a port, so set them and return nil.
424444 svcInfo .PodInfo = svcPodInfo
425445 svcInfo .PodPort = podPort
426- klog .V (5 ).Infof ("==> Got address and port information for service endpoint. podName: %s, podNamespace: %s, podIP: %s, podPort: %s, podNodeName: %s" ,
446+ klog .V (5 ).Infof ("==> Got address and port information for service endpoint slice . podName: %s, podNamespace: %s, podIP: %s, podPort: %s, podNodeName: %s" ,
427447 svcInfo .PodInfo .PodName , svcInfo .PodInfo .PodNamespace , svcInfo .PodInfo .IP , svcInfo .PodPort , svcInfo .PodInfo .NodeName )
428448 return nil
429449 }
430450 }
431451
432- return fmt .Errorf ("could not extract pod and port information from endpoints for service %s in namespace %s" , svcInfo .SvcName , svcInfo .SvcNamespace )
452+ return fmt .Errorf ("could not extract pod and port information from endpointslice for service %s in namespace %s" , svcInfo .SvcName , svcInfo .SvcNamespace )
433453}
434454
435455// getPodInfo returns a pointer to a fully populated PodInfo struct, or error on failure.
@@ -1222,7 +1242,6 @@ func main() {
12221242 }
12231243
12241244 klog .V (5 ).Infof ("OVN Kubernetes namespace is %s" , ovnNamespace )
1225-
12261245 if * dumpVRFTableIDs {
12271246 nodesVRFTableIDs , err := findUserDefinedNetworkVRFTableIDs (coreclient , restconfig , ovnNamespace )
12281247 if err != nil {
0 commit comments