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
072259f8
Commit
072259f8
authored
Sep 26, 2016
by
Atanas Mirchev
Committed by
Atanas Mirchev
Oct 13, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kubeadm join: wait for API endpoints
* Introduce a concurrent retry mechanism for bootstrapping with a single API endpoint
parent
ca75b476
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
68 additions
and
47 deletions
+68
-47
bootstrap.go
cmd/kubeadm/app/node/bootstrap.go
+68
-23
csr.go
cmd/kubeadm/app/node/csr.go
+0
-24
No files found.
cmd/kubeadm/app/node/bootstrap.go
View file @
072259f8
...
...
@@ -19,13 +19,17 @@ package node
import
(
"fmt"
"os"
"sync"
"time"
kubeadmapi
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmutil
"k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/apis/certificates"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
certclient
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/wait"
)
// ConnectionDetails represents a master API endpoint connection
...
...
@@ -36,7 +40,14 @@ type ConnectionDetails struct {
NodeName
types
.
NodeName
}
// EstablishMasterConnection establishes a connection with exactly one of the provided API endpoints or errors.
// retryTimeout between the subsequent attempts to connect
// to an API endpoint
const
retryTimeout
=
5
// EstablishMasterConnection establishes a connection with exactly one of the provided API endpoints.
// The function builds a client for every endpoint and concurrently keeps trying to connect to any one
// of the provided endpoints. Blocks until at least one connection is established, then it stops the
// connection attempts for other endpoints.
func
EstablishMasterConnection
(
s
*
kubeadmapi
.
NodeConfiguration
,
clusterInfo
*
kubeadmapi
.
ClusterInfo
)
(
*
ConnectionDetails
,
error
)
{
hostName
,
err
:=
os
.
Hostname
()
if
err
!=
nil
{
...
...
@@ -48,42 +59,53 @@ func EstablishMasterConnection(s *kubeadmapi.NodeConfiguration, clusterInfo *kub
endpoints
:=
clusterInfo
.
Endpoints
caCert
:=
[]
byte
(
clusterInfo
.
CertificateAuthorities
[
0
])
var
establishedConnection
*
ConnectionDetails
// TODO: add a wait mechanism for the API endpoints (retrying to connect to at least one)
stopChan
:=
make
(
chan
struct
{})
result
:=
make
(
chan
*
ConnectionDetails
)
var
wg
sync
.
WaitGroup
for
_
,
endpoint
:=
range
endpoints
{
clientSet
,
err
:=
createClients
(
caCert
,
endpoint
,
s
.
Secrets
.
BearerToken
,
nodeName
)
if
err
!=
nil
{
fmt
.
Printf
(
"<node/bootstrap> warning: %s. Skipping endpoint %s
\n
"
,
err
,
endpoint
)
continue
}
fmt
.
Printf
(
"<node/bootstrap> trying to connect to endpoint %s
\n
"
,
endpoint
)
// TODO: add a simple GET /version request to fail early if needed before attempting
// to connect with a discovery client.
if
err
:=
checkCertsAPI
(
clientSet
.
DiscoveryClient
);
err
!=
nil
{
fmt
.
Printf
(
"<node/bootstrap> warning: failed to connect to %s: %v
\n
"
,
endpoint
,
err
)
continue
}
fmt
.
Printf
(
"<node/bootstrap> successfully established connection with endpoint %s
\n
"
,
endpoint
)
// connection established
establishedConnection
=
&
ConnectionDetails
{
CertClient
:
clientSet
.
CertificatesClient
,
Endpoint
:
endpoint
,
CACert
:
caCert
,
NodeName
:
nodeName
,
}
break
wg
.
Add
(
1
)
go
func
(
apiEndpoint
string
)
{
defer
wg
.
Done
()
wait
.
Until
(
func
()
{
fmt
.
Printf
(
"<node/bootstrap> trying to connect to endpoint %s
\n
"
,
apiEndpoint
)
err
:=
checkAPIEndpoint
(
clientSet
,
apiEndpoint
)
if
err
!=
nil
{
fmt
.
Printf
(
"<node/bootstrap> endpoint check failed [%v]
\n
"
,
err
)
return
}
fmt
.
Printf
(
"<node/bootstrap> successfully established connection with endpoint %s
\n
"
,
apiEndpoint
)
// connection established, stop all wait threads
close
(
stopChan
)
result
<-
&
ConnectionDetails
{
CertClient
:
clientSet
.
CertificatesClient
,
Endpoint
:
apiEndpoint
,
CACert
:
caCert
,
NodeName
:
nodeName
,
}
},
retryTimeout
*
time
.
Second
,
stopChan
)
}(
endpoint
)
}
if
establishedConnection
==
nil
{
go
func
()
{
wg
.
Wait
()
// all wait.Until() calls have finished now
close
(
result
)
}()
establishedConnection
,
ok
:=
<-
result
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"<node/bootstrap> failed to create bootstrap clients "
+
"for any of the provided API endpoints"
)
}
return
establishedConnection
,
nil
}
//
C
reates a set of clients for this endpoint
//
c
reates a set of clients for this endpoint
func
createClients
(
caCert
[]
byte
,
endpoint
,
token
string
,
nodeName
types
.
NodeName
)
(
*
clientset
.
Clientset
,
error
)
{
bareClientConfig
:=
kubeadmutil
.
CreateBasicClientConfig
(
"kubernetes"
,
endpoint
,
caCert
)
bootstrapClientConfig
,
err
:=
clientcmd
.
NewDefaultClientConfig
(
...
...
@@ -101,3 +123,26 @@ func createClients(caCert []byte, endpoint, token string, nodeName types.NodeNam
}
return
clientSet
,
nil
}
// checks the connection requirements for a specific API endpoint
func
checkAPIEndpoint
(
clientSet
*
clientset
.
Clientset
,
endpoint
string
)
error
{
// check general connectivity
version
,
err
:=
clientSet
.
DiscoveryClient
.
ServerVersion
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to connect to %s [%v]"
,
endpoint
,
err
)
}
fmt
.
Printf
(
"<node/bootstrap> detected server version %s
\n
"
,
version
.
String
())
// check certificates API
serverGroups
,
err
:=
clientSet
.
DiscoveryClient
.
ServerGroups
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"certificate API check failed: failed to retrieve a list of supported API objects [%v]"
,
err
)
}
for
_
,
group
:=
range
serverGroups
.
Groups
{
if
group
.
Name
==
certificates
.
GroupName
{
return
nil
}
}
return
fmt
.
Errorf
(
"certificate API check failed: API version %s does not support certificates API, use v1.4.0 or newer"
,
version
.
String
())
}
cmd/kubeadm/app/node/csr.go
View file @
072259f8
...
...
@@ -20,8 +20,6 @@ import (
"fmt"
kubeadmutil
"k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/client/typed/discovery"
clientcmdapi
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
"k8s.io/kubernetes/pkg/kubelet/util/csr"
certutil
"k8s.io/kubernetes/pkg/util/cert"
...
...
@@ -57,25 +55,3 @@ func PerformTLSBootstrap(connection *ConnectionDetails) (*clientcmdapi.Config, e
return
finalConfig
,
nil
}
// Checks if the certificates API for this endpoint is functional
func
checkCertsAPI
(
discoveryClient
*
discovery
.
DiscoveryClient
)
error
{
serverGroups
,
err
:=
discoveryClient
.
ServerGroups
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to retrieve a list of supported API objects [%v]"
,
err
)
}
for
_
,
group
:=
range
serverGroups
.
Groups
{
if
group
.
Name
==
certificates
.
GroupName
{
return
nil
}
}
version
,
err
:=
discoveryClient
.
ServerVersion
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"unable to obtain API version [%v]"
,
err
)
}
return
fmt
.
Errorf
(
"API version %s does not support certificates API, use v1.4.0 or newer"
,
version
.
String
())
}
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