[Exploring Kubernetes] Creating a new Context to Demonstrate the Use of Role and RoleBinding

Puneeth Prakash
5 min readOct 19, 2023

--

  1. Create a new context and demonstrate the use of Role and RoleBinding

Creating the User
1) Create a private key.

controlplane $ alias k=kubectl

controlplane $ k get nodes
NAME STATUS ROLES AGE VERSION
controlplane Ready control-plane 36d v1.28.1
node01 Ready <none> 36d v1.28.1

controlplane $ openssl genrsa -out puneeth.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
……………………+++++
….+++++
e is 65537 (0x010001)

2) Create and approve a CertificateSigningRequest.

controlplane $ openssl req -new -key puneeth.key -out puneeth.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
— — -
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:karnataka
Locality Name (eg, city) []:Bengaluru
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Oracle
Organizational Unit Name (eg, section) []:Kubernetes
Common Name (e.g. server FQDN or YOUR name) []:puneeth
Email Address []:p@p.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:xxxxx
An optional company name []:Oracle

controlplane $ cat puneeth.csr | base64 | tr -d “\n”
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTVUpsYm1kaGJIVnlkVEVQTUEwR0ExVUVDZ3dHVDNKaFkyeGxNUk13RVFZRF…zJHQ2EyRDVUVTdWd0xwZzFyRHVEcW9WSHp1OCtrYlpndzJjd3VpVXlZQnRiTm03RmR3PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K

controlplane $ cat <<EOF | kubectl apply -f -
> apiVersion: certificates.k8s.io/v1
> kind: CertificateSigningRequest
> metadata:
> name: puneeth
> spec:
> request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0VBWURWUVFJREFscllYSnVZWFJoYTJFeApFakFRQmdOVkJBY01DVUpsYm1kaGJIVnlkVEVQTUEwR0ExVUVDZ3dHVDNKaFkyeGxNUk13RVFZRF…zJHQ2EyRDVUVTdWd0xwZzFyRHVEcW9WSHp1OCtrYlpndzJjd3VpVXlZQnRiTm03RmR3PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K
> signerName: kubernetes.io/kube-apiserver-client
> expirationSeconds: 86400 # one day
> usages:
> — client auth
> EOF
certificatesigningrequest.certificates.k8s.io/puneeth created

controlplane $ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
csr-46sxj 36d kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:z6kr08 <none> Approved,Issued
csr-6z592 36d kubernetes.io/kube-apiserver-client-kubelet system:node:controlplane <none> Approved,Issued
puneeth 38s kubernetes.io/kube-apiserver-client kubernetes-admin 24h Pending

controlplane $ kubectl certificate approve puneeth
certificatesigningrequest.certificates.k8s.io/puneeth approved

controlplane $ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
csr-46sxj 36d kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:z6kr08 <none> Approved,Issued
csr-6z592 36d kubernetes.io/kube-apiserver-client-kubelet system:node:controlplane <none> Approved,Issued
puneeth 55s kubernetes.io/kube-apiserver-client kubernetes-admin 24h Approved,Issued
controlplane $ kubectl get csr/puneeth -o yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{“apiVersion”:”certificates.k8s.io/v1",”kind”:”CertificateSigningRequest”,”metadata”:{“annotations”:{},”name”:”puneeth”},”spec”:{“expirationSeconds”:86400,”request”:”LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQyt6Q0NBZU1DQVFBd2dZVXhDekFKQmdOVkJBWVRBa2xPTVJJd0VBWURWUVFJREFscllYSnVZWFJoYTJFeApFakFRQmdOVkJBY01DVUpsYm1kaGJIVnlkVEVQTUEwR0ExVUVDZ3dHVDNKaFkyeGxNUk13RVFZRF…zJHQ2EyRDVUVTdWd0xwZzFyRHVEcW9WSHp1OCtrYlpndzJjd3VpVXlZQnRiTm03RmR3PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K”,”signerName”:”kubernetes.io/kube-apiserver-client”,”usages”:[“client auth”]}}
creationTimestamp: “2023–10–09T16:44:35Z”
name: puneeth
resourceVersion: “1891”
uid: c3727253–4588–4e28-a191–55feeef4a703
spec:
expirationSeconds: 86400
groups:
— system:masters
— system:authenticated
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQyt6Q0NBZU1DQVFBd2dZVXhDekFKQmdOVkJBWVRBa2xPTVJJd0VBWURWUVFJREFscllYSnVZWFJoYTJFeApFakFRQmdOVkJBY01DVUpsYm1kaGJIVnlkVEVQTUEwR0ExVUVDZ3dHVDNKaFkyeGxNUk13RVFZRF…zJHQ2EyRDVUVTdWd0xwZzFyRHVEcW9WSHp1OCtrYlpndzJjd3VpVXlZQnRiTm03RmR3PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K
signerName: kubernetes.io/kube-apiserver-client
usages:
— client auth
username: kubernetes-admin
status:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURVekNDQWp1Z0F3SUJBZ0lSQVA4aHZ4TjVWUi83bExmKzFTYUx4RVV3RFFZSktvWklodmNOQVFFTEJRQXcKRlRFVE1CRUdBMVVFQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TXpFd01Ea3hOalF3TWpkYUZ3MHlNekV3TVRBeA…NuNWJTWFV4dUpjQzZReHVUK0tibzVOMy9LTGFwOQoyZXRNYWhXRWhsbXR6TDYySnZyUFAxQ1l4cDNpak9wQ1k0YzdRMUxKNUdjTUNXNkpNK01nCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
conditions:
— lastTransitionTime: “2023–10–09T16:45:27Z”
lastUpdateTime: “2023–10–09T16:45:27Z”
message: This CSR was approved by kubectl certificate approve.
reason: KubectlApprove
status: “True”
type: Approved
controlplane $ kubectl get csr puneeth -o jsonpath=’{.status.certificate}’| base64 -d > puneeth.crt
controlplane $ kubectl config set-credentials puneeth --client-key=puneeth.key --client-certificate=puneeth.crt --embed-certs=true
User “puneeth” set.

controlplane $ ls
filesystem puneeth.crt puneeth.csr puneeth.key

controlplane $ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin

3) Add a context entry named puneeth to the kubeconfig file to represent the user.

controlplane $ kubectl config set-context puneeth --cluster=kubernetes --user=puneeth
Context “puneeth” created.

controlplane $ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
puneeth kubernetes puneeth
* kubernetes-admin@kubernetes kubernetes kubernetes-admin

controlplane $ k get po
No resources found in default namespace.

controlplane $ k --user=puneeth get po
Error from server (Forbidden): pods is forbidden: User “puneeth” cannot list resource “pods” in API group “” in the namespace “default”

Checking Default User Permissions
1) Change to the context to puneeth.

controlplane $ kubectl config use-context puneeth
Switched to context “puneeth”.

controlplane $ kubectl config current-context
puneeth

2) We get a Forbidden error while creating a Pod because this user does not have any role assigned to him at this point.

controlplane $ kubectl run nginix --image=nginx 
Error from server (Forbidden): pods is forbidden: User “puneeth” cannot create resource “pods” in API group “” in the namespace “default”
controlplane $

controlplane $ kubectl create role pod-reader --verb=watch --verb=get --verb=list --resource=pods
Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden: User “puneeth” cannot create resource “roles” in API group “rbac.authorization.k8s.io” in the namespace “default”

controlplane $ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* puneeth kubernetes puneeth
kubernetes-admin@kubernetes kubernetes kubernetes-admin

Granting Access to the User
1) Switch back to the original context with admin permissions.

controlplane $ kubectl config use-context kubernetes-admin@kubernetes
Switched to context “kubernetes-admin@kubernetes”.

2) Create a new Role named pod-reader. The Role should grant permissions to get, watch and list Pods.

controlplane $ kubectl create role pod-reader --verb=watch --verb=get --verb=list --resource=pods
role.rbac.authorization.k8s.io/pod-reader created

3) Create a new RoleBinding named read-pods. Map the user puneeth to the Role named pod-reader.

controlplane $ kubectl create rolebinding read-pods --role=pod-reader --user=puneeth
rolebinding.rbac.authorization.k8s.io/read-pods created

4) Make sure that both objects have been created properly.

controlplane $ kubectl get roles
NAME CREATED AT
pod-reader 2023–10–09T16:52:50Z

controlplane $ kubectl get rolebindings
NAME ROLE AGE
read-pods Role/pod-reader 17s
controlplane $ kubectl auth can-i --list --as=puneeth
Resources Non-Resource URLs Resource Names Verbs
selfsubjectreviews.authentication.k8s.io [] [] [create]
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/livez] [] [get]
[/livez] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/readyz] [] [get]
[/readyz] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]
pods [] [] [watch get list]

controlplane $ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
puneeth kubernetes puneeth
* kubernetes-admin@kubernetes kubernetes kubernetes-admin

5) Switch to the context named puneeth.

controlplane $ kubectl config use-context puneeth
Switched to context “puneeth”.

controlplane $ kubectl config current-context
puneeth

6) “Puneeth” User has the role to watch, list and get pods. So he will still not be able to create or run pods.
We would expect to see a forbidden error again.

controlplane $ kubectl run nginx --image=nginx 
Error from server (Forbidden): pods is forbidden: User “puneeth” cannot create resource “pods” in API group “” in the namespace “default”

7) List the Pods in the namespace. What would you expect to happen?
User is able to list, get and watch the Pods.

controlplane $ k get po
No resources found in default namespace.

controlplane $ k get po --all-namespaces
Error from server (Forbidden): pods is forbidden: User “puneeth” cannot list resource “pods” in API group “” at the cluster scope

controlplane $ k get po -n=default
No resources found in default namespace.

controlplane $ k get po -w

controlplane $ k get po
No resources found in default namespace.
controlplane $

--

--

Puneeth Prakash
Puneeth Prakash

Written by Puneeth Prakash

I work as a Subject Matter Expert in FMW at Oracle. This blogging space is to share my learning experiences. Views expressed here are solely my own.

No responses yet