mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-17 02:06:23 +00:00
Merge pull request #138959 from neolit123/automated-cherry-pick-of-#138957-origin-release-1.35
Automated cherry pick of #138957: kubeadm: use dedicated ClusterRole for apiserver kubelet client
This commit is contained in:
@@ -108,6 +108,11 @@ func runBootstrapToken(c workflow.RunData) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create RBAC rules that allow the API server kubelet client to access the kubelet API
|
||||
if err := nodebootstraptokenphase.AllowAPIServerToAccessKubeletAPI(client); err != nil {
|
||||
return errors.Wrap(err, "error allowing API server to access kubelet API")
|
||||
}
|
||||
|
||||
// Create the cluster-info ConfigMap with the associated RBAC rules
|
||||
if err := clusterinfophase.CreateBootstrapConfigMapIfNotExists(client, kubeconfig); err != nil {
|
||||
return errors.Wrap(err, "error creating bootstrap ConfigMap")
|
||||
|
||||
@@ -79,6 +79,11 @@ func runBootstrapToken(c workflow.RunData) error {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
// Create/update RBAC rules that allow the API server kubelet client to access the kubelet API
|
||||
if err := nodebootstraptoken.AllowAPIServerToAccessKubeletAPI(client); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
// Create/update RBAC rules that makes the cluster-info ConfigMap reachable
|
||||
if err := clusterinfophase.CreateClusterInfoRBACRules(client); err != nil {
|
||||
errs = append(errs, err)
|
||||
|
||||
@@ -210,6 +210,11 @@ const (
|
||||
// built-in ClusterRole.
|
||||
ClusterAdminsGroupAndClusterRoleBinding = "kubeadm:cluster-admins"
|
||||
|
||||
// KubeletAPIAdminClusterRoleBindingName is the name of the ClusterRoleBinding for the apiserver kubelet client
|
||||
KubeletAPIAdminClusterRoleBindingName = "kubeadm:apiserver-kubelet-client"
|
||||
// KubeletAPIAdminClusterRoleName is the name of the built-in ClusterRole for kubelet API access
|
||||
KubeletAPIAdminClusterRoleName = "system:kubelet-api-admin"
|
||||
|
||||
// KubernetesAPICallTimeout specifies how long kubeadm should wait for API calls
|
||||
KubernetesAPICallTimeout = 1 * time.Minute
|
||||
// KubernetesAPICallRetryInterval defines how long kubeadm should wait before retrying a failed API operation
|
||||
|
||||
@@ -130,3 +130,25 @@ func AutoApproveNodeCertificateRotation(client clientset.Interface) error {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// AllowAPIServerToAccessKubeletAPI creates RBAC rules that allow the API server kubelet client to access the kubelet API
|
||||
func AllowAPIServerToAccessKubeletAPI(client clientset.Interface) error {
|
||||
fmt.Println("[bootstrap-token] Configured RBAC rules to allow the API server kubelet client certificate to access the kubelet API")
|
||||
|
||||
return apiclient.CreateOrUpdate(client.RbacV1().ClusterRoleBindings(), &rbac.ClusterRoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: constants.KubeletAPIAdminClusterRoleBindingName,
|
||||
},
|
||||
RoleRef: rbac.RoleRef{
|
||||
APIGroup: rbac.GroupName,
|
||||
Kind: "ClusterRole",
|
||||
Name: constants.KubeletAPIAdminClusterRoleName,
|
||||
},
|
||||
Subjects: []rbac.Subject{
|
||||
{
|
||||
Kind: rbac.UserKind,
|
||||
Name: constants.APIServerKubeletClientCertCommonName,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -278,6 +278,63 @@ func TestAllowBootstrapTokensToGetNodes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllowAPIServerToAccessKubeletAPI(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
client clientset.Interface
|
||||
}{
|
||||
{
|
||||
name: "ClusterRoleBindings is empty",
|
||||
client: clientsetfake.NewSimpleClientset(),
|
||||
},
|
||||
{
|
||||
name: "ClusterRoleBindings already exists",
|
||||
client: newMockClusterRoleBinddingClientForTest(t, &rbac.ClusterRoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: constants.KubeletAPIAdminClusterRoleBindingName,
|
||||
},
|
||||
RoleRef: rbac.RoleRef{
|
||||
APIGroup: rbac.GroupName,
|
||||
Kind: "ClusterRole",
|
||||
Name: constants.KubeletAPIAdminClusterRoleName,
|
||||
},
|
||||
Subjects: []rbac.Subject{
|
||||
{
|
||||
Kind: rbac.UserKind,
|
||||
Name: constants.APIServerKubeletClientCertCommonName,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "Create new ClusterRoleBindings",
|
||||
client: newMockClusterRoleBinddingClientForTest(t, &rbac.ClusterRoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: constants.KubeletAPIAdminClusterRoleBindingName,
|
||||
},
|
||||
RoleRef: rbac.RoleRef{
|
||||
APIGroup: rbac.GroupName,
|
||||
Kind: "ClusterRole",
|
||||
Name: constants.KubeletAPIAdminClusterRoleName,
|
||||
},
|
||||
Subjects: []rbac.Subject{
|
||||
{
|
||||
Kind: rbac.GroupKind,
|
||||
Name: constants.NodesGroup,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := AllowAPIServerToAccessKubeletAPI(tt.client); err != nil {
|
||||
t.Errorf("AllowAPIServerToAccessKubeletAPI() return error = %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newMockClusterRoleBinddingClientForTest(t *testing.T, clusterRoleBinding *rbac.ClusterRoleBinding) *clientsetfake.Clientset {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
_, err := client.RbacV1().ClusterRoleBindings().Create(context.TODO(), clusterRoleBinding, metav1.CreateOptions{})
|
||||
|
||||
@@ -317,9 +317,8 @@ func KubeadmCertKubeletClient() *KubeadmCert {
|
||||
CAName: "ca",
|
||||
config: pkiutil.CertConfig{
|
||||
Config: certutil.Config{
|
||||
CommonName: kubeadmconstants.APIServerKubeletClientCertCommonName,
|
||||
Organization: []string{kubeadmconstants.ClusterAdminsGroupAndClusterRoleBinding},
|
||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
CommonName: kubeadmconstants.APIServerKubeletClientCertCommonName,
|
||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user