Parcourir la source

cmd/k8s-operator: disable HTTP/2 for the auth proxy

Kubernetes uses SPDY/3.1 which is incompatible with HTTP/2, disable it
in the transport and server.

Fixes #7645
Fixes #7646

Signed-off-by: Maisem Ali <[email protected]>
Maisem Ali il y a 3 ans
Parent
commit
df89b7de10
2 fichiers modifiés avec 32 ajouts et 5 suppressions
  1. 19 3
      cmd/k8s-operator/operator.go
  2. 13 2
      cmd/k8s-operator/proxy.go

+ 19 - 3
cmd/k8s-operator/operator.go

@@ -7,8 +7,10 @@ package main
 
 import (
 	"context"
+	"crypto/tls"
 	_ "embed"
 	"fmt"
+	"net/http"
 	"os"
 	"strings"
 	"time"
@@ -25,7 +27,7 @@ import (
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/fields"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/client-go/rest"
+	"k8s.io/client-go/transport"
 	"sigs.k8s.io/controller-runtime/pkg/builder"
 	"sigs.k8s.io/controller-runtime/pkg/cache"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -235,9 +237,23 @@ waitOnline:
 
 	startlog.Infof("Startup complete, operator running")
 	if shouldRunAuthProxy {
-		rt, err := rest.TransportFor(restConfig)
+		cfg, err := restConfig.TransportConfig()
 		if err != nil {
-			startlog.Fatalf("could not get rest transport: %v", err)
+			startlog.Fatalf("could not get rest.TransportConfig(): %v", err)
+		}
+
+		// Kubernetes uses SPDY for exec and port-forward, however SPDY is
+		// incompatible with HTTP/2; so disable HTTP/2 in the proxy.
+		tr := http.DefaultTransport.(*http.Transport).Clone()
+		tr.TLSClientConfig, err = transport.TLSConfigFor(cfg)
+		if err != nil {
+			startlog.Fatalf("could not get transport.TLSConfigFor(): %v", err)
+		}
+		tr.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) http.RoundTripper)
+
+		rt, err := transport.HTTPWrappersForConfig(cfg, tr)
+		if err != nil {
+			startlog.Fatalf("could not get rest.TransportConfig(): %v", err)
 		}
 		go runAuthProxy(s, rt, zlog.Named("auth-proxy").Infof)
 	}

+ 13 - 2
cmd/k8s-operator/proxy.go

@@ -5,6 +5,7 @@ package main
 
 import (
 	"context"
+	"crypto/tls"
 	"fmt"
 	"log"
 	"net/http"
@@ -48,7 +49,7 @@ func (h *authProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 //
 // It never returns.
 func runAuthProxy(s *tsnet.Server, rt http.RoundTripper, logf logger.Logf) {
-	ln, err := s.ListenTLS("tcp", ":443")
+	ln, err := s.Listen("tcp", ":443")
 	if err != nil {
 		log.Fatalf("could not listen on :443: %v", err)
 	}
@@ -103,7 +104,17 @@ func runAuthProxy(s *tsnet.Server, rt http.RoundTripper, logf logger.Logf) {
 			Transport: rt,
 		},
 	}
-	if err := http.Serve(ln, ap); err != nil {
+	hs := &http.Server{
+		// Kubernetes uses SPDY for exec and port-forward, however SPDY is
+		// incompatible with HTTP/2; so disable HTTP/2 in the proxy.
+		TLSConfig: &tls.Config{
+			GetCertificate: lc.GetCertificate,
+			NextProtos:     []string{"http/1.1"},
+		},
+		TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
+		Handler:      ap,
+	}
+	if err := hs.ServeTLS(ln, "", ""); err != nil {
 		log.Fatalf("runAuthProxy: failed to serve %v", err)
 	}
 }