Merge pull request #80804 from olivierlemasle/add-join-timeout

Make kubeadm join discovery wait for a finite time
This commit is contained in:
Kubernetes Prow Robot 2019-08-01 13:38:41 -07:00 committed by GitHub
commit 547617a523
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 23 additions and 10 deletions

View File

@ -27,7 +27,10 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["discovery_test.go"], srcs = ["discovery_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = ["//cmd/kubeadm/app/apis/kubeadm:go_default_library"], deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
],
) )
filegroup( filegroup(

View File

@ -75,9 +75,9 @@ func DiscoverValidatedKubeConfig(cfg *kubeadmapi.JoinConfiguration) (*clientcmda
case cfg.Discovery.File != nil: case cfg.Discovery.File != nil:
kubeConfigPath := cfg.Discovery.File.KubeConfigPath kubeConfigPath := cfg.Discovery.File.KubeConfigPath
if isHTTPSURL(kubeConfigPath) { if isHTTPSURL(kubeConfigPath) {
return https.RetrieveValidatedConfigInfo(kubeConfigPath, kubeadmapiv1beta2.DefaultClusterName) return https.RetrieveValidatedConfigInfo(kubeConfigPath, kubeadmapiv1beta2.DefaultClusterName, cfg.Discovery.Timeout.Duration)
} }
return file.RetrieveValidatedConfigInfo(kubeConfigPath, kubeadmapiv1beta2.DefaultClusterName) return file.RetrieveValidatedConfigInfo(kubeConfigPath, kubeadmapiv1beta2.DefaultClusterName, cfg.Discovery.Timeout.Duration)
case cfg.Discovery.BootstrapToken != nil: case cfg.Discovery.BootstrapToken != nil:
return token.RetrieveValidatedConfigInfo(cfg) return token.RetrieveValidatedConfigInfo(cfg)
default: default:

View File

@ -18,7 +18,9 @@ package discovery
import ( import (
"testing" "testing"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
) )
@ -69,7 +71,9 @@ func TestFor(t *testing.T) {
} }
for _, rt := range tests { for _, rt := range tests {
t.Run(rt.name, func(t *testing.T) { t.Run(rt.name, func(t *testing.T) {
_, actual := For(&rt.d) config := rt.d
config.Discovery.Timeout = &metav1.Duration{Duration: 5 * time.Minute}
_, actual := For(&config)
if (actual == nil) != rt.expect { if (actual == nil) != rt.expect {
t.Errorf( t.Errorf(
"failed For:\n\texpected: %t\n\t actual: %t", "failed For:\n\texpected: %t\n\t actual: %t",

View File

@ -17,6 +17,8 @@ limitations under the License.
package file package file
import ( import (
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
@ -34,18 +36,18 @@ import (
// RetrieveValidatedConfigInfo connects to the API Server and makes sure it can talk // RetrieveValidatedConfigInfo connects to the API Server and makes sure it can talk
// securely to the API Server using the provided CA cert and // securely to the API Server using the provided CA cert and
// optionally refreshes the cluster-info information from the cluster-info ConfigMap // optionally refreshes the cluster-info information from the cluster-info ConfigMap
func RetrieveValidatedConfigInfo(filepath, clustername string) (*clientcmdapi.Config, error) { func RetrieveValidatedConfigInfo(filepath, clustername string, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
config, err := clientcmd.LoadFromFile(filepath) config, err := clientcmd.LoadFromFile(filepath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return ValidateConfigInfo(config, clustername) return ValidateConfigInfo(config, clustername, discoveryTimeout)
} }
// ValidateConfigInfo connects to the API Server and makes sure it can talk // ValidateConfigInfo connects to the API Server and makes sure it can talk
// securely to the API Server using the provided CA cert/client certificates and // securely to the API Server using the provided CA cert/client certificates and
// optionally refreshes the cluster-info information from the cluster-info ConfigMap // optionally refreshes the cluster-info information from the cluster-info ConfigMap
func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clientcmdapi.Config, error) { func ValidateConfigInfo(config *clientcmdapi.Config, clustername string, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
err := validateKubeConfig(config) err := validateKubeConfig(config)
if err != nil { if err != nil {
return nil, err return nil, err
@ -91,7 +93,7 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien
klog.V(1).Infof("[discovery] Created cluster-info discovery client, requesting info from %q\n", currentCluster.Server) klog.V(1).Infof("[discovery] Created cluster-info discovery client, requesting info from %q\n", currentCluster.Server)
var clusterinfoCM *v1.ConfigMap var clusterinfoCM *v1.ConfigMap
wait.PollInfinite(constants.DiscoveryRetryInterval, func() (bool, error) { err = wait.Poll(constants.DiscoveryRetryInterval, discoveryTimeout, func() (bool, error) {
var err error var err error
clusterinfoCM, err = client.CoreV1().ConfigMaps(metav1.NamespacePublic).Get(bootstrapapi.ConfigMapClusterInfo, metav1.GetOptions{}) clusterinfoCM, err = client.CoreV1().ConfigMaps(metav1.NamespacePublic).Get(bootstrapapi.ConfigMapClusterInfo, metav1.GetOptions{})
if err != nil { if err != nil {
@ -106,6 +108,9 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien
} }
return true, nil return true, nil
}) })
if err == wait.ErrWaitTimeout {
return nil, errors.Errorf("Abort reading the %s ConfigMap after timeout of %v", bootstrapapi.ConfigMapClusterInfo, discoveryTimeout)
}
// If we couldn't fetch the cluster-info ConfigMap, just return the cluster-info object the user provided // If we couldn't fetch the cluster-info ConfigMap, just return the cluster-info object the user provided
if clusterinfoCM == nil { if clusterinfoCM == nil {

View File

@ -19,6 +19,7 @@ package https
import ( import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"time"
netutil "k8s.io/apimachinery/pkg/util/net" netutil "k8s.io/apimachinery/pkg/util/net"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
@ -29,7 +30,7 @@ import (
// RetrieveValidatedConfigInfo connects to the API Server and makes sure it can talk // RetrieveValidatedConfigInfo connects to the API Server and makes sure it can talk
// securely to the API Server using the provided CA cert and // securely to the API Server using the provided CA cert and
// optionally refreshes the cluster-info information from the cluster-info ConfigMap // optionally refreshes the cluster-info information from the cluster-info ConfigMap
func RetrieveValidatedConfigInfo(httpsURL, clustername string) (*clientcmdapi.Config, error) { func RetrieveValidatedConfigInfo(httpsURL, clustername string, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
client := &http.Client{Transport: netutil.SetOldTransportDefaults(&http.Transport{})} client := &http.Client{Transport: netutil.SetOldTransportDefaults(&http.Transport{})}
response, err := client.Get(httpsURL) response, err := client.Get(httpsURL)
if err != nil { if err != nil {
@ -46,5 +47,5 @@ func RetrieveValidatedConfigInfo(httpsURL, clustername string) (*clientcmdapi.Co
if err != nil { if err != nil {
return nil, err return nil, err
} }
return file.ValidateConfigInfo(config, clustername) return file.ValidateConfigInfo(config, clustername, discoveryTimeout)
} }