In this post we will look at how to configure RBAC (https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for a Kubernetes cluster hosted on Google Cloud Platform. This post assumes that you have at least Editor rights to your GCP project in order to configure IAM, Cloud Storage and Kubernetes Engine. You will also need to have admin access to your Kubernetes Cluster.
RBAC is the second step i.e. Authorization to your Kubernetes cluster. It will allow you to control who can do what in your cluster. However, it doesn’t allow you to define users. Kubernetes does not have users, it allows flexibility to define users and authenticate them against an external system. It does have service accounts which shouldn’t be considered as users. Users are humans who are allowed to interact with Kubernetes systems. Service Accounts can be considered machines or software which is allowed to query and use the Kubernetes API. An example of this could be an automation setup for QA which deploys and tests applications in a QA cluster.
RBAC vs Authentication
As I said earlier, RBAC allows you to control who does what i.e. it’s Authorization. Authentication on the other hand controls access to the cluster. An example of this scenario would be you have a user who is an Internal Auditor who needs to access Kubernetes cluster to check which applications are running and keep an audit of licenses. This user will need only connect privileges to the cluster and will not need any permissions to deploy applications. This in GCP can be done via Authentication itself.
IAM in Google Cloud Platform
IAM is a user management service which controls users access to different Google Cloud services e.g. Cloud SQL, Kubernetes, Google Cloud Run etc. Its a user management module available in GCP and it makes life very easy with its predefined roles. The console looks like the screenshot below.
As you can see there are Members and Roles. GCP has some really good default roles and policies created. To add users through IAM just click the Add button on top. If you AD is connected to your GCP project then you will be able to add them via email addresses. When you add the users you can add them with different Roles. Let’s say for example you want a user to be able to create Deployments and Services in Kubernetes you can assign a Kubernetes Engine Developer Role. To know more about the roles and what they mean you can look at the GCP documentation here – https://cloud.google.com/kubernetes-engine/docs/how-to/iam#predefined
This now means users can connect to your Kubernetes cluster. A user with access to the cluster can run a simple gcloud command to configure they kubernetes config file with the cluster details. Assuming the gcloud init command is run and authentication is completed with the GCP account the user can simply run
gcloud container clusters get-credentials <clustername> --region <region>
If the project is not configured when gcloud was initialized a –projectid argument can also be provided. Note that these roles allow users to perform actions at a Kubernetes level. They are not fine grained. For example if you want to only allow access to certain namespaces or read access to some namespaces and write to others this cannot be done by IAM.
Enter RBAC
RBAC allows fine grained controls to administrators over and above what IAM allows. I highly recommend reading the RBAC documentation from Kubernetes here https://kubernetes.io/docs/reference/access-authn-authz/rbac/. I’ll explain quickly what objects would be needed for RBAC.
Role
A Role object defines what’s allowed and not allowed. Typically you will not need to create new roles unless you have some really complex use cases. A Role is defined per namespace.
ClusterRole
ClusterRole is a role which is not restricted to a namespace. It also defines permissions just like a role. Kubernetes defines quite a few cluster roles. You can view the roles defined with the command –
kubectl get clusterroles.rbac.authorization.k8s.io
To get details on a particular role you can use
~ -> kubectl get clusterrole admin -o YAML
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2020-04-09T17:35:34Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: admin
resourceVersion: "259"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/admin
uid: 72852415-66a6-4144-8bb7-c2d40626c266
rules:
- apiGroups:
- ""
resources:
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
- secrets
- services/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- impersonate
- apiGroups:
- ""
resources:
- pods
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- replicationcontrollers
- replicationcontrollers/scale
- secrets
- serviceaccounts
- services
- services/proxy
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- replicasets
- replicasets/scale
- statefulsets
- statefulsets/scale
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- extensions
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- ingresses
- networkpolicies
- replicasets
- replicasets/scale
- replicationcontrollers/scale
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- networkpolicies
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- persistentvolumeclaims/status
- pods
- replicationcontrollers
- replicationcontrollers/scale
- serviceaccounts
- services
- services/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- bindings
- events
- limitranges
- namespaces/status
- pods/log
- pods/status
- replicationcontrollers/status
- resourcequotas
- resourcequotas/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- controllerrevisions
- daemonsets
- daemonsets/status
- deployments
- deployments/scale
- deployments/status
- replicasets
- replicasets/scale
- replicasets/status
- statefulsets
- statefulsets/scale
- statefulsets/status
verbs:
- get
- list
- watch
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
- horizontalpodautoscalers/status
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
- cronjobs/status
- jobs
- jobs/status
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- daemonsets
- daemonsets/status
- deployments
- deployments/scale
- deployments/status
- ingresses
- ingresses/status
- networkpolicies
- replicasets
- replicasets/scale
- replicasets/status
- replicationcontrollers/scale
verbs:
- get
- list
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
- poddisruptionbudgets/status
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- ingresses/status
- networkpolicies
verbs:
- get
- list
- watch
- apiGroups:
- authorization.k8s.io
resources:
- localsubjectaccessreviews
verbs:
- create
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
We will be using the cluster-admin role in our example to grant admin access to specific namespaces.
RoleBinding and ClusterRoleBindings
These are bindings or objects created for assigning the role to a user or service account. This is a great way to separate the permission creation from permission assignements. Role and ClusterRole are permissions and the bindings are a way to assign them. For example to grant admin access to users for a demo namespace you can use the following YAML
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: demos
name: demos-admin-RoleBinding
subjects:
# Google Cloud user account
- kind: User
name: [email protected]
- kind: User
name: [email protected]
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
Note that the binding is done in the roleRef section where we have referenced the pre-created admin role from rbac.authorization.k8s.io. As you can see that the kind is ClusterRole however we are creating a RoleBinding and not a ClusterRoleBinding which will provide access across namespaces.
That’s it. If you know what you want to do then it’s pretty easy ! The only way to understand this well is to try it out.