diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go index 99aacc28b08..8051feed06b 100644 --- a/cmd/kubeadm/app/constants/constants.go +++ b/cmd/kubeadm/app/constants/constants.go @@ -185,6 +185,10 @@ const ( TLSBootstrapTimeout = 5 * time.Minute // TLSBootstrapRetryInterval specifies how long kubeadm should wait before retrying the TLS Bootstrap check TLSBootstrapRetryInterval = 5 * time.Second + // APICallWithWriteTimeout specifies how long kubeadm should wait for api calls with at least one write + APICallWithWriteTimeout = 40 * time.Second + // APICallWithReadTimeout specifies how long kubeadm should wait for api calls with only reads + APICallWithReadTimeout = 15 * time.Second // PullImageRetry specifies how many times ContainerRuntime retries when pulling image failed PullImageRetry = 5 diff --git a/cmd/kubeadm/app/util/apiclient/idempotency.go b/cmd/kubeadm/app/util/apiclient/idempotency.go index e8ffee8c06c..f893c352cec 100644 --- a/cmd/kubeadm/app/util/apiclient/idempotency.go +++ b/cmd/kubeadm/app/util/apiclient/idempotency.go @@ -205,16 +205,18 @@ func DeleteDeploymentForeground(client clientset.Interface, namespace, name stri // CreateOrUpdateRole creates a Role if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. func CreateOrUpdateRole(client clientset.Interface, role *rbac.Role) error { - if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Create(context.TODO(), role, metav1.CreateOptions{}); err != nil { - if !apierrors.IsAlreadyExists(err) { - return errors.Wrap(err, "unable to create RBAC role") - } + return wait.PollImmediate(constants.APICallRetryInterval, constants.APICallWithWriteTimeout, func() (bool, error) { + if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Create(context.TODO(), role, metav1.CreateOptions{}); err != nil { + if !apierrors.IsAlreadyExists(err) { + return false, errors.Wrap(err, "unable to create RBAC role") + } - if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Update(context.TODO(), role, metav1.UpdateOptions{}); err != nil { - return errors.Wrap(err, "unable to update RBAC role") + if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Update(context.TODO(), role, metav1.UpdateOptions{}); err != nil { + return false, errors.Wrap(err, "unable to update RBAC role") + } } - } - return nil + return true, nil + }) } // CreateOrUpdateRoleBinding creates a RoleBinding if the target resource doesn't exist. If the resource exists already, this function will update the resource instead.