Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
b411864b
Commit
b411864b
authored
Oct 05, 2022
by
Brad Davidson
Committed by
Brad Davidson
Oct 05, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle custom kubelet port in agent tunnel
The kubelet port can be overridden by users; we shouldn't assume its always 10250 Signed-off-by:
Brad Davidson
<
brad.davidson@rancher.com
>
parent
11072e25
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
47 additions
and
18 deletions
+47
-18
tunnel.go
pkg/agent/tunnel/tunnel.go
+34
-5
types.go
pkg/daemons/config/types.go
+0
-8
tunnel.go
pkg/daemons/control/tunnel.go
+13
-5
No files found.
pkg/agent/tunnel/tunnel.go
View file @
b411864b
...
@@ -7,7 +7,9 @@ import (
...
@@ -7,7 +7,9 @@ import (
"net"
"net"
"os"
"os"
"reflect"
"reflect"
"strconv"
"sync"
"sync"
"time"
"github.com/gorilla/websocket"
"github.com/gorilla/websocket"
agentconfig
"github.com/k3s-io/k3s/pkg/agent/config"
agentconfig
"github.com/k3s-io/k3s/pkg/agent/config"
...
@@ -22,6 +24,7 @@ import (
...
@@ -22,6 +24,7 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/rest"
...
@@ -31,10 +34,11 @@ import (
...
@@ -31,10 +34,11 @@ import (
)
)
type
agentTunnel
struct
{
type
agentTunnel
struct
{
client
kubernetes
.
Interface
client
kubernetes
.
Interface
cidrs
cidranger
.
Ranger
cidrs
cidranger
.
Ranger
ports
map
[
string
]
bool
ports
map
[
string
]
bool
mode
string
mode
string
kubeletPort
string
}
}
// explicit interface check
// explicit interface check
...
@@ -85,6 +89,9 @@ func Setup(ctx context.Context, config *daemonconfig.Node, proxy proxy.Proxy) er
...
@@ -85,6 +89,9 @@ func Setup(ctx context.Context, config *daemonconfig.Node, proxy proxy.Proxy) er
close
(
apiServerReady
)
close
(
apiServerReady
)
}()
}()
// Allow the kubelet port, as published via our node object
go
tunnel
.
setKubeletPort
(
ctx
,
apiServerReady
)
switch
tunnel
.
mode
{
switch
tunnel
.
mode
{
case
daemonconfig
.
EgressSelectorModeCluster
:
case
daemonconfig
.
EgressSelectorModeCluster
:
// In Cluster mode, we allow the cluster CIDRs, and any connections to the node's IPs for pods using host network.
// In Cluster mode, we allow the cluster CIDRs, and any connections to the node's IPs for pods using host network.
...
@@ -135,6 +142,23 @@ func Setup(ctx context.Context, config *daemonconfig.Node, proxy proxy.Proxy) er
...
@@ -135,6 +142,23 @@ func Setup(ctx context.Context, config *daemonconfig.Node, proxy proxy.Proxy) er
return
nil
return
nil
}
}
// setKubeletPort retrieves the configured kubelet port from our node object
func
(
a
*
agentTunnel
)
setKubeletPort
(
ctx
context
.
Context
,
apiServerReady
<-
chan
struct
{})
{
<-
apiServerReady
wait
.
PollImmediateWithContext
(
ctx
,
time
.
Second
,
util
.
DefaultAPIServerReadyTimeout
,
func
(
ctx
context
.
Context
)
(
bool
,
error
)
{
nodeName
:=
os
.
Getenv
(
"NODE_NAME"
)
node
,
err
:=
a
.
client
.
CoreV1
()
.
Nodes
()
.
Get
(
ctx
,
nodeName
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
logrus
.
Debugf
(
"Tunnel authorizer failed to get Kubelet Port: %v"
,
err
)
return
false
,
nil
}
a
.
kubeletPort
=
strconv
.
FormatInt
(
int64
(
node
.
Status
.
DaemonEndpoints
.
KubeletEndpoint
.
Port
),
10
)
logrus
.
Infof
(
"Tunnel authorizer set Kubelet Port %s"
,
a
.
kubeletPort
)
return
true
,
nil
})
}
func
(
a
*
agentTunnel
)
clusterAuth
(
config
*
daemonconfig
.
Node
)
{
func
(
a
*
agentTunnel
)
clusterAuth
(
config
*
daemonconfig
.
Node
)
{
// In Cluster mode, we add static entries for the Node IPs and Cluster CIDRs
// In Cluster mode, we add static entries for the Node IPs and Cluster CIDRs
for
_
,
ip
:=
range
config
.
AgentConfig
.
NodeIPs
{
for
_
,
ip
:=
range
config
.
AgentConfig
.
NodeIPs
{
...
@@ -304,7 +328,7 @@ func (a *agentTunnel) authorized(ctx context.Context, proto, address string) boo
...
@@ -304,7 +328,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
proto
==
"tcp"
&&
daemonconfig
.
KubeletReservedPorts
[
port
]
&&
(
host
==
"127.0.0.1"
||
host
==
"::1"
)
{
if
a
.
isKubeletPort
(
proto
,
host
,
port
)
{
return
true
return
true
}
}
if
ip
:=
net
.
ParseIP
(
host
);
ip
!=
nil
{
if
ip
:=
net
.
ParseIP
(
host
);
ip
!=
nil
{
...
@@ -359,3 +383,8 @@ func (a *agentTunnel) connect(rootCtx context.Context, waitGroup *sync.WaitGroup
...
@@ -359,3 +383,8 @@ func (a *agentTunnel) connect(rootCtx context.Context, waitGroup *sync.WaitGroup
return
cancel
return
cancel
}
}
// isKubeletPort returns true if the connection is to a reserved TCP port on a loopback address.
func
(
a
*
agentTunnel
)
isKubeletPort
(
proto
,
host
,
port
string
)
bool
{
return
proto
==
"tcp"
&&
(
host
==
"127.0.0.1"
||
host
==
"::1"
)
&&
(
port
==
a
.
kubeletPort
||
port
==
daemonconfig
.
StreamServerPort
)
}
pkg/daemons/config/types.go
View file @
b411864b
...
@@ -32,16 +32,8 @@ const (
...
@@ -32,16 +32,8 @@ const (
EgressSelectorModePod
=
"pod"
EgressSelectorModePod
=
"pod"
CertificateRenewDays
=
90
CertificateRenewDays
=
90
StreamServerPort
=
"10010"
StreamServerPort
=
"10010"
KubeletPort
=
"10250"
)
)
// These ports can always be accessed via the tunnel server, at the loopback address.
// Other addresses and ports are only accessible via the tunnel on newer agents, when used by a pod.
var
KubeletReservedPorts
=
map
[
string
]
bool
{
StreamServerPort
:
true
,
KubeletPort
:
true
,
}
type
Node
struct
{
type
Node
struct
{
Docker
bool
Docker
bool
ContainerRuntimeEndpoint
string
ContainerRuntimeEndpoint
string
...
...
pkg/daemons/control/tunnel.go
View file @
b411864b
...
@@ -7,6 +7,7 @@ import (
...
@@ -7,6 +7,7 @@ import (
"io"
"io"
"net"
"net"
"net/http"
"net/http"
"strconv"
"strings"
"strings"
"sync"
"sync"
"time"
"time"
...
@@ -77,15 +78,21 @@ type TunnelServer struct {
...
@@ -77,15 +78,21 @@ type TunnelServer struct {
var
_
cidranger
.
RangerEntry
=
&
tunnelEntry
{}
var
_
cidranger
.
RangerEntry
=
&
tunnelEntry
{}
type
tunnelEntry
struct
{
type
tunnelEntry
struct
{
cidr
net
.
IPNet
kubeletPort
string
nodeName
string
nodeName
string
node
bool
cidr
net
.
IPNet
}
}
func
(
n
*
tunnelEntry
)
Network
()
net
.
IPNet
{
func
(
n
*
tunnelEntry
)
Network
()
net
.
IPNet
{
return
n
.
cidr
return
n
.
cidr
}
}
// Some ports can always be accessed via the tunnel server, at the loopback address.
// Other addresses and ports are only accessible via the tunnel on newer agents, when used by a pod.
func
(
n
*
tunnelEntry
)
IsReservedPort
(
port
string
)
bool
{
return
n
.
kubeletPort
!=
""
&&
(
port
==
n
.
kubeletPort
||
port
==
config
.
StreamServerPort
)
}
// ServeHTTP handles either CONNECT requests, or websocket requests to the remotedialer server
// ServeHTTP handles either CONNECT requests, or websocket requests to the remotedialer server
func
(
t
*
TunnelServer
)
ServeHTTP
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
(
t
*
TunnelServer
)
ServeHTTP
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
logrus
.
Debugf
(
"Tunnel server handing %s %s request for %s from %s"
,
req
.
Proto
,
req
.
Method
,
req
.
URL
,
req
.
RemoteAddr
)
logrus
.
Debugf
(
"Tunnel server handing %s %s request for %s from %s"
,
req
.
Proto
,
req
.
Method
,
req
.
URL
,
req
.
RemoteAddr
)
...
@@ -134,7 +141,8 @@ func (t *TunnelServer) onChangeNode(nodeName string, node *v1.Node) (*v1.Node, e
...
@@ -134,7 +141,8 @@ func (t *TunnelServer) onChangeNode(nodeName string, node *v1.Node) (*v1.Node, e
t
.
cidrs
.
Remove
(
*
n
)
t
.
cidrs
.
Remove
(
*
n
)
}
else
{
}
else
{
logrus
.
Debugf
(
"Tunnel server egress proxy updating Node %s IP %v"
,
nodeName
,
n
)
logrus
.
Debugf
(
"Tunnel server egress proxy updating Node %s IP %v"
,
nodeName
,
n
)
t
.
cidrs
.
Insert
(
&
tunnelEntry
{
cidr
:
*
n
,
nodeName
:
nodeName
,
node
:
true
})
kubeletPort
:=
strconv
.
FormatInt
(
int64
(
node
.
Status
.
DaemonEndpoints
.
KubeletEndpoint
.
Port
),
10
)
t
.
cidrs
.
Insert
(
&
tunnelEntry
{
cidr
:
*
n
,
nodeName
:
nodeName
,
kubeletPort
:
kubeletPort
})
}
}
}
}
}
}
...
@@ -222,7 +230,7 @@ func (t *TunnelServer) dialBackend(ctx context.Context, addr string) (net.Conn,
...
@@ -222,7 +230,7 @@ func (t *TunnelServer) dialBackend(ctx context.Context, addr string) (net.Conn,
if
nets
,
err
:=
t
.
cidrs
.
ContainingNetworks
(
ip
);
err
==
nil
&&
len
(
nets
)
>
0
{
if
nets
,
err
:=
t
.
cidrs
.
ContainingNetworks
(
ip
);
err
==
nil
&&
len
(
nets
)
>
0
{
if
n
,
ok
:=
nets
[
0
]
.
(
*
tunnelEntry
);
ok
{
if
n
,
ok
:=
nets
[
0
]
.
(
*
tunnelEntry
);
ok
{
nodeName
=
n
.
nodeName
nodeName
=
n
.
nodeName
if
n
.
node
&&
config
.
KubeletReservedPorts
[
port
]
{
if
n
.
IsReservedPort
(
port
)
{
toKubelet
=
true
toKubelet
=
true
useTunnel
=
true
useTunnel
=
true
}
else
{
}
else
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment