mirror of https://github.com/k3s-io/k3s
Ensure remotedialer kubelet connections use kubelet bind address
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
(cherry picked from commit eb8bd15889
)
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
pull/10540/head
parent
2bdaaed7bb
commit
92f8dc0a15
2
go.mod
2
go.mod
|
@ -125,7 +125,7 @@ require (
|
||||||
github.com/rancher/dynamiclistener v0.3.6
|
github.com/rancher/dynamiclistener v0.3.6
|
||||||
github.com/rancher/lasso v0.0.0-20230830164424-d684fdeb6f29
|
github.com/rancher/lasso v0.0.0-20230830164424-d684fdeb6f29
|
||||||
github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7
|
github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7
|
||||||
github.com/rancher/remotedialer v0.3.0
|
github.com/rancher/remotedialer v0.4.1
|
||||||
github.com/rancher/wharfie v0.6.4
|
github.com/rancher/wharfie v0.6.4
|
||||||
github.com/rancher/wrangler v1.1.1
|
github.com/rancher/wrangler v1.1.1
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -1434,8 +1434,8 @@ github.com/rancher/lasso v0.0.0-20230830164424-d684fdeb6f29 h1:+kige/h8/LnzWgPjB
|
||||||
github.com/rancher/lasso v0.0.0-20230830164424-d684fdeb6f29/go.mod h1:kgk9kJVMj9FIrrXU0iyM6u/9Je4bEjPImqswkTVaKsQ=
|
github.com/rancher/lasso v0.0.0-20230830164424-d684fdeb6f29/go.mod h1:kgk9kJVMj9FIrrXU0iyM6u/9Je4bEjPImqswkTVaKsQ=
|
||||||
github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7 h1:0Kg2SGoMeU1ll4xPi4DE0+qNHLFO/U5MwtK0WrIdK+o=
|
github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7 h1:0Kg2SGoMeU1ll4xPi4DE0+qNHLFO/U5MwtK0WrIdK+o=
|
||||||
github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7/go.mod h1:fsbs0YOsGn1ofPD5p+BuI4qDhbMbSJtTegKt6Ucna+c=
|
github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7/go.mod h1:fsbs0YOsGn1ofPD5p+BuI4qDhbMbSJtTegKt6Ucna+c=
|
||||||
github.com/rancher/remotedialer v0.3.0 h1:y1EO8JCsgZo0RcqTUp6U8FXcBAv27R+TLnWRcpvX1sM=
|
github.com/rancher/remotedialer v0.4.1 h1:jwOf2kPRjBBpSFofv1OuZHWaYHeC9Eb6/XgDvbkoTgc=
|
||||||
github.com/rancher/remotedialer v0.3.0/go.mod h1:BwwztuvViX2JrLLUwDlsYt5DiyUwHLlzynRwkZLAY0Q=
|
github.com/rancher/remotedialer v0.4.1/go.mod h1:Ys004RpJuTLSm+k4aYUCoFiOOad37ubYev3TkOFg/5w=
|
||||||
github.com/rancher/wharfie v0.6.4 h1:JwYB+q661n8ut/ysgsjKe0P0z6bHCCFoC+29995ME90=
|
github.com/rancher/wharfie v0.6.4 h1:JwYB+q661n8ut/ysgsjKe0P0z6bHCCFoC+29995ME90=
|
||||||
github.com/rancher/wharfie v0.6.4/go.mod h1:kWv97z0sMAbnVNT/oe+JFZJVKn4xkas7ZdFf6UifWis=
|
github.com/rancher/wharfie v0.6.4/go.mod h1:kWv97z0sMAbnVNT/oe+JFZJVKn4xkas7ZdFf6UifWis=
|
||||||
github.com/rancher/wrangler v1.1.1-0.20230818201331-3604a6be798d h1:RQBqHXyAN5gWqUazV637kqmYcy8M8K5bdvXszNciLcY=
|
github.com/rancher/wrangler v1.1.1-0.20230818201331-3604a6be798d h1:RQBqHXyAN5gWqUazV637kqmYcy8M8K5bdvXszNciLcY=
|
||||||
|
@ -1452,8 +1452,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||||
github.com/rootless-containers/rootlesskit v1.0.1 h1:jepqW1txFSowKSMAEkVhWH3Oa1TCY9S400MVYe/6Iro=
|
github.com/rootless-containers/rootlesskit v1.0.1 h1:jepqW1txFSowKSMAEkVhWH3Oa1TCY9S400MVYe/6Iro=
|
||||||
github.com/rootless-containers/rootlesskit v1.0.1/go.mod h1:t2UAiYagxrJ+wmpFAUIZPcqsm4k2B7ve6g7lILKbloc=
|
github.com/rootless-containers/rootlesskit v1.0.1/go.mod h1:t2UAiYagxrJ+wmpFAUIZPcqsm4k2B7ve6g7lILKbloc=
|
||||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||||
|
|
|
@ -38,6 +38,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
endpointDebounceDelay = time.Second
|
endpointDebounceDelay = time.Second
|
||||||
|
defaultDialer = net.Dialer{}
|
||||||
)
|
)
|
||||||
|
|
||||||
type agentTunnel struct {
|
type agentTunnel struct {
|
||||||
|
@ -45,6 +46,7 @@ type agentTunnel struct {
|
||||||
cidrs cidranger.Ranger
|
cidrs cidranger.Ranger
|
||||||
ports map[string]bool
|
ports map[string]bool
|
||||||
mode string
|
mode string
|
||||||
|
kubeletAddr string
|
||||||
kubeletPort string
|
kubeletPort string
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
}
|
}
|
||||||
|
@ -82,6 +84,7 @@ func Setup(ctx context.Context, config *daemonconfig.Node, proxy proxy.Proxy) er
|
||||||
cidrs: cidranger.NewPCTrieRanger(),
|
cidrs: cidranger.NewPCTrieRanger(),
|
||||||
ports: map[string]bool{},
|
ports: map[string]bool{},
|
||||||
mode: config.EgressSelectorMode,
|
mode: config.EgressSelectorMode,
|
||||||
|
kubeletAddr: config.AgentConfig.ListenAddress,
|
||||||
kubeletPort: fmt.Sprint(ports.KubeletPort),
|
kubeletPort: fmt.Sprint(ports.KubeletPort),
|
||||||
startTime: time.Now().Truncate(time.Second),
|
startTime: time.Now().Truncate(time.Second),
|
||||||
}
|
}
|
||||||
|
@ -186,7 +189,7 @@ func (a *agentTunnel) setKubeletPort(ctx context.Context, apiServerReady <-chan
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
a.kubeletPort = kubeletPort
|
a.kubeletPort = kubeletPort
|
||||||
logrus.Infof("Tunnel authorizer set Kubelet Port %s", a.kubeletPort)
|
logrus.Infof("Tunnel authorizer set Kubelet Port %s", net.JoinHostPort(a.kubeletAddr, a.kubeletPort))
|
||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -390,7 +393,7 @@ func (a *agentTunnel) authorized(ctx context.Context, proto, address string) boo
|
||||||
logrus.Debugf("Tunnel authorizer checking dial request for %s", address)
|
logrus.Debugf("Tunnel authorizer checking dial request for %s", address)
|
||||||
host, port, err := net.SplitHostPort(address)
|
host, port, err := net.SplitHostPort(address)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if a.isKubeletPort(proto, host, port) {
|
if a.isKubeletOrStreamPort(proto, host, port) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if ip := net.ParseIP(host); ip != nil {
|
if ip := net.ParseIP(host); ip != nil {
|
||||||
|
@ -448,7 +451,7 @@ func (a *agentTunnel) connect(rootCtx context.Context, waitGroup *sync.WaitGroup
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
// ConnectToProxy blocks until error or context cancellation
|
// ConnectToProxy blocks until error or context cancellation
|
||||||
err := remotedialer.ConnectToProxy(ctx, wsURL, nil, auth, ws, onConnect)
|
err := remotedialer.ConnectToProxyWithDialer(ctx, wsURL, nil, auth, ws, a.dialContext, onConnect)
|
||||||
connected = false
|
connected = false
|
||||||
if err != nil && !errors.Is(err, context.Canceled) {
|
if err != nil && !errors.Is(err, context.Canceled) {
|
||||||
logrus.WithField("url", wsURL).WithError(err).Error("Remotedialer proxy error; reconnecting...")
|
logrus.WithField("url", wsURL).WithError(err).Error("Remotedialer proxy error; reconnecting...")
|
||||||
|
@ -471,7 +474,21 @@ func (a *agentTunnel) connect(rootCtx context.Context, waitGroup *sync.WaitGroup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isKubeletPort returns true if the connection is to a reserved TCP port on a loopback address.
|
// isKubeletOrStreamPort returns true if the connection is to a reserved TCP port on a loopback address.
|
||||||
func (a *agentTunnel) isKubeletPort(proto, host, port string) bool {
|
func (a *agentTunnel) isKubeletOrStreamPort(proto, host, port string) bool {
|
||||||
return proto == "tcp" && (host == "127.0.0.1" || host == "::1") && (port == a.kubeletPort || port == daemonconfig.StreamServerPort)
|
return proto == "tcp" && (host == "127.0.0.1" || host == "::1") && (port == a.kubeletPort || port == daemonconfig.StreamServerPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dialContext dials a local connection on behalf of the remote server. If the
|
||||||
|
// connection is to the kubelet port on the loopback address, the kubelet is dialed
|
||||||
|
// at its configured bind address. Otherwise, the connection is dialed normally.
|
||||||
|
func (a *agentTunnel) dialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
host, port, err := net.SplitHostPort(address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if a.isKubeletOrStreamPort(network, host, port) && port == a.kubeletPort {
|
||||||
|
address = net.JoinHostPort(a.kubeletAddr, port)
|
||||||
|
}
|
||||||
|
return defaultDialer.DialContext(ctx, network, address)
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package control
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -197,7 +196,6 @@ func (t *TunnelServer) dialBackend(ctx context.Context, addr string) (net.Conn,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
loopback := t.config.Loopback(true)
|
|
||||||
|
|
||||||
var nodeName string
|
var nodeName string
|
||||||
var toKubelet, useTunnel bool
|
var toKubelet, useTunnel bool
|
||||||
|
@ -224,14 +222,17 @@ func (t *TunnelServer) dialBackend(ctx context.Context, addr string) (net.Conn,
|
||||||
useTunnel = true
|
useTunnel = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always dial kubelet via the loopback address.
|
|
||||||
if toKubelet {
|
|
||||||
addr = fmt.Sprintf("%s:%s", loopback, port)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If connecting to something hosted by the local node, don't tunnel
|
// If connecting to something hosted by the local node, don't tunnel
|
||||||
if nodeName == t.config.ServerNodeName {
|
if nodeName == t.config.ServerNodeName {
|
||||||
useTunnel = false
|
useTunnel = false
|
||||||
|
if toKubelet {
|
||||||
|
// Dial local kubelet at the configured bind address
|
||||||
|
addr = net.JoinHostPort(t.config.BindAddress, port)
|
||||||
|
}
|
||||||
|
} else if toKubelet {
|
||||||
|
// Dial remote kubelet via the loopback address, the remotedialer client
|
||||||
|
// will ensure that it hits the right local address.
|
||||||
|
addr = net.JoinHostPort(t.config.Loopback(false), port)
|
||||||
}
|
}
|
||||||
|
|
||||||
if useTunnel {
|
if useTunnel {
|
||||||
|
|
Loading…
Reference in New Issue