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

* Kirimen (Juso, Osaka)

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.

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

 

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!

If you found this article helpful , please give it a like!
5
Loading...
5 votes, average: 1.00 / 15
1,274
X facebook Hatena Bookmark pocket

The person who wrote this article

About the author

Hide@Infrastructure Engineer

It all started with a very interesting interview.
A mid-career employee of the System Solutions Department in Osaka.My
job is to build and operate servers and clouds!
I have the qualifications of LPIC1, AWS SAA, and OCI Architect Associate.

Actually, I love ramen and
have investigated over 100 stores in Osaka (。-∀-) I'm striving to become the Ramen King of Nibi Beyond
!

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