diff --git a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go index 0798befe929..e3ff4d20e64 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go +++ b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go @@ -683,13 +683,31 @@ func EnsureAdminClusterRoleBindingImpl(ctx context.Context, adminClient, superAd kubeadmconstants.ClusterAdminsGroupAndClusterRoleBinding, kubeadmconstants.SuperAdminKubeConfigFileName) - if _, err := superAdminClient.RbacV1().ClusterRoleBindings().Create( + err = wait.PollUntilContextTimeout( ctx, - clusterRoleBinding, - metav1.CreateOptions{}, - ); err != nil { - return nil, errors.Wrapf(err, "unable to create the %s ClusterRoleBinding", - kubeadmconstants.ClusterAdminsGroupAndClusterRoleBinding) + retryInterval, + retryTimeout, + true, func(ctx context.Context) (bool, error) { + if _, err := superAdminClient.RbacV1().ClusterRoleBindings().Create( + ctx, + clusterRoleBinding, + metav1.CreateOptions{}, + ); err != nil { + lastError = err + if apierrors.IsAlreadyExists(err) { + // This should not happen, as the previous "create" call that uses + // the admin.conf should have passed. Return the error. + return true, err + } + // Retry on any other type of error. + return false, nil + } + return true, nil + }) + if err != nil { + return nil, errors.Wrapf(lastError, "unable to create the %s ClusterRoleBinding by using %s", + kubeadmconstants.ClusterAdminsGroupAndClusterRoleBinding, + kubeadmconstants.SuperAdminKubeConfigFileName) } // Once the CRB is in place, start using the admin.conf client. diff --git a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go index cdbc4e51300..3705dbaeed5 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go +++ b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go @@ -902,6 +902,22 @@ func TestEnsureAdminClusterRoleBindingImpl(t *testing.T) { }, expectedError: false, }, + { + name: "super-admin.conf: admin.conf cannot create CRB, try to create CRB with super-admin.conf, encounter 'already exists' error", + setupAdminClient: func(client *clientsetfake.Clientset) { + client.PrependReactor("create", "clusterrolebindings", func(action clientgotesting.Action) (bool, runtime.Object, error) { + return true, nil, apierrors.NewForbidden( + schema.GroupResource{}, "name", errors.New("")) + }) + }, + setupSuperAdminClient: func(client *clientsetfake.Clientset) { + client.PrependReactor("create", "clusterrolebindings", func(action clientgotesting.Action) (bool, runtime.Object, error) { + return true, nil, apierrors.NewAlreadyExists( + schema.GroupResource{}, "name") + }) + }, + expectedError: true, + }, } for _, tc := range tests {