From a08887040b8a4e4057f3e58166c08b351b5115a3 Mon Sep 17 00:00:00 2001 From: tokers Date: Thu, 13 May 2021 15:02:11 +0800 Subject: [PATCH] fix: use exponential backoff mechanism to listen on nginx.StatusPort --- internal/ingress/controller/checker_test.go | 3 +- internal/ingress/controller/nginx_test.go | 31 ++++++++++++++++--- .../metric/collectors/nginx_status_test.go | 27 +++++++++++++++- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/internal/ingress/controller/checker_test.go b/internal/ingress/controller/checker_test.go index 56919dd738..3f02f40165 100644 --- a/internal/ingress/controller/checker_test.go +++ b/internal/ingress/controller/checker_test.go @@ -18,7 +18,6 @@ package controller import ( "fmt" - "net" "net/http" "net/http/httptest" "os" @@ -46,7 +45,7 @@ func TestNginxCheck(t *testing.T) { mux := http.NewServeMux() - listener, err := net.Listen("tcp", fmt.Sprintf(":%v", nginx.StatusPort)) + listener, err := tryListen("tcp", fmt.Sprintf(":%v", nginx.StatusPort)) if err != nil { t.Fatalf("creating tcp listener: %s", err) } diff --git a/internal/ingress/controller/nginx_test.go b/internal/ingress/controller/nginx_test.go index cf6463f551..fb86320299 100644 --- a/internal/ingress/controller/nginx_test.go +++ b/internal/ingress/controller/nginx_test.go @@ -31,6 +31,7 @@ import ( jsoniter "github.com/json-iterator/go" apiv1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/ingress-nginx/internal/ingress" "k8s.io/ingress-nginx/internal/nginx" @@ -149,13 +150,13 @@ func TestIsDynamicConfigurationEnough(t *testing.T) { } func TestConfigureDynamically(t *testing.T) { - listener, err := net.Listen("tcp", fmt.Sprintf(":%v", nginx.StatusPort)) + listener, err := tryListen("tcp", fmt.Sprintf(":%v", nginx.StatusPort)) if err != nil { t.Fatalf("creating tcp listener: %s", err) } defer listener.Close() - streamListener, err := net.Listen("tcp", fmt.Sprintf(":%v", nginx.StreamPort)) + streamListener, err := tryListen("tcp", fmt.Sprintf(":%v", nginx.StreamPort)) if err != nil { t.Fatalf("creating tcp listener: %s", err) } @@ -303,13 +304,13 @@ func TestConfigureDynamically(t *testing.T) { } func TestConfigureCertificates(t *testing.T) { - listener, err := net.Listen("tcp", fmt.Sprintf(":%v", nginx.StatusPort)) + listener, err := tryListen("tcp", fmt.Sprintf(":%v", nginx.StatusPort)) if err != nil { t.Fatalf("creating tcp listener: %s", err) } defer listener.Close() - streamListener, err := net.Listen("tcp", fmt.Sprintf(":%v", nginx.StreamPort)) + streamListener, err := tryListen("tcp", fmt.Sprintf(":%v", nginx.StreamPort)) if err != nil { t.Fatalf("creating tcp listener: %s", err) } @@ -525,3 +526,25 @@ func TestCleanTempNginxCfg(t *testing.T) { t.Errorf("expected one file but %d were found", len(files)) } } + +func tryListen(network, address string) (l net.Listener, err error) { + condFunc := func() (bool, error) { + l, err = net.Listen(network, address) + if err == nil { + return true, nil + } + if strings.Contains(err.Error(), "bind: address already in use") { + return false, nil + } + return false, err + } + + backoff := wait.Backoff{ + Duration: 500 * time.Millisecond, + Factor: 2, + Steps: 6, + Cap: 128 * time.Second, + } + err = wait.ExponentialBackoff(backoff, condFunc) + return +} diff --git a/internal/ingress/metric/collectors/nginx_status_test.go b/internal/ingress/metric/collectors/nginx_status_test.go index ea9229728a..4dc67c4252 100644 --- a/internal/ingress/metric/collectors/nginx_status_test.go +++ b/internal/ingress/metric/collectors/nginx_status_test.go @@ -21,10 +21,13 @@ import ( "net" "net/http" "net/http/httptest" + "strings" "testing" "time" "github.com/prometheus/client_golang/prometheus" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/ingress-nginx/internal/nginx" ) @@ -96,7 +99,7 @@ func TestStatusCollector(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - listener, err := net.Listen("tcp", fmt.Sprintf(":%v", nginx.StatusPort)) + listener, err := tryListen("tcp", fmt.Sprintf(":%v", nginx.StatusPort)) if err != nil { t.Fatalf("crating unix listener: %s", err) } @@ -147,3 +150,25 @@ func TestStatusCollector(t *testing.T) { }) } } + +func tryListen(network, address string) (l net.Listener, err error) { + condFunc := func() (bool, error) { + l, err = net.Listen(network, address) + if err == nil { + return true, nil + } + if strings.Contains(err.Error(), "bind: address already in use") { + return false, nil + } + return false, err + } + + backoff := wait.Backoff{ + Duration: 500 * time.Millisecond, + Factor: 2, + Steps: 6, + Cap: 128 * time.Second, + } + err = wait.ExponentialBackoff(backoff, condFunc) + return +}