[Kubernetes] How to create a user for connecting to a cluster

table of contents
Hello!
I'm Hide, the Ramen King from Beyond Inc.'s Osaka office.
This is my 14th post.
Last time, I wrote about how to set up Basic authentication with Cloudflare Workers!
The setup is relatively easy, but if you make a mistake in the settings, you may not be able to view the site at all.
I've introduced an easy-to-understand setup method to avoid mistakes, so if you're interested, please check it out.
overview

I want to create a separate user to connect to the Kubernetes cluster, but I don't know how .
I also want to adjust the permissions given to the user, but I really don't know how.
Oh? Am I stuck?
Have you ever thought something like the above?
I also knew that it was possible to create a separate user to connect to the cluster, but the more I looked into it, the more difficult it seemed...
After much trial and error, I was finally able to create it, so if you want to create one, please use this as a reference!
Let's give it a try!
Precautions

This procedure does not explain basic Kubernetes concepts or resources.
Also, for managed Kubernetes clusters on each cloud, such as EKS or GKE, the method for adding users may differ. If
you are running Kubernetes on a cloud, please refer to the respective references.
procedure
1. Create and encode the key
1-1. Create a private key and a public key
*Please enter your username in {username}
cd .kube/ openssl genrsa -out {UserName}.key 2048 openssl req -new -key {UserName}.key -out {UserName}.csr -subj "/CN={UserName}"
Example: If the user name is example-test
openssl genrsa -out example-test.key 2048 openssl req -new -key example-test.key -out example-test.csr -subj "/CN=example-test"
1-2.Encode with base64
cat {UserName}.csr | base64 | tr -d "\n"
⇒The encoded value will be output, so make a note of it
example:
[example-test@bastion01 ~]$ cat example-test.csr | base64 | tr -d "\n" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2. Apply the created CSR and set it
2-1.Create a yaml file
Enter the username in
{ UserName *Enter the encoded value in {EncodeValue}
vi {UserName}-csr.yaml apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: {UserName} spec: request: {EncodeValue} signerName: kubernetes.io/kube-apiserver-client usages: - client auth
example:
vi example-test-csr.yaml apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: example-test spec: request: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx signerName: kubernetes.io/kube-apiserver-client usages: - client auth
2-2.apply the yaml file
kubectl apply -f {UserName}-csr.yaml
example:
[example-test@bastion01 ~]$ kubectl apply -f example-test-csr.yaml certificatesigningrequest.certificates.k8s.io/example-test created
2-3. Check if it was applied
*The status is Pending because the CSR has not been approved.
*Note the value output in NAME.
kubectl get csr
example:
[example-test@bastion01 ~]$ kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION example-test 12s kubernetes.io/kube-apiserver-client xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 〈none〉 Pending
2-4.Approve CSR
* Enter the NAME value you noted down earlier in {CsrName}
kubectl certificate approve {CsrName}
example:
[example-test@bastion01 ~]$ kubectl certificate approve example-test certificatesigningrequest.certificates.k8s.io/example-test approved
2-5. Check CSR approval
*If the CONDITION column says approved, it is approved
kubectl get csr
example:
[example-test@bastion01 ~]$ kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION example-test 14m kubernetes.io/kube-apiserver-client xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 〈none〉 Approved,Issued
2-6.Create a crt file
* Enter the NAME value you noted down earlier in {CsrName}
kubectl get csr {CrtName} -o jsonpath='{.status.certificate}' | base64 -d > {CrtName}.crt
3. Add User and Context
3-1. Add User and Certificate Information
*Please enter your username in {UserName}
kubectl config set-credentials {UserName} --client-key={UserName}.key --client-certificate={UserName}.crt --embed-certs=true
example:
[example-test@bastion01 ~]$ kubectl config set-credentials example-test --client-key=example-test.key --client-certificate=example-test.crt --embed-certs=true User "example-test"
*The settings will be automatically added to .kube/config as shown below
cat ~/.kube/config
- name: example-test user: client-certificate-data: xxxxxxxxxxxxxxxxxxxxx client-key-data: xxxxxxxxxxxxxxxxxxxxxx
3-2. Note down the cluster name
cat ~/.kube/config
Example:
*name is the cluster name
apiVersion: v1 clusters: - cluster: certificate-authority-data: xxxxxxxxxxxxxxxxxxxxxxx server: https://xxxxxxxxxxxxxxxxxxxxxxx name: xxxxxxxxxxxxxxx
3-3.Add to context
*Please enter your username in {UserName}
*Please enter the value you noted down earlier in {ClusterName}
kubectl config set-context {UserName} --cluster={ClusterName} --user={UserName}
example:
[example-test@example-testbastion01 ~]$ kubectl config set-context example-test --cluster=xxxxxxxxxxxx --user=example-test Context "example-test" created.
*The settings will be automatically added to .kube/config as shown below
contexts: - context: cluster: xxxxxxxxxxx user: xxxxxxxxxxxxxx name: xxxxxxxxxxxxxxx - context: cluster: xxxxxxxxxxxxxx user: example-test name: example-test
4. Grant permissions
Creating a new cluster role and granting it any privileges
1. Create a ClusterRole.
*Enter the cluster role name in {ClusterRoleName}.
*Set {VerbName} and {ResourceName} using the table below as a reference.
kubectl create clusterrole {ClusterRoleName} --verb={VerbName} --resource={ResourceName}
* List of main resource names and verb names
| resource name | namespace | nodes | pods | services | Ingress | sercrets | configmaps |
| verb name | remarks |
| get | Get Resources |
| list | Listing resources |
| create | Create a resource |
| update | Update Resources |
| patch | Partially update a resource |
| delete | Delete a resource |
| deletecollection | Bulk delete resources |
| watch | Monitor resource changes |
Example: ReadOnly permission for a Pod
[example-test@bastion01 ~]$ kubectl create clusterrole pod-readonly --verb=get,list,watch --resource=pods clusterrole.rbac.authorization.k8s.io/pod-readonly created
2. Check the created cluster role.
*Please enter the cluster role name in {ClusterRoleName}.
kubectl describe clusterrole {ClusterRoleName}
example:
[example-test@bastion01 ~]$ kubectl describe clusterrole pod-readonly Name: pod-readonly Labels:<none> Annotations:<none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch]
3. Grant the permissions of the created cluster role to the user
. *Enter the cluster role binding name in {ClusterRoleName}
*Enter the user name in {UserName}
kubectl create clusterrolebinding {ClusterRoleBindingName} --clusterrole={ClusterRoleName} --user={UserName}
example:
[example-test@bastion01 ~]$ kubectl create clusterrolebinding pod-readonly-binding --clusterrole=pod-readonly --user=example-test clusterrolebinding.rbac.authorization.k8s.io/pod-readonly-binding created
4. Confirm that permissions have been granted
. If the username specified in user is in Subjects, there is no problem.
kubectl describe clusterrolebinding {ClusterRoleBindingName}
example:
[example-test@bastion01 ~]$ kubectl describe clusterrolebinding pod-readonly-binding Name: pod-readonly-binding Labels:<none> Annotations:<none> Role: Kind: ClusterRole Name: pod-readonly-binding Subjects: Kind Name Namespace ---- ---- -------- User example-test
To assign a predefined cluster role:
1. Grant a user the privileges of a predefined cluster role.
* {ClusterRoleName} is the cluster role binding name.
* {ClusterRoleName} is the cluster role name.
* {UserName} is the user name.
kubectl create clusterrolebinding {ClusterRoleBindingName} --clusterrole={ClusterRoleName} --user={UserName}
example:
[example-test@bastion01 ~]$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=example-test clusterrolebinding.rbac.authorization.k8s.io/cluster-admin-binding created
*List of predefined cluster roles
| Default ClusterRole | Default ClusterRoleBinding | explanation |
| cluster-admin | system:masters group | Allows a superuser to perform any action on any resource. When used in a ClusterRoleBinding, it grants full control over all resources in the cluster and in all Namespaces. When used in a RoleBinding, it grants full control over all resources in the RoleBinding's Namespaces, including the Namespace itself |
| admin | None | Allows administrative access, intended to be granted within a Namespace using a RoleBinding. When used in a RoleBinding, allows read/write access to most resources in the Namespace, including the ability to create Roles and RoleBindings within the Namespace. This Role does not allow write access to resource quotas or the Namespace itself |
| edit | None | Grants read/write access to most objects in a Namespace. This role does not grant permission to view or modify Roles or RoleBindings. However, this role grants access to Secrets and allows Pods to run as any ServiceAccount in the Namespace, and can be used to obtain the API access level of any ServiceAccount in the Namespace |
| view | None | Grants read-only access to view most objects in a Namespace, but cannot view Roles or RoleBindings. This Role does not allow viewing Secrets, as reading their contents would give access to the credentials of any ServiceAccount in the Namespace. This grants API access as any ServiceAccount in the Namespace (a form of privilege escalation) |
2. Check that permissions have been granted.
*If the username specified in user is in Subjects, there is no problem.
kubectl describe clusterrolebinding {ClusterRoleBindingName}
example:
[example-test@bastion01 ~]$ kubectl describe clusterrolebinding cluster-admin-binding Name: cluster-admin-binding Labels:<none> Annotations:<none> Role: Kind: ClusterRole Name: cluster-admin Subjects: Kind Name Namespace ---- ---- --------- User example-test
5. Operation check
5-1. Changing the context
*Please enter your username in {UserName}
*The user you use will be switched here
kubectl config use-context {UserName}
example:
[example-test@bastion01 ~]$ kubectl config use-context example-test Switched to context "example-test".
5-2. Check the context (current user)
kubectl config current-context
example:
[example-test@bastion01 ~]$ kubectl config current-context example-test
5-3. Execute commands with kubectl
*If you have given ReadOnly permission to the Pod, it will look like this:
[example-test@bastion01 ~]$ kubectl get po NAME READY STATUS RESTARTS AGE xxxx-f5p2t 1/1 Ready 0 261d
[example-test@bastion01 ~]$ kubectl get node Error from server (Forbidden): nodes is forbidden: User "example-test" cannot list resource "nodes" in API group "" at the cluster scope
summary
What did you think?
By creating a user to connect to a cluster in Kubernetes, you can freely manage user permissions.
Reusing a user with cluster-admin privileges can lead to unexpected accidents during operation, so
if multiple people are operating the system, we recommend creating users as similar to Linux users as possible!
Please use this as a reference when operating Kubernetes!
5