Unified Authentication

For one or a group of user subjects (users, groups, or service accounts) in a member cluster, we can import them into Karmada control plane and grant them the clusters/proxy permission, so that we can access the member cluster with permission of the user subject through Karmada.

In this section, we use a serviceaccount named tom for the test.

Step1: Create ServiceAccount in member1 cluster (optional)

If the serviceaccount has been created in your environment, you can skip this step.

Create a serviceaccount that does not have any permission:

  1. kubectl --kubeconfig $HOME/.kube/members.config --context member1 create serviceaccount tom

Step2: Create ServiceAccount in Karmada control plane

  1. kubectl --kubeconfig $HOME/.kube/karmada.config --context karmada-apiserver create serviceaccount tom

In order to grant serviceaccount the clusters/proxy permission, apply the following rbac yaml file:

cluster-proxy-rbac.yaml:

unfold me to see the yaml

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRole
  3. metadata:
  4. name: cluster-proxy-clusterrole
  5. rules:
  6. - apiGroups:
  7. - 'cluster.karmada.io'
  8. resources:
  9. - clusters/proxy
  10. resourceNames:
  11. - member1
  12. verbs:
  13. - '*'
  14. ---
  15. apiVersion: rbac.authorization.k8s.io/v1
  16. kind: ClusterRoleBinding
  17. metadata:
  18. name: cluster-proxy-clusterrolebinding
  19. roleRef:
  20. apiGroup: rbac.authorization.k8s.io
  21. kind: ClusterRole
  22. name: cluster-proxy-clusterrole
  23. subjects:
  24. - kind: ServiceAccount
  25. name: tom
  26. namespace: default
  27. # The token generated by the serviceaccount can parse the group information. Therefore, you need to specify the group information below.
  28. - kind: Group
  29. name: "system:serviceaccounts"
  30. - kind: Group
  31. name: "system:serviceaccounts:default"
  1. kubectl --kubeconfig $HOME/.kube/karmada.config --context karmada-apiserver apply -f cluster-proxy-rbac.yaml

Step3: Access member1 cluster

Manually create a long-lived api token for the serviceaccount tom:

  1. kubectl apply -f - <<EOF
  2. apiVersion: v1
  3. kind: Secret
  4. metadata:
  5. name: tom
  6. annotations:
  7. kubernetes.io/service-account.name: tom
  8. type: kubernetes.io/service-account-token
  9. EOF

Obtain token of serviceaccount tom:

  1. kubectl get secret tom -oyaml | grep token: | awk '{print $2}' | base64 -d

Then construct a kubeconfig file tom.config for tom serviceaccount:

  1. apiVersion: v1
  2. clusters:
  3. - cluster:
  4. insecure-skip-tls-verify: true
  5. server: {karmada-apiserver-address} # Replace {karmada-apiserver-address} with karmada-apiserver-address. You can find it in /root/.kube/karmada.config file.
  6. name: tom
  7. contexts:
  8. - context:
  9. cluster: tom
  10. user: tom
  11. name: tom
  12. current-context: tom
  13. kind: Config
  14. users:
  15. - name: tom
  16. user:
  17. token: {token} # Replace {token} with the token obtain above.

Run the command below to access member1 cluster:

  1. kubectl --kubeconfig tom.config get --raw /apis/cluster.karmada.io/v1alpha1/clusters/member1/proxy/apis

We can find that we were able to access, but run the command below:

  1. kubectl --kubeconfig tom.config get --raw /apis/cluster.karmada.io/v1alpha1/clusters/member1/proxy/api/v1/nodes

It will fail because serviceaccount tom does not have any permissions in the member1 cluster.

Step4: Grant permission to Serviceaccount in member1 cluster

Apply the following YAML file:

member1-rbac.yaml

unfold me to see the yaml

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRole
  3. metadata:
  4. name: tom
  5. rules:
  6. - apiGroups:
  7. - '*'
  8. resources:
  9. - '*'
  10. verbs:
  11. - '*'
  12. ---
  13. apiVersion: rbac.authorization.k8s.io/v1
  14. kind: ClusterRoleBinding
  15. metadata:
  16. name: tom
  17. roleRef:
  18. apiGroup: rbac.authorization.k8s.io
  19. kind: ClusterRole
  20. name: tom
  21. subjects:
  22. - kind: ServiceAccount
  23. name: tom
  24. namespace: default
  1. kubectl --kubeconfig $HOME/.kube/members.config --context member1 apply -f member1-rbac.yaml

Run the command that failed in the previous step again:

  1. kubectl --kubeconfig tom.config get --raw /apis/cluster.karmada.io/v1alpha1/clusters/member1/proxy/api/v1/nodes

The access will be successful.

Or we can append /apis/cluster.karmada.io/v1alpha1/clusters/member1/proxy to the server address of tom.config, and then you can directly use:

  1. kubectl --kubeconfig tom.config get node

Note: For a member cluster that joins Karmada in pull mode and allows only cluster-to-karmada access, we can deploy apiserver-network-proxy (ANP) to access it.