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
9ac2dc31
Commit
9ac2dc31
authored
Mar 29, 2022
by
Brad Davidson
Committed by
Brad Davidson
Apr 15, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow agents to query non-apiserver supervisors for apiserver endpoints
Signed-off-by:
Brad Davidson
<
brad.davidson@rancher.com
>
(cherry picked from commit
49544e0d
)
parent
ab004371
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
82 additions
and
8 deletions
+82
-8
config.go
pkg/agent/config/config.go
+39
-0
run.go
pkg/agent/run.go
+4
-0
tunnel.go
pkg/agent/tunnel/tunnel.go
+13
-8
router.go
pkg/server/router.go
+26
-0
No files found.
pkg/agent/config/config.go
View file @
9ac2dc31
...
@@ -78,6 +78,29 @@ RETRY:
...
@@ -78,6 +78,29 @@ RETRY:
}
}
}
}
// APIServers returns a list of apiserver endpoints, suitable for seeding client loadbalancer configurations.
// This function will block until it can return a populated list of apiservers, or if the remote server returns
// an error (indicating that it does not support this functionality).
func
APIServers
(
ctx
context
.
Context
,
node
*
config
.
Node
,
proxy
proxy
.
Proxy
)
[]
string
{
ticker
:=
time
.
NewTicker
(
5
*
time
.
Second
)
defer
ticker
.
Stop
()
RETRY
:
for
{
addresses
,
err
:=
getAPIServers
(
ctx
,
node
,
proxy
)
if
err
!=
nil
{
logrus
.
Infof
(
"Failed to retrieve list of apiservers from server: %v"
,
err
)
return
nil
}
if
len
(
addresses
)
==
0
{
logrus
.
Infof
(
"Waiting for apiserver addresses"
)
for
range
ticker
.
C
{
continue
RETRY
}
}
return
addresses
}
}
type
HTTPRequester
func
(
u
string
,
client
*
http
.
Client
,
username
,
password
string
)
([]
byte
,
error
)
type
HTTPRequester
func
(
u
string
,
client
*
http
.
Client
,
username
,
password
string
)
([]
byte
,
error
)
func
Request
(
path
string
,
info
*
clientaccess
.
Info
,
requester
HTTPRequester
)
([]
byte
,
error
)
{
func
Request
(
path
string
,
info
*
clientaccess
.
Info
,
requester
HTTPRequester
)
([]
byte
,
error
)
{
...
@@ -570,6 +593,22 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
...
@@ -570,6 +593,22 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
return
nodeConfig
,
nil
return
nodeConfig
,
nil
}
}
// getAPIServers attempts to return a list of apiservers from the server.
func
getAPIServers
(
ctx
context
.
Context
,
node
*
config
.
Node
,
proxy
proxy
.
Proxy
)
([]
string
,
error
)
{
info
,
err
:=
clientaccess
.
ParseAndValidateToken
(
proxy
.
SupervisorURL
(),
node
.
Token
)
if
err
!=
nil
{
return
nil
,
err
}
data
,
err
:=
info
.
Get
(
"/v1-"
+
version
.
Program
+
"/apiservers"
)
if
err
!=
nil
{
return
nil
,
err
}
endpoints
:=
[]
string
{}
return
endpoints
,
json
.
Unmarshal
(
data
,
&
endpoints
)
}
// getKubeProxyDisabled attempts to return the DisableKubeProxy setting from the server configuration data.
// getKubeProxyDisabled attempts to return the DisableKubeProxy setting from the server configuration data.
// It first checks the server readyz endpoint, to ensure that the configuration has stabilized before use.
// It first checks the server readyz endpoint, to ensure that the configuration has stabilized before use.
func
getKubeProxyDisabled
(
ctx
context
.
Context
,
node
*
config
.
Node
,
proxy
proxy
.
Proxy
)
(
bool
,
error
)
{
func
getKubeProxyDisabled
(
ctx
context
.
Context
,
node
*
config
.
Node
,
proxy
proxy
.
Proxy
)
(
bool
,
error
)
{
...
...
pkg/agent/run.go
View file @
9ac2dc31
...
@@ -237,6 +237,10 @@ func RunStandalone(ctx context.Context, cfg cmds.Agent) error {
...
@@ -237,6 +237,10 @@ func RunStandalone(ctx context.Context, cfg cmds.Agent) error {
close
(
cfg
.
AgentReady
)
close
(
cfg
.
AgentReady
)
}
}
if
err
:=
tunnel
.
Setup
(
ctx
,
nodeConfig
,
proxy
);
err
!=
nil
{
return
err
}
<-
ctx
.
Done
()
<-
ctx
.
Done
()
return
ctx
.
Err
()
return
ctx
.
Err
()
}
}
...
...
pkg/agent/tunnel/tunnel.go
View file @
9ac2dc31
...
@@ -10,6 +10,7 @@ import (
...
@@ -10,6 +10,7 @@ import (
"time"
"time"
"github.com/gorilla/websocket"
"github.com/gorilla/websocket"
agentconfig
"github.com/rancher/k3s/pkg/agent/config"
"github.com/rancher/k3s/pkg/agent/proxy"
"github.com/rancher/k3s/pkg/agent/proxy"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/util"
"github.com/rancher/k3s/pkg/util"
...
@@ -53,14 +54,18 @@ func Setup(ctx context.Context, config *config.Node, proxy proxy.Proxy) error {
...
@@ -53,14 +54,18 @@ func Setup(ctx context.Context, config *config.Node, proxy proxy.Proxy) error {
return
err
return
err
}
}
// Do an immediate fill of proxy addresses from the server endpoint list, before going into the
// Try to get a list of apiservers from the server we're connecting to. If that fails, fall back to
// watch loop. This will fail on the first server, as the apiserver won't be started yet - but
// querying the endpoints list from Kubernetes. This fallback requires that the server we're joining be
// that's fine because the local server is already seeded into the proxy address list.
// running an apiserver, but is the only safe thing to do if its supervisor is down-level and can't provide us
endpoint
,
_
:=
client
.
CoreV1
()
.
Endpoints
(
"default"
)
.
Get
(
ctx
,
"kubernetes"
,
metav1
.
GetOptions
{})
// with an endpoint list.
if
endpoint
!=
nil
{
if
addresses
:=
agentconfig
.
APIServers
(
ctx
,
config
,
proxy
);
len
(
addresses
)
>
0
{
addresses
:=
util
.
GetAddresses
(
endpoint
)
proxy
.
SetSupervisorDefault
(
addresses
[
0
])
if
len
(
addresses
)
>
0
{
proxy
.
Update
(
addresses
)
proxy
.
Update
(
util
.
GetAddresses
(
endpoint
))
}
else
{
if
endpoint
,
_
:=
client
.
CoreV1
()
.
Endpoints
(
"default"
)
.
Get
(
ctx
,
"kubernetes"
,
metav1
.
GetOptions
{});
endpoint
!=
nil
{
if
addresses
:=
util
.
GetAddresses
(
endpoint
);
len
(
addresses
)
>
0
{
proxy
.
Update
(
addresses
)
}
}
}
}
}
...
...
pkg/server/router.go
View file @
9ac2dc31
...
@@ -22,9 +22,11 @@ import (
...
@@ -22,9 +22,11 @@ import (
"github.com/rancher/k3s/pkg/cli/cmds"
"github.com/rancher/k3s/pkg/cli/cmds"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/nodepassword"
"github.com/rancher/k3s/pkg/nodepassword"
"github.com/rancher/k3s/pkg/util"
"github.com/rancher/k3s/pkg/version"
"github.com/rancher/k3s/pkg/version"
coreclient
"github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1"
coreclient
"github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/json"
)
)
...
@@ -45,6 +47,7 @@ func router(ctx context.Context, config *Config, cfg *cmds.Server) http.Handler
...
@@ -45,6 +47,7 @@ func router(ctx context.Context, config *Config, cfg *cmds.Server) http.Handler
authed
.
Path
(
prefix
+
"/client-"
+
version
.
Program
+
"-controller.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ClientK3sControllerCert
,
serverConfig
.
Runtime
.
ClientK3sControllerKey
))
authed
.
Path
(
prefix
+
"/client-"
+
version
.
Program
+
"-controller.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ClientK3sControllerCert
,
serverConfig
.
Runtime
.
ClientK3sControllerKey
))
authed
.
Path
(
prefix
+
"/client-ca.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ClientCA
))
authed
.
Path
(
prefix
+
"/client-ca.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ClientCA
))
authed
.
Path
(
prefix
+
"/server-ca.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ServerCA
))
authed
.
Path
(
prefix
+
"/server-ca.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ServerCA
))
authed
.
Path
(
prefix
+
"/apiservers"
)
.
Handler
(
apiserversHandler
(
serverConfig
))
authed
.
Path
(
prefix
+
"/config"
)
.
Handler
(
configHandler
(
serverConfig
,
cfg
))
authed
.
Path
(
prefix
+
"/config"
)
.
Handler
(
configHandler
(
serverConfig
,
cfg
))
authed
.
Path
(
prefix
+
"/readyz"
)
.
Handler
(
readyzHandler
(
serverConfig
))
authed
.
Path
(
prefix
+
"/readyz"
)
.
Handler
(
readyzHandler
(
serverConfig
))
...
@@ -288,6 +291,29 @@ func fileHandler(fileName ...string) http.Handler {
...
@@ -288,6 +291,29 @@ func fileHandler(fileName ...string) http.Handler {
})
})
}
}
func
apiserversHandler
(
server
*
config
.
Control
)
http
.
Handler
{
var
endpointsClient
coreclient
.
EndpointsClient
return
http
.
HandlerFunc
(
func
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
var
endpoints
[]
string
if
endpointsClient
==
nil
{
if
server
.
Runtime
.
Core
!=
nil
{
endpointsClient
=
server
.
Runtime
.
Core
.
Core
()
.
V1
()
.
Endpoints
()
}
}
if
endpointsClient
!=
nil
{
if
endpoint
,
_
:=
endpointsClient
.
Get
(
"default"
,
"kubernetes"
,
metav1
.
GetOptions
{});
endpoint
!=
nil
{
endpoints
=
util
.
GetAddresses
(
endpoint
)
}
}
resp
.
Header
()
.
Set
(
"content-type"
,
"application/json"
)
if
err
:=
json
.
NewEncoder
(
resp
)
.
Encode
(
endpoints
);
err
!=
nil
{
logrus
.
Errorf
(
"Failed to encode apiserver endpoints: %v"
,
err
)
resp
.
WriteHeader
(
http
.
StatusInternalServerError
)
}
})
}
func
configHandler
(
server
*
config
.
Control
,
cfg
*
cmds
.
Server
)
http
.
Handler
{
func
configHandler
(
server
*
config
.
Control
,
cfg
*
cmds
.
Server
)
http
.
Handler
{
return
http
.
HandlerFunc
(
func
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
return
http
.
HandlerFunc
(
func
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
if
req
.
TLS
==
nil
{
if
req
.
TLS
==
nil
{
...
...
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