@@ -22,6 +22,7 @@ import (
22
22
"fmt"
23
23
"net"
24
24
"regexp"
25
+ "strconv"
25
26
"sync"
26
27
"time"
27
28
@@ -32,8 +33,9 @@ import (
32
33
clientset "k8s.io/client-go/kubernetes"
33
34
"k8s.io/client-go/rest"
34
35
"k8s.io/klog/v2"
35
-
36
+ "k8s.io/kubernetes/test/e2e/framework"
36
37
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
38
+ e2epodoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
37
39
)
38
40
39
41
const (
@@ -43,6 +45,8 @@ const (
43
45
kubeControllerManagerPort = 10257
44
46
// snapshotControllerPort is the port for the snapshot controller
45
47
snapshotControllerPort = 9102
48
+ // kubeProxyPort is the default port for the kube-proxy status server.
49
+ kubeProxyPort = 10249
46
50
)
47
51
48
52
// MetricsGrabbingDisabledError is an error that is wrapped by the
@@ -233,6 +237,45 @@ func (g *Grabber) getMetricsFromNode(ctx context.Context, nodeName string, kubel
233
237
}
234
238
}
235
239
240
+ // GrabFromKubeProxy returns metrics from kube-proxy
241
+ func (g * Grabber ) GrabFromKubeProxy (ctx context.Context , nodeName string ) (KubeProxyMetrics , error ) {
242
+ nodes , err := g .client .CoreV1 ().Nodes ().List (ctx , metav1.ListOptions {FieldSelector : fields.Set {"metadata.name" : nodeName }.AsSelector ().String ()})
243
+ if err != nil {
244
+ return KubeProxyMetrics {}, err
245
+ }
246
+
247
+ if len (nodes .Items ) != 1 {
248
+ return KubeProxyMetrics {}, fmt .Errorf ("error listing nodes with name %v, got %v" , nodeName , nodes .Items )
249
+ }
250
+ output , err := g .grabFromKubeProxy (ctx , nodeName )
251
+ if err != nil {
252
+ return KubeProxyMetrics {}, err
253
+ }
254
+ return parseKubeProxyMetrics (output )
255
+ }
256
+
257
+ func (g * Grabber ) grabFromKubeProxy (ctx context.Context , nodeName string ) (string , error ) {
258
+ hostCmdPodName := fmt .Sprintf ("grab-kube-proxy-metrics-%s" , framework .RandomSuffix ())
259
+ hostCmdPod := e2epod .NewExecPodSpec (metav1 .NamespaceSystem , hostCmdPodName , true )
260
+ nodeSelection := e2epod.NodeSelection {Name : nodeName }
261
+ e2epod .SetNodeSelection (& hostCmdPod .Spec , nodeSelection )
262
+ if _ , err := g .client .CoreV1 ().Pods (metav1 .NamespaceSystem ).Create (ctx , hostCmdPod , metav1.CreateOptions {}); err != nil {
263
+ return "" , fmt .Errorf ("failed to create pod to fetch metrics: %w" , err )
264
+ }
265
+ if err := e2epod .WaitTimeoutForPodReadyInNamespace (ctx , g .client , hostCmdPodName , metav1 .NamespaceSystem , 5 * time .Minute ); err != nil {
266
+ return "" , fmt .Errorf ("error waiting for pod to be up: %w" , err )
267
+ }
268
+
269
+ host := "127.0.0.1"
270
+ if framework .TestContext .ClusterIsIPv6 () {
271
+ host = "::1"
272
+ }
273
+
274
+ stdout , err := e2epodoutput .RunHostCmd (metav1 .NamespaceSystem , hostCmdPodName , fmt .Sprintf ("curl --silent %s/metrics" , net .JoinHostPort (host , strconv .Itoa (kubeProxyPort ))))
275
+ _ = g .client .CoreV1 ().Pods (metav1 .NamespaceSystem ).Delete (ctx , hostCmdPodName , metav1.DeleteOptions {})
276
+ return stdout , err
277
+ }
278
+
236
279
// GrabFromScheduler returns metrics from scheduler
237
280
func (g * Grabber ) GrabFromScheduler (ctx context.Context ) (SchedulerMetrics , error ) {
238
281
if ! g .grabFromScheduler {
0 commit comments