mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Merge pull request #121743 from neolit123/1.29-super-admin-conf
kubeadm: ensure the kubelet and kube-apiserver wait checks go first
This commit is contained in:
commit
cf4d031dbb
@ -496,21 +496,28 @@ func (d *initData) OutputWriter() io.Writer {
|
||||
return d.outputWriter
|
||||
}
|
||||
|
||||
// getDryRunClient creates a fake client that answers some GET calls in order to be able to do the full init flow in dry-run mode.
|
||||
func getDryRunClient(d *initData) (clientset.Interface, error) {
|
||||
svcSubnetCIDR, err := kubeadmconstants.GetKubernetesServiceCIDR(d.cfg.Networking.ServiceSubnet)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to get internal Kubernetes Service IP from the given service CIDR (%s)", d.cfg.Networking.ServiceSubnet)
|
||||
}
|
||||
dryRunGetter := apiclient.NewInitDryRunGetter(d.cfg.NodeRegistration.Name, svcSubnetCIDR.String())
|
||||
return apiclient.NewDryRunClient(dryRunGetter, os.Stdout), nil
|
||||
}
|
||||
|
||||
// Client returns a Kubernetes client to be used by kubeadm.
|
||||
// This function is implemented as a singleton, thus avoiding to recreate the client when it is used by different phases.
|
||||
// Important. This function must be called after the admin.conf kubeconfig file is created.
|
||||
func (d *initData) Client() (clientset.Interface, error) {
|
||||
var err error
|
||||
if d.client == nil {
|
||||
if d.dryRun {
|
||||
svcSubnetCIDR, err := kubeadmconstants.GetKubernetesServiceCIDR(d.cfg.Networking.ServiceSubnet)
|
||||
d.client, err = getDryRunClient(d)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to get internal Kubernetes Service IP from the given service CIDR (%s)", d.cfg.Networking.ServiceSubnet)
|
||||
return nil, err
|
||||
}
|
||||
// If we're dry-running, we should create a faked client that answers some GETs in order to be able to do the full init flow and just logs the rest of requests
|
||||
dryRunGetter := apiclient.NewInitDryRunGetter(d.cfg.NodeRegistration.Name, svcSubnetCIDR.String())
|
||||
d.client = apiclient.NewDryRunClient(dryRunGetter, os.Stdout)
|
||||
} else { // Use a real client
|
||||
var err error
|
||||
if !d.adminKubeConfigBootstrapped {
|
||||
// Call EnsureAdminClusterRoleBinding() to obtain a working client from admin.conf.
|
||||
d.client, err = kubeconfigphase.EnsureAdminClusterRoleBinding(kubeadmconstants.KubernetesDir, nil)
|
||||
@ -531,6 +538,28 @@ func (d *initData) Client() (clientset.Interface, error) {
|
||||
return d.client, nil
|
||||
}
|
||||
|
||||
// ClientWithoutBootstrap returns a dry-run client or a regular client from admin.conf.
|
||||
// Unlike Client(), it does not call EnsureAdminClusterRoleBinding() or sets d.client.
|
||||
// This means the client only has anonymous permissions and does not persist in initData.
|
||||
func (d *initData) ClientWithoutBootstrap() (clientset.Interface, error) {
|
||||
var (
|
||||
client clientset.Interface
|
||||
err error
|
||||
)
|
||||
if d.dryRun {
|
||||
client, err = getDryRunClient(d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else { // Use a real client
|
||||
client, err = kubeconfigutil.ClientSetFromFile(d.KubeConfigPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// Tokens returns an array of token strings.
|
||||
func (d *initData) Tokens() []string {
|
||||
tokens := []string{}
|
||||
|
@ -45,6 +45,7 @@ type InitData interface {
|
||||
ExternalCA() bool
|
||||
OutputWriter() io.Writer
|
||||
Client() (clientset.Interface, error)
|
||||
ClientWithoutBootstrap() (clientset.Interface, error)
|
||||
Tokens() []string
|
||||
PatchesDir() string
|
||||
}
|
||||
|
@ -31,22 +31,23 @@ type testInitData struct{}
|
||||
// testInitData must satisfy InitData.
|
||||
var _ InitData = &testInitData{}
|
||||
|
||||
func (t *testInitData) UploadCerts() bool { return false }
|
||||
func (t *testInitData) CertificateKey() string { return "" }
|
||||
func (t *testInitData) SetCertificateKey(key string) {}
|
||||
func (t *testInitData) SkipCertificateKeyPrint() bool { return false }
|
||||
func (t *testInitData) Cfg() *kubeadmapi.InitConfiguration { return nil }
|
||||
func (t *testInitData) DryRun() bool { return false }
|
||||
func (t *testInitData) SkipTokenPrint() bool { return false }
|
||||
func (t *testInitData) IgnorePreflightErrors() sets.Set[string] { return nil }
|
||||
func (t *testInitData) CertificateWriteDir() string { return "" }
|
||||
func (t *testInitData) CertificateDir() string { return "" }
|
||||
func (t *testInitData) KubeConfigDir() string { return "" }
|
||||
func (t *testInitData) KubeConfigPath() string { return "" }
|
||||
func (t *testInitData) ManifestDir() string { return "" }
|
||||
func (t *testInitData) KubeletDir() string { return "" }
|
||||
func (t *testInitData) ExternalCA() bool { return false }
|
||||
func (t *testInitData) OutputWriter() io.Writer { return nil }
|
||||
func (t *testInitData) Client() (clientset.Interface, error) { return nil, nil }
|
||||
func (t *testInitData) Tokens() []string { return nil }
|
||||
func (t *testInitData) PatchesDir() string { return "" }
|
||||
func (t *testInitData) UploadCerts() bool { return false }
|
||||
func (t *testInitData) CertificateKey() string { return "" }
|
||||
func (t *testInitData) SetCertificateKey(key string) {}
|
||||
func (t *testInitData) SkipCertificateKeyPrint() bool { return false }
|
||||
func (t *testInitData) Cfg() *kubeadmapi.InitConfiguration { return nil }
|
||||
func (t *testInitData) DryRun() bool { return false }
|
||||
func (t *testInitData) SkipTokenPrint() bool { return false }
|
||||
func (t *testInitData) IgnorePreflightErrors() sets.Set[string] { return nil }
|
||||
func (t *testInitData) CertificateWriteDir() string { return "" }
|
||||
func (t *testInitData) CertificateDir() string { return "" }
|
||||
func (t *testInitData) KubeConfigDir() string { return "" }
|
||||
func (t *testInitData) KubeConfigPath() string { return "" }
|
||||
func (t *testInitData) ManifestDir() string { return "" }
|
||||
func (t *testInitData) KubeletDir() string { return "" }
|
||||
func (t *testInitData) ExternalCA() bool { return false }
|
||||
func (t *testInitData) OutputWriter() io.Writer { return nil }
|
||||
func (t *testInitData) Client() (clientset.Interface, error) { return nil, nil }
|
||||
func (t *testInitData) ClientWithoutBootstrap() (clientset.Interface, error) { return nil, nil }
|
||||
func (t *testInitData) Tokens() []string { return nil }
|
||||
func (t *testInitData) PatchesDir() string { return "" }
|
||||
|
@ -82,9 +82,10 @@ func runWaitControlPlanePhase(c workflow.RunData) error {
|
||||
// waiter holds the apiclient.Waiter implementation of choice, responsible for querying the API server in various ways and waiting for conditions to be fulfilled
|
||||
klog.V(1).Infoln("[wait-control-plane] Waiting for the API server to be healthy")
|
||||
|
||||
client, err := data.Client()
|
||||
// WaitForAPI uses the /healthz endpoint, thus a client without permissions works fine
|
||||
client, err := data.ClientWithoutBootstrap()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot obtain client")
|
||||
return errors.Wrap(err, "cannot obtain client without bootstrap")
|
||||
}
|
||||
|
||||
timeout := data.Cfg().ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration
|
||||
|
Loading…
Reference in New Issue
Block a user