kubernetes RBAC
By Aravind
Role Based Access Control (RBAC)
ClusterRoles and roles define the action the user can perform within a cluster or namespace Certificates generated using kubeadm will be valid for a year.
From the control node, create a directory to hold keys
root@k8s-master:~/cka_practice# mkdir cert && cd cert
Generate the keys
root@k8s-master:~/cka_practice/cert# openssl genrsa -out aprabh.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
...............................................................................+++++
..........................+++++
e is 65537 (0x010001)
Create a sign request (CSR)
root@k8s-master:~/cka_practice/cert# openssl req -new -key aprabh.key -out aprabh.csr -subj "/CN=aprabh/O=cka-study-guide"
root@k8s-master:~/cka_practice/cert# ls -lrt
total 8
-rw------- 1 root root 1675 Jun 26 13:36 aprabh.key
-rw-r--r-- 1 root root 924 Jun 26 13:38 aprabh.csr
Sign the kubernetes cluster certificate authority
root@k8s-master:~/cka_practice/cert# openssl x509 -req -in aprabh.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out aprabh.crt -days 364
Signature ok
subject=CN = aprabh, O = cka-study-guide
Getting CA Private Key
Create the user in k8s
Create the user in kubernetes by setting a user in kubeconfig. Point the CRT and key file. Set the context entry on the kubeconfig file for the user.
root@k8s-master:~/cka_practice/cert# kubectl config set-credentials aprabh --client-certificate=aprabh.crt --client-key=aprabh.key
User "aprabh" set.
root@k8s-master:~/cka_practice/cert# kubectl config set-context aprabh-context --cluster=kubeadm --user=aprabh
Context "aprabh-context" created.
Switch context to new user
root@k8s-master:~/cka_practice/cert# kubectl config use-context aprabh-context
Switched to context "aprabh-context".
root@k8s-master:~/cka_practice/cert# kubectl config current-context
aprabh-context
Since no permissions were given, no kubectl
commands can be run. you will notice erros as below
root@k8s-master:~/cka_practice# kubectl get pods
The connection to the server localhost:8080 was refused - did you specify the right host or port?
so switch to admin context
root@k8s-master:~/cka_practice# k config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
Service accounts
Kubernetes cluster comes with default service account. Any pods which doesnt explicitely mention will live in the default namespace.
Manifest for defining a service account
root@k8s-master:~/cka_practice# more serviceaccount.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: test
Apply
root@k8s-master:~/cka_practice# kubectl apply -f serviceaccount.yaml
serviceaccount/test created
Verify
root@k8s-master:~/cka_practice# k get serviceaccounts
NAME SECRETS AGE
default 1 25d
test 1 2m9s
root@k8s-master:~/cka_practice# k describe serviceaccounts test
Name: test
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: test-token-d729d
Tokens: test-token-d729d
Events: <none>
Create a test pod with service account
root@k8s-master:~/cka_practice# more test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: testpod
spec:
serviceAccountName: test
containers:
- name: ubuntu
image: ubuntu:latest
command: ["/bin/sleep", "3650d"]
imagePullPolicy: IfNotPresent
restartPolicy: Always
Apply
root@k8s-master:~/cka_practice# kubectl apply -f test-pod.yaml
Verify
root@k8s-master:~/cka_practice# kubectl get pods
NAME READY STATUS RESTARTS AGE
testpod 1/1 Running 0 2m6s
root@k8s-master:~/cka_practice# kubectl describe pods testpod
Name: testpod
Namespace: default
< ------- snipped -------- >
Containers:
ubuntu:
Container ID: docker://6e43167cb4b01c243b7cdefcf55755a15670091ac9948eaec82cb54305923eca
Image: ubuntu:latest
Image ID: docker-pullable://ubuntu@sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
Port: <none>
Host Port: <none>
Command:
/bin/sleep
3650d
State: Running
Started: Sun, 26 Jun 2022 14:32:22 -0400
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-dgtsp (ro)
< -------- Snipped ------- >
Notice the mounts mentioned as readonly service account.
RBAC API Primitives
- Role: This helps declare operations that should be applied to a resource. For example allow to list, delete of pods. Any operation not explicitely mentioned will consider as deny operation.
- Rolebinding: Binds the role to the subject. For example, bind the role to user
Default user facing role
- cluster-admin : Alllows read and write access to resources across all namespaces
- admin: allows read and write access to resources in a namespace include role and rolebindings
- edit: allows read and write access to resources in namespaces except roles and role bindings. Provides access to secrets
- view: allows read only access to resources in namespaces except roles, rolebindings and secrets.
Create a role
root@k8s-master:~/cka_practice# more role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: read-only
rules:
- apiGroups:
- ""
resources:
- pods
- services
verbs:
- list
- get
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- list
- get
- watch
Verify
root@k8s-master:~/cka_practice# kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/read-only created
root@k8s-master:~/cka_practice# k get roles
NAME CREATED AT
read-only 2022-06-26T18:55:52Z
root@k8s-master:~/cka_practice# k describe role read-only
Name: read-only
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [list get watch]
services [] [] [list get watch]
deployments.apps [] [] [list get watch]
Create a role binding
root@k8s-master:~/cka_practice# more rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-only-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: read-only
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: aprabh
Verify
root@k8s-master:~/cka_practice# kubectl apply -f rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/read-only-binding created
root@k8s-master:~/cka_practice# k get rolebindings
NAME ROLE AGE
read-only-binding Role/read-only 48s
root@k8s-master:~/cka_practice# k describe rolebinding read-only-binding
Name: read-only-binding
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: read-only
Subjects:
Kind Name Namespace
---- ---- ---------
User aprabh
Create cluster role
root@k8s-master:~/cka_practice# more clusterole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: list-pods
labels:
rbac-pod-list: "true"
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
kubernetes
]
tags: kubernetes