cmd/k8s-proxy: use L4 TCPForward instead of L7 HTTP proxy (#18179)
considerable latency was seen when using k8s-proxy with ProxyGroup in the kubernetes operator. Switching to L4 TCPForward solves this. Fixes tailscale#18171 Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk> Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
This commit is contained in:
@@ -161,7 +161,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
💣 github.com/modern-go/reflect2 from github.com/json-iterator/go
|
💣 github.com/modern-go/reflect2 from github.com/json-iterator/go
|
||||||
github.com/munnerz/goautoneg from k8s.io/kube-openapi/pkg/handler3+
|
github.com/munnerz/goautoneg from k8s.io/kube-openapi/pkg/handler3+
|
||||||
github.com/opencontainers/go-digest from github.com/distribution/reference
|
github.com/opencontainers/go-digest from github.com/distribution/reference
|
||||||
github.com/pires/go-proxyproto from tailscale.com/ipn/ipnlocal
|
github.com/pires/go-proxyproto from tailscale.com/ipn/ipnlocal+
|
||||||
github.com/pkg/errors from github.com/evanphx/json-patch/v5+
|
github.com/pkg/errors from github.com/evanphx/json-patch/v5+
|
||||||
github.com/pmezard/go-difflib/difflib from k8s.io/apimachinery/pkg/util/diff
|
github.com/pmezard/go-difflib/difflib from k8s.io/apimachinery/pkg/util/diff
|
||||||
D github.com/prometheus-community/pro-bing from tailscale.com/wgengine/netstack
|
D github.com/prometheus-community/pro-bing from tailscale.com/wgengine/netstack
|
||||||
|
|||||||
+10
-12
@@ -50,6 +50,12 @@ import (
|
|||||||
"tailscale.com/tsnet"
|
"tailscale.com/tsnet"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// proxyProtocolV2 enables PROXY protocol v2 to preserve original client
|
||||||
|
// connection info after TLS termination.
|
||||||
|
proxyProtocolV2 = 2
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
encoderCfg := zap.NewProductionEncoderConfig()
|
encoderCfg := zap.NewProductionEncoderConfig()
|
||||||
encoderCfg.EncodeTime = zapcore.RFC3339TimeEncoder
|
encoderCfg.EncodeTime = zapcore.RFC3339TimeEncoder
|
||||||
@@ -441,24 +447,16 @@ func setServeConfig(ctx context.Context, lc *local.Client, cm *certs.CertManager
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error getting local client status: %w", err)
|
return fmt.Errorf("error getting local client status: %w", err)
|
||||||
}
|
}
|
||||||
serviceHostPort := ipn.HostPort(fmt.Sprintf("%s.%s:443", name.WithoutPrefix(), status.CurrentTailnet.MagicDNSSuffix))
|
serviceSNI := fmt.Sprintf("%s.%s", name.WithoutPrefix(), status.CurrentTailnet.MagicDNSSuffix)
|
||||||
|
|
||||||
serveConfig := ipn.ServeConfig{
|
serveConfig := ipn.ServeConfig{
|
||||||
// Configure for the Service hostname.
|
|
||||||
Services: map[tailcfg.ServiceName]*ipn.ServiceConfig{
|
Services: map[tailcfg.ServiceName]*ipn.ServiceConfig{
|
||||||
name: {
|
name: {
|
||||||
TCP: map[uint16]*ipn.TCPPortHandler{
|
TCP: map[uint16]*ipn.TCPPortHandler{
|
||||||
443: {
|
443: {
|
||||||
HTTPS: true,
|
TCPForward: "localhost:80",
|
||||||
},
|
TerminateTLS: serviceSNI,
|
||||||
},
|
ProxyProtocol: proxyProtocolV2,
|
||||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{
|
|
||||||
serviceHostPort: {
|
|
||||||
Handlers: map[string]*ipn.HTTPHandler{
|
|
||||||
"/": {
|
|
||||||
Proxy: "http://localhost:80",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pires/go-proxyproto"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
@@ -150,10 +151,18 @@ func (ap *APIServerProxy) Run(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
proxyLn, err = net.Listen("tcp", "localhost:80")
|
baseLn, err := net.Listen("tcp", "localhost:80")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not listen on :80: %w", err)
|
return fmt.Errorf("could not listen on :80: %w", err)
|
||||||
}
|
}
|
||||||
|
proxyLn = &proxyproto.Listener{
|
||||||
|
Listener: baseLn,
|
||||||
|
ReadHeaderTimeout: 10 * time.Second,
|
||||||
|
ConnPolicy: proxyproto.ConnPolicyFunc(func(opts proxyproto.ConnPolicyOptions) (proxyproto.Policy,
|
||||||
|
error) {
|
||||||
|
return proxyproto.REQUIRE, nil
|
||||||
|
}),
|
||||||
|
}
|
||||||
serve = ap.hs.Serve
|
serve = ap.hs.Serve
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user