mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 09:49:50 +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
|
return d.outputWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client returns a Kubernetes client to be used by kubeadm.
|
// 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.
|
||||||
// This function is implemented as a singleton, thus avoiding to recreate the client when it is used by different phases.
|
func getDryRunClient(d *initData) (clientset.Interface, error) {
|
||||||
// Important. This function must be called after the admin.conf kubeconfig file is created.
|
|
||||||
func (d *initData) Client() (clientset.Interface, error) {
|
|
||||||
if d.client == nil {
|
|
||||||
if d.dryRun {
|
|
||||||
svcSubnetCIDR, err := kubeadmconstants.GetKubernetesServiceCIDR(d.cfg.Networking.ServiceSubnet)
|
svcSubnetCIDR, err := kubeadmconstants.GetKubernetesServiceCIDR(d.cfg.Networking.ServiceSubnet)
|
||||||
if err != nil {
|
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, errors.Wrapf(err, "unable to get internal Kubernetes Service IP from the given service CIDR (%s)", d.cfg.Networking.ServiceSubnet)
|
||||||
}
|
}
|
||||||
// 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())
|
dryRunGetter := apiclient.NewInitDryRunGetter(d.cfg.NodeRegistration.Name, svcSubnetCIDR.String())
|
||||||
d.client = apiclient.NewDryRunClient(dryRunGetter, os.Stdout)
|
return apiclient.NewDryRunClient(dryRunGetter, os.Stdout), nil
|
||||||
} else { // Use a real client
|
}
|
||||||
|
|
||||||
|
// 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
|
var err error
|
||||||
|
if d.client == nil {
|
||||||
|
if d.dryRun {
|
||||||
|
d.client, err = getDryRunClient(d)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else { // Use a real client
|
||||||
if !d.adminKubeConfigBootstrapped {
|
if !d.adminKubeConfigBootstrapped {
|
||||||
// Call EnsureAdminClusterRoleBinding() to obtain a working client from admin.conf.
|
// Call EnsureAdminClusterRoleBinding() to obtain a working client from admin.conf.
|
||||||
d.client, err = kubeconfigphase.EnsureAdminClusterRoleBinding(kubeadmconstants.KubernetesDir, nil)
|
d.client, err = kubeconfigphase.EnsureAdminClusterRoleBinding(kubeadmconstants.KubernetesDir, nil)
|
||||||
@ -531,6 +538,28 @@ func (d *initData) Client() (clientset.Interface, error) {
|
|||||||
return d.client, nil
|
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.
|
// Tokens returns an array of token strings.
|
||||||
func (d *initData) Tokens() []string {
|
func (d *initData) Tokens() []string {
|
||||||
tokens := []string{}
|
tokens := []string{}
|
||||||
|
@ -45,6 +45,7 @@ type InitData interface {
|
|||||||
ExternalCA() bool
|
ExternalCA() bool
|
||||||
OutputWriter() io.Writer
|
OutputWriter() io.Writer
|
||||||
Client() (clientset.Interface, error)
|
Client() (clientset.Interface, error)
|
||||||
|
ClientWithoutBootstrap() (clientset.Interface, error)
|
||||||
Tokens() []string
|
Tokens() []string
|
||||||
PatchesDir() string
|
PatchesDir() string
|
||||||
}
|
}
|
||||||
|
@ -48,5 +48,6 @@ func (t *testInitData) KubeletDir() string { return "" }
|
|||||||
func (t *testInitData) ExternalCA() bool { return false }
|
func (t *testInitData) ExternalCA() bool { return false }
|
||||||
func (t *testInitData) OutputWriter() io.Writer { return nil }
|
func (t *testInitData) OutputWriter() io.Writer { return nil }
|
||||||
func (t *testInitData) Client() (clientset.Interface, error) { return nil, 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) Tokens() []string { return nil }
|
||||||
func (t *testInitData) PatchesDir() string { return "" }
|
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
|
// 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")
|
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 {
|
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
|
timeout := data.Cfg().ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration
|
||||||
|
Loading…
Reference in New Issue
Block a user