RBAC with kubernetes

I will create a private key, then sign it using openssl

openssl genrsa -out myuser.key 2048

openssl req -new -key myuser.key -out myuser.csr -subj '/CN=myuser/O=databases'

Create a CertificateSigningRequest

First Methode

Using kubectl:

cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser
spec:
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400  # one day
  usages:
  - client auth
EOF

Approve the CertificateSigningRequest

kubectl get csr

kubectl certificate approve myuser

Get the certificate

kubectl get csr/myuser -o yaml

The certificate value is in Base64-encoded format under status.certificate.

Export the issued certificate from the CertificateSigningRequest.

kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt

Seconde Methode

Since i am connected to the manger node i can sign the certificate myself after i have generated the request

touk@k8smaster:~/k8s-users$ sudo  openssl x509 -req -in taki.csr -CAcreateserial -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -out taki.crt -days 1000
Signature ok
subject=CN = taki, O = databases
Getting CA Private Key

Create the Kubeconfig file

kubectl --kubeconfig=taki.config config set-cluster takicluster --server=https://k8smaster:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs

kubectl --kubeconfig=taki.config config set-credentials --embed-certs --client-certificate taki.crt --client-key=taki.key taki --username=taki

kubectl --kubeconfig=taki.config config set-context takictx --cluster takicluster --user taki --namespace databases

kubectl --kubeconfig=taki.config config use-context takictx

touk@k8smaster:~/k8s-users$ kubectl --kubeconfig taki.config version
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
Client Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.1", GitCommit:"4c9411232e10168d7b050c49a1b59f6df9d7ea4b", GitTreeState:"clean", BuildDate:"2023-04-14T13:21:19Z", GoVersion:"go1.20.3", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v5.0.1
Server Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.1", GitCommit:"4c9411232e10168d7b050c49a1b59f6df9d7ea4b", GitTreeState:"clean", BuildDate:"2023-04-14T13:14:42Z", GoVersion:"go1.20.3", Compiler:"gc", Platform:"linux/amd64"}

**Create Role and RoleBinding

kubectl --namespace databases create role databasemanager --verb=list,get,create,delete --resource=pods

touk@k8smaster:~/k8s-users$ k get roles
NAME              CREATED AT
databasemanager   2023-09-09T14:34:30Z

Now we bind it:

kubectl --namespace databases create rolebinding databasemanagerbinding --user=taki --role=databasemanager

touk@k8smaster:~/k8s-users$ kubectl --namespace databases describe role
Name:         databasemanager
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [list get create delete]
touk@k8smaster:~/k8s-users$ kubectl --namespace databases describe rolebinding
Name:         databasemanagerbinding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  databasemanager
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  taki

And now the user will be able to use the cluster with it’s permission:

touk@k8smaster:~/k8s-users$ kubectl --kubeconfig taki.config --namespace databases get pods
No resources found in databases namespace.

And if i try to interact with something else than pods:

kubectl --kubeconfig taki.config --namespace databases get services

This error show: Error from server (Forbidden): services is forbidden: User "taki" cannot list resource "services" in API group "" in the namespace "databases"

Let’s create a pod:

kubectl --kubeconfig taki.config --namespace databases run --image=mysql --port=3306 mysqldb

touk@k8smaster:~/k8s-users$ kubectl --kubeconfig taki.config --namespace databases run --image=mysql --port=3306 mysqldb
pod/mysqldb created






From kodecloud lab:

How to creat a context for a specifi user

kubectl config set-credentials martin --client-certificate=martin.crt --client-key=martin.key

kubectl config set-context developer --user=martin --cluster=kubernetes

kubectl config use-context developer

Kepp in mind that i have this:

controlplane ~   ls
developer-rolebinding.yml  developer-role.yml  jekyll-node-service.yml  jekyll-pvc.yml  jekyll.yml  martin.crt  martin.csr  martin.key