DEV Community

Sina Tavakkol
Sina Tavakkol

Posted on

40 Days Of Kubernetes (23/40)

Day 23/40

Kubernetes RBAC Explained - Role Based Access Control Kubernetes

Video Link
@piyushsachdeva
Git Repository
My Git Repo

In this section we are looking into Role Based Access Control, RBAC, authorization.

Simple check if I have access to get pods or not:

root@localhost:~# kubectl auth whoami
ATTRIBUTE   VALUE
Username    kubernetes-admin
Groups      [kubeadm:cluster-admins system:authenticated]
root@localhost:~# kubectl auth can-i get pods
yes
Enter fullscreen mode Exit fullscreen mode

Because I am kubernetes-admin, in the group cluster-admins, I'm authorized to get pods :)
Then, let's check adam has the right or not:

root@localhost:~# kubectl auth can-i get pods --as adam
no
Enter fullscreen mode Exit fullscreen mode

We have to grant him to do it, so we need to define role and rolebinding objects.

Let's check the all role in our cluster:

root@localhost:~# kubectl get roles -A
NAMESPACE     NAME                                               CREATED AT
kube-public   kubeadm:bootstrap-signer-clusterinfo               2024-07-01T16:17:07Z
kube-public   system:controller:bootstrap-signer                 2024-07-01T16:17:06Z
kube-system   extension-apiserver-authentication-reader          2024-07-01T16:17:06Z
kube-system   kube-proxy                                         2024-07-01T16:17:08Z
kube-system   kubeadm:kubelet-config                             2024-07-01T16:17:07Z
kube-system   kubeadm:nodes-kubeadm-config                       2024-07-01T16:17:07Z
kube-system   leader-locking-nfs-client-nfs-client-provisioner   2024-07-06T07:07:02Z
kube-system   system::leader-locking-kube-controller-manager     2024-07-01T16:17:06Z
kube-system   system::leader-locking-kube-scheduler              2024-07-01T16:17:06Z
kube-system   system:controller:bootstrap-signer                 2024-07-01T16:17:06Z
kube-system   system:controller:cloud-provider                   2024-07-01T16:17:06Z
kube-system   system:controller:token-cleaner                    2024-07-01T16:17:06Z

Enter fullscreen mode Exit fullscreen mode

And rolebindings:

root@localhost:~# kubectl get rolebinding -A
NAMESPACE     NAME                                                ROLE                                                    AGE
kube-public   kubeadm:bootstrap-signer-clusterinfo                Role/kubeadm:bootstrap-signer-clusterinfo               23d
kube-public   system:controller:bootstrap-signer                  Role/system:controller:bootstrap-signer                 23d
kube-system   kube-proxy                                          Role/kube-proxy                                         23d
kube-system   kubeadm:kubelet-config                              Role/kubeadm:kubelet-config                             23d
kube-system   kubeadm:nodes-kubeadm-config                        Role/kubeadm:nodes-kubeadm-config                       23d
kube-system   leader-locking-nfs-client-nfs-client-provisioner    Role/leader-locking-nfs-client-nfs-client-provisioner   18d
kube-system   system::extension-apiserver-authentication-reader   Role/extension-apiserver-authentication-reader          23d
kube-system   system::leader-locking-kube-controller-manager      Role/system::leader-locking-kube-controller-manager     23d
kube-system   system::leader-locking-kube-scheduler               Role/system::leader-locking-kube-scheduler              23d
kube-system   system:controller:bootstrap-signer                  Role/system:controller:bootstrap-signer                 23d
kube-system   system:controller:cloud-provider                    Role/system:controller:cloud-provider                   23d
kube-system   system:controller:token-cleaner                     Role/system:controller:token-cleaner                    23d
Enter fullscreen mode Exit fullscreen mode

Role example

source

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
Enter fullscreen mode Exit fullscreen mode

Instead of spec we have rules in this object. verbs is access and when we set blank in the apiGroups it indicates the core API group.

There are several API groups in Kubernetes:

  • The core (also called legacy) group is found at REST path /api/v1. The core group is not specified as part of the apiVersion field, for example, apiVersion: v1.
  • The named groups are at REST path /apis/$GROUP_NAME/$VERSION and use apiVersion: $GROUP_NAME/$VERSION (for example, apiVersion: batch/v1). source

Let's apply the role in our cluster:

root@localhost:~# kubectl get role
No resources found in default namespace.
root@localhost:~# kubectl apply -f day23-role.yaml
role.rbac.authorization.k8s.io/pod-reader created
root@localhost:~# kubectl get roles
NAME         CREATED AT
pod-reader   2024-07-24T16:27:15Z
root@localhost:~# kubectl describe role pod-reader
Name:         pod-reader
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get watch list]

Enter fullscreen mode Exit fullscreen mode

It still needs to define to which user, this role should be applied, so we will define rolebinding which is binding roles to users.

RoleBinding example

source

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "adam" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
  name: adam # "name" is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io
Enter fullscreen mode Exit fullscreen mode

Apply the yaml file:

root@localhost:~# kubectl get rolebinding
No resources found in default namespace.
root@localhost:~# kubectl apply -f day23-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created
root@localhost:~# kubectl get rolebinding read-pods
NAME        ROLE              AGE
read-pods   Role/pod-reader   37s
root@localhost:~# kubectl describe rolebinding read-pods
Name:         read-pods
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  pod-reader
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  adam
Enter fullscreen mode Exit fullscreen mode

And finally:

root@localhost:~# kubectl auth can-i get pod --as adam
yes
Enter fullscreen mode Exit fullscreen mode

Then we are going to log in as user adam and get pods:

root@localhost:~# kubectl config set-credentials adam --client-key=adam.key --client-certificate=adam.crt
User "adam" set.
root@localhost:~# kubectl config set-context adam --cluster=kind-lucky-luke --user=adam
Context "adam" created.
root@localhost:~# kubectl config get-contexts
CURRENT   NAME              CLUSTER           AUTHINFO          NAMESPACE
          adam              kind-lucky-luke   adam
*         kind-lucky-luke   kind-lucky-luke   kind-lucky-luke

Enter fullscreen mode Exit fullscreen mode

Switch to new context, adam

root@localhost:~# kubectl config use-context adam
Switched to context "adam".
root@localhost:~# kubectl config get-contexts
CURRENT   NAME              CLUSTER           AUTHINFO          NAMESPACE
*         adam              kind-lucky-luke   adam
          kind-lucky-luke   kind-lucky-luke   kind-lucky-luke
root@localhost:~# kubectl auth whoami
ATTRIBUTE   VALUE
Username    adam
Groups      [system:authenticated]
root@localhost:~# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://127.0.0.1:39283
  name: kind-lucky-luke
contexts:
- context:
    cluster: kind-lucky-luke
    user: adam
  name: adam
- context:
    cluster: kind-lucky-luke
    user: kind-lucky-luke
  name: kind-lucky-luke
current-context: adam
kind: Config
preferences: {}
users:
- name: adam
  user:
    client-certificate: /root/adam.crt
    client-key: /root/adam.key
- name: kind-lucky-luke
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

Enter fullscreen mode Exit fullscreen mode

Check the permissions:

root@localhost:~# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
nginx-pod-3   1/1     Running   0          25s
root@localhost:~# kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "adam" cannot list resource "nodes" in API group "" at the cluster scope
Enter fullscreen mode Exit fullscreen mode

check with curl and the keys

root@localhost:~# curl https://127.0.0.1:39283/api/v1/namespaces/default/pods --key adam.key --cert adam.crt --cacert ca.crt
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "resourceVersion": "3003522"
  },
  "items": [
    {
      "metadata": {
        "name": "nginx-pod-3",
        "namespace": "default",
...
            "lastState": {},
            "ready": true,
            "restartCount": 0,
            "image": "docker.io/library/nginx:latest",
            "imageID": "docker.io/library/nginx@sha256:6af79ae5de407283dcea8b00d5c37ace95441fd58a8b1d2aa1ed93f5511bb18c",
            "containerID": "containerd://5ef66bb91400fd10cc3d9b9f0bfb08fd4d640df0f2c2834ec6598eb54edd4efb",
            "started": true
          }
        ],
        "qosClass": "BestEffort"
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Let's check the validity of certification expired date of adam:

root@localhost:~# openssl x509 -noout -dates -in adam.crt
notBefore=Jul 22 17:38:02 2024 GMT
notAfter=Aug  1 17:38:02 2024 GMT
Enter fullscreen mode Exit fullscreen mode

We extend it for a year again with openssl

root@localhost:~# openssl x509 -req -in adam.csr  -CA ca.crt -CAkey ca.key -CAcreateserial -out adam.crt -days 365
Certificate request self-signature ok
subject=CN = adam
root@localhost:~# openssl x509 -noout -dates -in adam.crt
notBefore=Jul 24 17:20:31 2024 GMT
notAfter=Jul 24 17:20:31 2025 GMT

Enter fullscreen mode Exit fullscreen mode

New user instruction:
source

1. openssl genrsa -out krishna.key 2048
2. openssl req -new -key krishna.key -out krishna.csr -subj "/CN=krishna"
3. change name, requests expired date in csr.yaml

4. cat krishna.csr | base64 >>> request
5. kubectl apply -f krishna-csr.yaml
6. kubectl certificate approve krishna

7. kubectl get csr krishna -o jsonpath='{.status.certificate}' | base64 -d > krishna.crt
8. kubectl create role developer --verb=get --verb=create --verb=list --verb=update --verb=delete --resource=pods
9. kubectl create rolebinding developer-role --role=developer --user=krishna

10. kubectl config set-credential krishna --client-key=krishna.key --client-certificate=krishna.crt
11. kubectl config set-context krishna --cluster=lucky-luke --user=krishna
12. kubectl config use-context krishna

13. check the premission

Enter fullscreen mode Exit fullscreen mode
  • Define Role and RoleBinding, Imperative way
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods

kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
Enter fullscreen mode Exit fullscreen mode

Top comments (0)