mirror of https://github.com/k3s-io/k3s
Merge pull request #70480 from rosti/controlplane-timeout
kubeadm: Add configurable control plane up timeoutpull/58/head
commit
b3d81e5c0f
|
@ -50,6 +50,11 @@ func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c fuzz.Continue) {
|
|||
// More specifically:
|
||||
// internal with manually applied defaults -> external object : loosing ClusterConfiguration) -> internal object with automatically applied defaults
|
||||
obj.ClusterConfiguration = kubeadm.ClusterConfiguration{
|
||||
APIServer: kubeadm.APIServer{
|
||||
TimeoutForControlPlane: &metav1.Duration{
|
||||
Duration: constants.DefaultControlPlaneTimeout,
|
||||
},
|
||||
},
|
||||
AuditPolicyConfiguration: kubeadm.AuditPolicyConfiguration{
|
||||
LogDir: constants.StaticPodAuditPolicyLogDir,
|
||||
LogMaxAge: &v1beta1.DefaultAuditPolicyLogMaxAge,
|
||||
|
@ -97,6 +102,9 @@ func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue
|
|||
obj.ClusterName = "bar"
|
||||
obj.ImageRepository = "baz"
|
||||
obj.KubernetesVersion = "qux"
|
||||
obj.APIServer.TimeoutForControlPlane = &metav1.Duration{
|
||||
Duration: constants.DefaultControlPlaneTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
func fuzzAuditPolicyConfiguration(obj *kubeadm.AuditPolicyConfiguration, c fuzz.Continue) {
|
||||
|
|
|
@ -130,6 +130,9 @@ type APIServer struct {
|
|||
|
||||
// CertSANs sets extra Subject Alternative Names for the API Server signing cert.
|
||||
CertSANs []string
|
||||
|
||||
// TimeoutForControlPlane controls the timeout that we use for API server to appear
|
||||
TimeoutForControlPlane *metav1.Duration
|
||||
}
|
||||
|
||||
// ComponentConfigs holds known internal ComponentConfig types for other components
|
||||
|
|
|
@ -17,8 +17,10 @@ limitations under the License.
|
|||
package v1alpha3
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
)
|
||||
|
||||
func Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConfiguration, out *kubeadm.JoinConfiguration, s conversion.Scope) error {
|
||||
|
@ -84,6 +86,9 @@ func Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *C
|
|||
|
||||
out.APIServer.ExtraArgs = in.APIServerExtraArgs
|
||||
out.APIServer.CertSANs = in.APIServerCertSANs
|
||||
out.APIServer.TimeoutForControlPlane = &metav1.Duration{
|
||||
Duration: constants.DefaultControlPlaneTimeout,
|
||||
}
|
||||
if err := convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&in.APIServerExtraVolumes, &out.APIServer.ExtraVolumes, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -101,6 +101,16 @@ func SetDefaults_ClusterConfiguration(obj *ClusterConfiguration) {
|
|||
|
||||
SetDefaults_Etcd(obj)
|
||||
SetDefaults_AuditPolicyConfiguration(obj)
|
||||
SetDefaults_APIServer(&obj.APIServer)
|
||||
}
|
||||
|
||||
// SetDefaults_APIServer assigns default values for the API Server
|
||||
func SetDefaults_APIServer(obj *APIServer) {
|
||||
if obj.TimeoutForControlPlane == nil {
|
||||
obj.TimeoutForControlPlane = &metav1.Duration{
|
||||
Duration: constants.DefaultControlPlaneTimeout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetDefaults_Etcd assigns default values for the Proxy
|
||||
|
|
|
@ -212,6 +212,7 @@ limitations under the License.
|
|||
// certSANs:
|
||||
// - "10.100.1.1"
|
||||
// - "ec2-10-100-0-1.compute-1.amazonaws.com"
|
||||
// timeoutForControlPlane: 4m0s
|
||||
// controllerManager:
|
||||
// extraArgs:
|
||||
// node-cidr-mask-size: 20
|
||||
|
|
|
@ -120,6 +120,9 @@ type APIServer struct {
|
|||
|
||||
// CertSANs sets extra Subject Alternative Names for the API Server signing cert.
|
||||
CertSANs []string `json:"certSANs,omitempty"`
|
||||
|
||||
// TimeoutForControlPlane controls the timeout that we use for API server to appear
|
||||
TimeoutForControlPlane *metav1.Duration `json:"timeoutForControlPlane,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
|
|
@ -257,6 +257,7 @@ func autoConvert_v1beta1_APIServer_To_kubeadm_APIServer(in *APIServer, out *kube
|
|||
return err
|
||||
}
|
||||
out.CertSANs = *(*[]string)(unsafe.Pointer(&in.CertSANs))
|
||||
out.TimeoutForControlPlane = (*v1.Duration)(unsafe.Pointer(in.TimeoutForControlPlane))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -270,6 +271,7 @@ func autoConvert_kubeadm_APIServer_To_v1beta1_APIServer(in *kubeadm.APIServer, o
|
|||
return err
|
||||
}
|
||||
out.CertSANs = *(*[]string)(unsafe.Pointer(&in.CertSANs))
|
||||
out.TimeoutForControlPlane = (*v1.Duration)(unsafe.Pointer(in.TimeoutForControlPlane))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,11 @@ func (in *APIServer) DeepCopyInto(out *APIServer) {
|
|||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.TimeoutForControlPlane != nil {
|
||||
in, out := &in.TimeoutForControlPlane, &out.TimeoutForControlPlane
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
|
|||
|
||||
func SetObjectDefaults_ClusterConfiguration(in *ClusterConfiguration) {
|
||||
SetDefaults_ClusterConfiguration(in)
|
||||
SetDefaults_APIServer(&in.APIServer)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ClusterStatus(in *ClusterStatus) {
|
||||
|
|
|
@ -53,6 +53,11 @@ func (in *APIServer) DeepCopyInto(out *APIServer) {
|
|||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.TimeoutForControlPlane != nil {
|
||||
in, out := &in.TimeoutForControlPlane, &out.TimeoutForControlPlane
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -469,8 +469,10 @@ func runInit(i *initData, out io.Writer) error {
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create client")
|
||||
}
|
||||
|
||||
// TODO: NewControlPlaneWaiter should be converted to private after the self-hosting phase is removed.
|
||||
waiter, err := phases.NewControlPlaneWaiter(i.dryRun, client, i.outputWriter)
|
||||
timeout := i.cfg.ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration
|
||||
waiter, err := phases.NewControlPlaneWaiter(i.dryRun, timeout, client, i.outputWriter)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create waiter")
|
||||
}
|
||||
|
|
|
@ -93,12 +93,13 @@ func runWaitControlPlanePhase(c workflow.RunData) error {
|
|||
return errors.Wrap(err, "cannot obtain client")
|
||||
}
|
||||
|
||||
waiter, err := NewControlPlaneWaiter(data.DryRun(), client, data.OutputWriter())
|
||||
timeout := data.Cfg().ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration
|
||||
waiter, err := NewControlPlaneWaiter(data.DryRun(), timeout, client, data.OutputWriter())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating waiter")
|
||||
}
|
||||
|
||||
fmt.Printf("[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory %q\n", data.ManifestDir())
|
||||
fmt.Printf("[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory %q. This can take up to %v\n", data.ManifestDir(), timeout)
|
||||
|
||||
if err := waiter.WaitForKubeletAndFunc(waiter.WaitForAPI); err != nil {
|
||||
ctx := map[string]string{
|
||||
|
@ -143,14 +144,10 @@ func printFilesIfDryRunning(data waitControlPlaneData) error {
|
|||
|
||||
// NewControlPlaneWaiter returns a new waiter that is used to wait on the control plane to boot up.
|
||||
// TODO: make private (lowercase) after self-hosting phase is removed.
|
||||
func NewControlPlaneWaiter(dryRun bool, client clientset.Interface, out io.Writer) (apiclient.Waiter, error) {
|
||||
func NewControlPlaneWaiter(dryRun bool, timeout time.Duration, client clientset.Interface, out io.Writer) (apiclient.Waiter, error) {
|
||||
if dryRun {
|
||||
return dryrunutil.NewWaiter(), nil
|
||||
}
|
||||
|
||||
// We know that the images should be cached locally already as we have pulled them using
|
||||
// crictl in the preflight checks. Hence we can have a pretty short timeout for the kubelet
|
||||
// to start creating Static Pods.
|
||||
timeout := 4 * time.Minute
|
||||
return apiclient.NewKubeWaiter(client, timeout, out), nil
|
||||
}
|
||||
|
|
|
@ -178,6 +178,9 @@ const (
|
|||
// TLSBootstrapTimeout specifies how long kubeadm should wait for the kubelet to perform the TLS Bootstrap
|
||||
TLSBootstrapTimeout = 2 * time.Minute
|
||||
|
||||
// DefaultControlPlaneTimeout specifies the default control plane (actually API Server) timeout for use by kubeadm
|
||||
DefaultControlPlaneTimeout = 4 * time.Minute
|
||||
|
||||
// MinimumAddressesInServiceSubnet defines minimum amount of nodes the Service subnet should allow.
|
||||
// We need at least ten, because the DNS service is always at the tenth cluster clusterIP
|
||||
MinimumAddressesInServiceSubnet = 10
|
||||
|
|
|
@ -16,6 +16,7 @@ APIServer:
|
|||
Name: WritableVolume
|
||||
PathType: ""
|
||||
ReadOnly: false
|
||||
TimeoutForControlPlane: 4m0s
|
||||
AuditPolicyConfiguration:
|
||||
LogDir: /var/log/kubernetes/audit
|
||||
LogMaxAge: 2
|
||||
|
|
|
@ -29,6 +29,7 @@ apiServer:
|
|||
- hostPath: /host/writable
|
||||
mountPath: /mount/writable
|
||||
name: WritableVolume
|
||||
timeoutForControlPlane: 4m0s
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
auditPolicy:
|
||||
logDir: /var/log/kubernetes/audit
|
||||
|
|
|
@ -18,7 +18,8 @@ nodeRegistration:
|
|||
- effect: NoSchedule
|
||||
key: node-role.kubernetes.io/master
|
||||
---
|
||||
apiServer: {}
|
||||
apiServer:
|
||||
timeoutForControlPlane: 4m0s
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
auditPolicy:
|
||||
logDir: /var/log/kubernetes/audit
|
||||
|
|
Loading…
Reference in New Issue