From 633d2cdfc1657180650a5a8986ecb5cc34d5c28c Mon Sep 17 00:00:00 2001 From: gmarek Date: Fri, 4 Mar 2016 10:19:16 +0100 Subject: [PATCH] Add a workaround for hanging proxy in nodeProxyRequest --- test/e2e/kubelet_stats.go | 46 ++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/test/e2e/kubelet_stats.go b/test/e2e/kubelet_stats.go index ee00560bb84..a6a4dbb6698 100644 --- a/test/e2e/kubelet_stats.go +++ b/test/e2e/kubelet_stats.go @@ -42,6 +42,11 @@ import ( "k8s.io/kubernetes/pkg/util/wait" ) +const ( + // timeout for proxy requests. + proxyTimeout = 2 * time.Minute +) + // KubeletMetric stores metrics scraped from the kubelet server's /metric endpoint. // TODO: Get some more structure around the metrics and this type type KubeletMetric struct { @@ -339,28 +344,39 @@ type usageDataPerContainer struct { // Performs a get on a node proxy endpoint given the nodename and rest client. func nodeProxyRequest(c *client.Client, node, endpoint string) (restclient.Result, error) { + // proxy tends to hang in some cases when Node is not ready. Add an artificial timeout for this call. + // This will leak a goroutine if proxy hangs. #22165 subResourceProxyAvailable, err := serverVersionGTE(subResourceServiceAndNodeProxyVersion, c) if err != nil { return restclient.Result{}, err } var result restclient.Result - if subResourceProxyAvailable { - result = c.Get(). - Resource("nodes"). - SubResource("proxy"). - Name(fmt.Sprintf("%v:%v", node, ports.KubeletPort)). - Suffix(endpoint). - Do() + finished := make(chan struct{}) + go func() { + if subResourceProxyAvailable { + result = c.Get(). + Resource("nodes"). + SubResource("proxy"). + Name(fmt.Sprintf("%v:%v", node, ports.KubeletPort)). + Suffix(endpoint). + Do() - } else { - result = c.Get(). - Prefix("proxy"). - Resource("nodes"). - Name(fmt.Sprintf("%v:%v", node, ports.KubeletPort)). - Suffix(endpoint). - Do() + } else { + result = c.Get(). + Prefix("proxy"). + Resource("nodes"). + Name(fmt.Sprintf("%v:%v", node, ports.KubeletPort)). + Suffix(endpoint). + Do() + } + finished <- struct{}{} + }() + select { + case <-finished: + return result, nil + case <-time.After(proxyTimeout): + return restclient.Result{}, nil } - return result, nil } // Retrieve metrics from the kubelet server of the given node.