top of page
Writer's pictureSathish Kumar

Kubernetes Administration- Users


Note: If you have missed my previous articles on Docker and Kubernetes, you can find them here. 
Application deployment models evolution.
Getting started with Docker.
Docker file and images.
Publishing images to Docker Hub and re-using them.
Docker- Find out what's going on.
Docker Networking- Part 1.
Docker Networking- Part 2.
Docker Swarm-Multi-Host container Cluster.
Docker Networking- Part 3 (Overlay Driver).
Introduction to Kubernetes.
Kubernetes- Diving in (Part 1)-Installing Kubernetes multi-node cluster.
Kubernetes-Diving in (Part2)- Services.
Kubernetes- Infrastructure As Code with Yaml (part 1).
Kubernetes- Infrastructure As Code Part 2- Creating PODs with YAML.
Kubernetes Infrastructure-as-Code part 3- Replicasets with YAML.
Kubernetes Infrastructure-as-Code part 4 - Deployments and Services with YAML.
Deploying a microservices APP with Kubernetes.
Kubernetes- Time based scaling of deployments with python client.
Kubernetes Networking - The Flannel network explained.
Kubernetes- Installing and using kubectl top for monitoring nodes and PoDs
Kubernetes Administration- Scheduling
Kubernetes Administration- Storage

Administration is an important part of maintaining any infrastructure be it physical, virtual, or container-based. Major administration tasks involve managing resources like compute (CPU, Memory), storage, users, etc. In Kubernetes Administration- Scheduling I gave a brief overview of requesting CPU and Memory resources for PoDs. Kubernetes Administration- Storage gives an overview of storage administration. In this article, I will attempt to give an overview of user administration in Kubernetes.


User administration generally involves the following:


Who can Access resources? i.e Authentication

What can they do ? i.e Authorization


Role-Based Access control is a method of authorization where a user's role in the organization determines what he can do with resources. For example, users with role admins might have complete control of the resources, whereas developer would be able to view resources and cannot create or delete resources. Kubernetes offers the ability to administer roles and attach users to roles both at namespace and cluster level. I will be describing these in a bit, but let's look at various components in Kubernetes where access control is required:


Physical Security:

This involves ensuring only authorized users have access to physical infrastructure that hosts the Kubernetes cluster. This is a separate topic by itself.


Cluster/Node Security:

User management/security of nodes that hosts the cluster. From Kubernetes standpoint, this would essentially mean users with the ability to login to node (master node) and run Kubectl, kubeadm, etcdctl utilities.

Application Security:


Applications (PoDs or deployments) may implement their own security mechanisms for authenticating users. Single Sign On/OWAuth have become popular and do not have anything to do with Kubernetes.


Service Accounts:

Service account enables a PoD to authenticate with API server with an authentication token. A "default" service account is created when cluster is installed and unless overridden this account is used during the creation of objects like PoDs.




root@sathish-vm2:/home/sathish# kubectl get serviceaccount -o yaml
apiVersion: v1
items:
- apiVersion: v1
  kind: ServiceAccount
  metadata:
    creationTimestamp: "2020-10-15T05:06:26Z"
    name: default
    namespace: default
    resourceVersion: "391"
    selfLink: /api/v1/namespaces/default/serviceaccounts/default
    uid: ae3bea7c-1294-4c65-a54d-17b95bc55bc4
  secrets:
  - name: default-token-spkmz
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

root@sathish-vm2:/home/sathish# kubectl get secret default-token-spkmz
NAME                  TYPE                                  DATA   AGE
default-token-spkmz   kubernetes.io/service-account-token   3      73d


root@sathish-vm2:/home/sathish# kubectl run mybusybox --image=busybox --command sleep 1000
pod/mybusybox created

#default-token-spkmz is  mounted in the created PoD. This is used to authenticate with API  server
root@sathish-vm2:/home/sathish# kubectl describe pods mybusybox
Name:         mybusybox
Namespace:    default
Priority:     0
Node:         sathish-vm1/172.28.147.44
Start Time:   Sun, 27 Dec 2020 07:11:46 +0000
Labels:       run=mybusybox
Annotations:  <none>
Status:       Running
IP:           10.244.1.5
IPs:
  IP:  10.244.1.5
Containers:
  mybusybox:
    Container ID:  docker://3a5a93115f83d83bb8351120878d72fcce13b2fde7e0ec6bef3a6dfb29f56362
    Image:         busybox
    Image ID:      docker-pullable://busybox@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678
    Port:          <none>
    Host Port:     <none>
    Command:
      sleep
      1000
    State:          Running
      Started:      Sun, 27 Dec 2020 07:11:53 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-spkmz (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-spkmz:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-spkmz
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From                  Message
  ----    ------     ----   ----                  -------
  Normal  Scheduled  9m5s                         Successfully assigned default/mybusybox to sathish-vm1
  Normal  Pulling    9m4s   kubelet, sathish-vm1  Pulling image "busybox"
  Normal  Pulled     8m58s  kubelet, sathish-vm1  Successfully pulled image "busybox" in 5.59136436s
  Normal  Created    8m58s  kubelet, sathish-vm1  Created container mybusybox
  Normal  Started    8m58s  kubelet, sathish-vm1  Started container mybusybox

Let's create a new service account and try using it to create a PoD


#Create a new service account
root@sathish-vm2:/home/sathish# kubectl create sa sathish
serviceaccount/sathish created

#Create a new clusterrole
root@sathish-vm2:/home/sathish# kubectl create clusterrole pod-admin --verb=get,list,watch,create,delete --resource=podsclusterrole.rbac.authorization.k8s.io/pod-admin created

#Create a  rolebinding
root@sathish-vm2:/home/sathish# kubectl create clusterrolebinding pod-admin-binding --clusterrole=pod-admin --serviceaccount=sathish
error: serviceaccount must be <namespace>:<name>
root@sathish-vm2:/home/sathish# kubectl create clusterrolebinding pod-admin-binding --clusterrole=pod-admin --serviceaccount=default:sathish
clusterrolebinding.rbac.authorization.k8s.io/pod-admin-binding created

#Create and view PoD with service account

root@sathish-vm2:/home/sathish# kubectl run customsabusybox --image=busybox --command sleep 1000 --serviceaccount=sathish
pod/customsabusybox created

#This PoD uses the sathish SA
root@sathish-vm2:/home/sathish# kubectl describe pod customsabusybox
Name:         customsabusybox
Namespace:    default
Priority:     0
Node:         sathish-vm1/172.28.147.44
Start Time:   Sun, 27 Dec 2020 07:36:04 +0000
Labels:       run=customsabusybox
Annotations:  <none>
Status:       Running
IP:           10.244.1.6
IPs:
  IP:  10.244.1.6
Containers:
  customsabusybox:
    Container ID:  docker://a7cc5b57cc82d97c7c26da6354ef1178f1b1f2fe7ffe16f7c68cc64ba51c10a9
    Image:         busybox
    Image ID:      docker-pullable://busybox@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678
    Port:          <none>
    Host Port:     <none>
    Command:
      sleep
      1000
    State:          Running
      Started:      Sun, 27 Dec 2020 07:36:10 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from sathish-token-2jsvm (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  sathish-token-2jsvm:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  sathish-token-2jsvm
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From                  Message
  ----    ------     ----  ----                  -------
  Normal  Scheduled  68s                         Successfully assigned default/customsabusybox to sathish-vm1
  Normal  Pulling    68s   kubelet, sathish-vm1  Pulling image "busybox"
  Normal  Pulled     63s   kubelet, sathish-vm1  Successfully pulled image "busybox" in 5.015162728s
  Normal  Created    62s   kubelet, sathish-vm1  Created container customsabusybox
  Normal  Started    62s   kubelet, sathish-vm1  Started container customsabusybox

As we can see this PoD uses the custom service account


Kubernetes role and rolebindings


Kubernetes implements role-based access control to manage users. A role determines level of access a particular user has. For example, it is possible to create roles to only view PoDs. RoleBindings "bind" user(s) to a role. Further, roles and RoleBindings are categorized as:


  • Namespace wide

  • Cluster Wide

Let's look at the steps involved in creating roles and rolebinding in default namespace



Note: ClusterRoles and ClusterRoleBindings can be created by following similar steps. Use ClusterRole and ClusterRolebinding keywords when creating roles and role bindings for cluster.
  1. Create a Linux user .

root@sathish-vm2:/home/sathish# useradd podadmin
root@sathish-vm2:/home/sathish# passwd podadmin
#Grant SUDO permission to user.
root@sathish-vm2:/home/sathish# usermod -aG sudo podadmin

2. Generate csr and private keys. Change to podadmin user before running the below commands.



# Create Private Key 
$ openssl genrsa -out podadmin.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................+++++
...........................................+++++
e is 65537 (0x010001)

# Create CSR and sign with the  key
$ openssl req -new -key podadmin.key -out podadmin.csr -subj "/CN=podadmin

# Generate selfsigned cert with CSR
sudo openssl x509 -req -in podadmin.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out podadmin.crt -days 365


3. Create a certificate signing request. CSR needs certificate request to be base64 encoded

Getting base64 encoded format of certificate
$ cat podadmin.csr | base64 | tr -d "\n"
<copy the complete content>

# Create a CSR
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: podadmin
spec:
  groups:
  - system:authenticated
  request: LS0<pasted base64value>
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth

4. At this point change back to the user that has full cluster access and create/approve csr



root@sathish-vm2:/home/k8admin# whoami
root
root@sathish-vm2:/home/sathish# kubectl apply -f /home/podadmin/csr.yaml
certificatesigningrequest.certificates.k8s.io/defaultpodadmin created

root@sathish-vm2:/home/sathish# kubectl get  csr
NAME              AGE   SIGNERNAME                            REQUESTOR          CONDITION
podadmin   58s   kubernetes.io/kube-apiserver-client   kubernetes-admin   Pending
# Appprove the CSR
root@sathish-vm2:/home/sathish# kubectl certificate  approve podadmin
certificatesigningrequest.certificates.k8s.io/podadmin approved
root@sathish-vm2:/home/sathish# kubectl get csr
NAME              AGE   SIGNERNAME                            REQUESTOR          CONDITION
podadmin   72s   kubernetes.io/kube-apiserver-client   kubernetes-admin   Approved,Issued


Now, podadmin can authenticate/talk to kube-api server. However, the user does not have the required Kubernetes permissions. This can be verified with kubectl auth


root@sathish-vm2:/home/k8admin# kubectl auth can-i create pods --as=podadmin
no

5. Grant permission to podadmin to create PoDs by creating roles and rolebindings. We have the option of creating namespace wide or cluster-wide roles. For this example, we will choose namespace wide rolebinding.


root@sathish-vm2:/home/k8admin# kubectl create role podadmin --verb=create,delete,get,list --resource=pod
role.rbac.authorization.k8s.io/podadmin created

root@sathish-vm2:/home/k8admin# kubectl describe role podadmin
Name:         podadmin
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [create delete get list]

root@sathish-vm2:/home/sathish# kubectl create rolebinding podadmin --role=podadmin --user=podadmin
rolebinding.rbac.authorization.k8s.io/podadmin created
root@sathish-vm2:/home/sathish# kubectl describe rolebinding podadminbinding
Name:         podadmin
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  podadmin
Subjects:
  Kind  Name             Namespace
  ----  ----             ---------
  User  podadmin

6. Verify the role. podadmin can create pods in default namespace but not in other namespaces like kube-system



root@sathish-vm2:/home/defaultpodadmin# kubectl auth can-i create pods --as=podadmin
yes
root@sathish-vm2:/home/defaultpodadmin# kubectl auth can-i create pods --as=podadmin -n kube-system
no

#Checkdefaultpodadmin should not be able to create other  objects

root@sathish-vm2:/home/defaultpodadmin# kubectl auth can-i create pv --as=podadmin
Warning: resource 'persistentvolumes' is not namespace scoped
no
root@sathish-vm2:/home/defaultpodadmin# kubectl auth can-i create deployments --as=podadmin
no
root@sathish-vm2:/home/defaultpodadmin# kubectl auth can-i create replicasets --as=podadmin
no

Now, create the Kubeconfig file for the user- we can copy the existing kubeconfig file and make necessary changes. Before following the steps below, change to podadmin user



$ sudo cp /root/.kube/config /home/podadmin/.kube
[sudo] password for podadmin:
$ sudo chown -R podadmin /home/podadmin
# Add Credentials

$ kubectl config set-credentials podadmin --client-key=/home/podadmin/podadmin.key --client-certificate=/home/podadmin/podadmin.crt --embed-certs=true
User "podadmin" set.

# Add context

$ kubectl config set-context podadmin --cluster=kubernetes --user=podadmin
Context "podadmin" created.

# Change context to pod admin

$ kubectl config use-context podadmin
Switched to context "podadmin"

# Check Permissions

$ kubectl get  pods
NAME                           READY   STATUS    RESTARTS   AGE
mywebserver-6d6c47b597-jqtfc   1/1     Running   0          9d

$ kubectl get deployments
Error from server (Forbidden): deployments.apps is forbidden: User "podadmin" cannot list resource "deployments" in API group "apps" in the namespace "default"

$ kubectl run nginx1 --image=nginx
pod/nginx1 created

The above user can administer pods but cannot create/delete other objects like deployments. This is RBAC in Kubernetes.


That's it for today folks !! Hope, this short intro to user administration in Kubernetes was useful. Until next time, have a great week ahead, and Happy New Year!

372 views0 comments

Comments


bottom of page