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

* Kirimen (Juso, Osaka)

Hello!
This is Hide, the Ramen King from Beyond Co., Ltd.'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, there's a possibility that your site might become inaccessible.
I've explained the setup method in an easy-to-understand way so that you won't make any mistakes, so please check it out if you're interested.

How to use Basic Authentication with Cloudflare Workers

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 I give to the user, but I really don't know how.
Uh oh, am I stuck?

 

Have you ever thought something like the above?
I knew that it was possible to create a separate user to connect to the cluster, but the more I researched it, the more difficult it seemed...
After much trial and error, I finally managed to create one, so please use this as a reference if you want to create one!
Let's get started!

Precautions

This procedure does not cover basic Kubernetes concepts or resource explanations.
Also, the method for adding users may differ for managed Kubernetes clusters on cloud services such as EKS and GKE. If
you are running Kubernetes on a cloud, please refer to the respective documentation.

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

{UserNameReplace
. * Replace {EncodeValue} with the encoded value.

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 down 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 will be 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}
* and 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.
*Please enter the cluster role name in {ClusterRoleName}.
* *For {VerbName} and {ResourceName}, please refer to the table below.*

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. Verify 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 user the permissions for the created cluster role
. *Please enter the cluster role binding name in {ClusterRoleName}
*Please enter the username 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. Verify permission is granted
. *If the username specified in "user" is present 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 the user permissions for a predefined cluster role
. *Please enter the cluster role binding name in {ClusterRoleName}.
*Please enter the cluster role name in {ClusterRoleName}.
*Please enter the username in {UserName}.

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)
・Reference materials
Use RBAC authorization
https://kubernetes.io/ja/docs/reference/access-authn-authz/rbac/

 

2. Verify that permissions are granted.
*If the username specified in "user" is present 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 will be using will switch 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

How was it?
By creating a user to connect to the cluster in Kubernetes, you can freely manage user permissions.
Reusing a user with cluster-admin privileges can lead to unexpected accidents during operation, so
especially when multiple people are operating, we recommend creating users as similarly to Linux users as possible!
Please keep this in mind when operating Kubernetes!

If you found this article helpful,please give it a "Like"!
5
Loading...
5 votes, average: 1.00 / 15
1,410
X Facebook Hatena Bookmark pocket

The person who wrote this article

About the author

Hide@Infrastructure Engineer

thanks to an incredibly interesting interview.
I joined the company mid-career in the System Solutions Department in Osaka,
My work involves building and operating servers and cloud services!
I also hold LPIC1, AWS SAA, and OCI Architect Associate certifications.

Actually, I love ramen and
have already investigated over 100 ramen shops in Osaka (。-∀-) I'm striving to become the Ramen King of Nihi Beyond
ビヨンドのラーメン王を目指し奮闘中!!

I'm also on Twitter, so please follow me! (´∇`)
Click the Twitter icon in the upper right corner!