Understanding Kubernetes RBAC | Access control basics explained

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] if you're new to kubernetes you've probably heard the words are back so what is rbac rbac stands for role based access control in systems we have users that need to access the system roles allow us to categorize these users based on their needs let's say we have developers marketing users and administrators we could define a role called readers that allow certain users to read from the system and we could bind that role to all users we could define a role called writers that allow certain users to write to the system and bind that to developers we could also define a role called administrators that allow certain users to delete from the system and bind that to administrators in kubernetes we have roles we can bind these roles to users or groups using role bindings rbac as a concept is very simple you have users or groups and then you have roles that define the permissions of users or groups and then you bind those roles to the users or groups using a role binding so roles and role bindings live at a namespace level this means you could have a development team who have access to the shopping namespace where all the shopping microservices live for an online shopping system or you have a marketing namespace where all the marketing systems live and marketing users have access to that namespace roles and role bindings will give those users access to that namespace because roles and role bindings live at a namespace level to provide cluster level permissions meaning to all namespaces you will have to use a cluster role and a cluster role binding it's the same as a role in a role binding but it is at a cluster level and this may provide permissions across all namespaces so use it with care in this video we're going to break down our back by taking a look at the roles and role bindings and how to give user access to kubernetes we're going to take a look at what authentication looks like in traditional kubernetes and provide access to users as well as services so without further ado let's go [Music] so taking a look at a practical example i have a github repo with a kubernetes folder and in the kubernetes folder i have an rbac folder with a readme and this is our introduction to kubernetes for rbac we'll be creating a kubernetes cluster and we'll take a look at everything regarding rbac creating a new cube config file for a user called bob giving bob access to kubernetes using a role and a role binding and then we'll take a look at the authentication mechanisms around how bob will authenticate with traditional kubernetes we'll also be deploying a pod and use a service account to give access to services so be sure to check out the link down below to the source code so you can follow along [Music] now in this example we're gonna need a kubernetes cluster and i'm gonna use a utility called kind to create a test cluster you can also use minicube or any other kind of kubernetes implementation so kind is a really useful product for allowing you to run lightweight kubernetes clusters inside of docker containers and it's useful for testing purposes and has most of the kubernetes features to create a cluster it's very simple i just say kind create cluster and i'm going to call this cluster r back and i'm going to run kubernetes 1.20 so copy paste that to the terminal and that'll give me a kubernetes cluster that i can use for testing and once that cluster is up it only takes a few seconds i can do cubect i'll get nodes and we can see i have a onenote kubernetes cluster running in a docker container and to understand rbac we'll be taking a look at a cube config file now when we created this cluster using kind it's manipulated my local cube config file and it's added the cluster called rbac to that file so whether you're using minicube or a cluster in the cloud feel free to explore your cubeconfig file to take a look what it looks like it's a critical component to understand user access now kubernetes does not have the concept of users a user or a group in kubernetes is just their arbitrary string so it could be the name of the user it could be a user id or group id in traditional kubernetes to identify a user or a group kubernetes uses a certificate and it only trusts a certificate which was signed by the kubernetes ca when you provision a kubernetes cluster you provide a ca certificate so this means i cannot log into kubernetes and add a user called bob i have to create a client certificate and set bob as the common name in the certificate and then i have to sign that certificate with the kubernetes ca and the kubernetes ca key then i have to create a role to allow bob some permission set and bind that role to the certificate using the same common name so when bob tries to access kubernetes kubernetes will say do i trust the certificate does the user's intent match any of the roles where the role bindings user is bob now in a managed kubernetes offering in the cloud this process is slightly automated and a little different but more on that later to understand this a little bit more let's dive into kubernetes now as i mentioned kubernetes does not have the concept of users so we can't add a user called bob instead what we're going to do is we need to grab the kubernetes ca certificate from the master node the kubernetes ca is used to sign user certificates so that we can trust them and give them access the ca is basically the brains of trust in the kubernetes system now when you create a managed kubernetes like eks aks or gke you do not generally need the ca certificates because managed kubernetes uses an oauth mechanism to authenticate which is slightly different in an unmanaged kubernetes you may need the ca certificate or you may provide that certificate when you bootstrap your cluster now generally the certificate lives inside etc kubernetes pki folder by default you can find this in the kind cluster on one of the master nodes as well as in minicube you may find it under the userfolder.minicube so to get this file what we can do is we can say docker exec minus it and the name of the container because our cluster runs as a docker container and then pass in bash so we can copy this to the terminal and now we're inside our master node and if i run ls minus l and i look inside of this directory we can see we have the ca certificate and key so we're going to need the certificate and ca to sign and provide user access so let's do that let's go out of our container let's change directory to the kubernetes are back folder and let's copy those certificates out by doing docker cp the name of the container and we're going to copy the ca certificate out from the etc kubernetes pki folder and we're just going to copy it locally call it ca.set so copy paste that to the terminal and you can see on the left here we have the ca cert and then i'm going to do the same thing but this time for the ca key i'm going to copy paste that and we have the ca key so now that we have the ca we can use that to sign user certificates and to use that certificate we will embed it in a cube config file to pass it to the user the user will then use that cube config file and runs cube ctl command to access our cluster now kubernetes also supports openid connect and oauth which means unmanaged kubernetes like eks aks or gke or any cloud provider you would generally use your microsoft or your google or your amazon account in order to log in and kubernetes will instead of passing a certificate will pass in a group id and an oauth token so kubernetes will know what groups that user belongs and we can use that group id to set up roles and role bindings in traditional kubernetes we just use certificates instead of oauth and we can sign a user certificate and give it an expiry that means the user will only have access to the kubernetes cluster for x amount of time in the oauth world the token also has an expiry which means the user when they run a cube ctl command kubernetes will validate that token if it's expired or if the certificate expires it will deny access or it will ask you to log in again so to understand the traditional authentication of kubernetes let's create a user certificate called bob and then we give bob access to our cluster so to do this we're going to create a user certificate and the easiest way to do this is running a small alpine container so i'm going to say docker run minus it for interactive terminal i'm going to mount my local directory which is this rbac folder into the container on a path called slash work i'm going to set that as my working directory and then i'm also going to pass in my home directory which is where my cube config lives because i need to be able to access the cluster as admin in order to add bob and then i pass in net host because it's running as a docker container i want this cluster to be able to access my kind cluster and i'm just going to run a small lightweight alpine container this means i don't have to install openssl on my machine if you have openssl you can skip this step so i'm going to copy this command paste in the terminal and now i'm inside an alpine container and i'm going to install openssl really quickly by saying apk add openssl and this is an ssl tool that will allow us to generate certificates so let's create a certificate for user called bob smith so i start by saying open ssl gen rsa and i'm going to create a key called bob and i'm just going to put a strength of 2048 so i'm saying bob.key i'm going to run that and that'll generate a file on the left which is the private key for bob and now that we have a key the general process of signing certificates is to create a certificate signing request or csr and the important part is we want to create a certificate with the common name of the user name or the user id or the group id which that user belongs to so in our case i'm going to say openssl req to create a new request and i'm going to pass in my key bob.key and i want a csr file out as output and the subject is going to be look at the cn equals bob smith and he's part of the shopping group so i'm going to copy paste this to the terminal and this will give me a csr certificate signing request which i can now use to sign the certificate using the ca search so now i will use the ca certificate we got earlier to sign and create a certificate so i say open ssl and i'm going to create an x 509 certificate i pass in the bob.csr which is the certificate signing request i say dash ca and ca key where i pass in the ca certificate and key and i want an output file bob.crt and i want the certificate to last one day so it's very important to always have a certificate expiry that means if someone runs off with a cube config and they leave your company they will lose their access after a few days it's the same concept as password expiry managed kubernetes clusters deal with this by using a oauth token which also expires so i'm going to copy this command paste it to the terminal and we see we now have a certificate for bob so bob.cert so now that we have a certificate where the common name is bob we can start creating a new cube config file which is what users use to access kubernetes and we can embed bob certificates inside of that file now cubectl uses a cubeconfig to access kubernetes clusters it's very important to understand what the cubeconfig file looks like and it's also important to keep a cube config safe as it will embed certificates for certificate authentication and if you're using a managed cloud provider there will be oauth tokens that may still be valid so what we need to do now is embed that certificate that we created into a cube config file so that we can give it to bob so that he can access our cluster a cube config has a list of clusters each cluster has a ca and an http address of the kubernetes api server a cube config also has a list of users each user has a certificate or an oauth token which identifies the user a cube config also has contacts which binds the cluster to a user this means we can have a dev context to connect to a dev cluster or a prod context to connect to a prod cluster so to understand that further open up one of your cube config files and you'll see a list of clusters each of these clusters lists the certificate authority as well as the server of the api so this would be the location of the kubernetes api for a user to use this cluster there would need to be a user entry so down here under users we have a user and we can see we have a certificate data which is the certificate of the user as well as the key and this is the default admin account when you deploy a kind cluster the same thing would happen for a mini cube or a cloud provider for a managed cloud provider that uses open id or oauth instead of having certificate data they would have oauth tokens and refresh tokens so the user entry is used to identify the user so this is the area where we will create a user and we'll put the bob certificate inside of this entry and in order to use a user to access a cluster we need to create what's called a context and under the context section you can see i have a context here which binds the cluster you can see the cluster here is called kind rbac with a user and the user is called kind rbac and you can see this cubeconfig currently points to the kind rbac cluster so i have multiple clusters in this config multiple users multiple contexts but we're currently pointing to the kind cluster for rbac which is the class that i've just created now by default cubectl looks for this file called config inside of the user's directory you can also override the location by setting an environment variable called cube config and setting it to a different file so what we're going to do is create a new cube config file that's empty and then we're going to proceed to add a cluster because we know where our kubernetes cluster is so we know the api endpoints as well as we have the certificate authority so we're going to create a cluster entry and then proceed to add our user certificate so to do this what i'm gonna do is inside of that alpine container that i have i'm gonna install nano which is a lightweight text editor and then i'm also gonna download cubectl give it execution right and move it to user local bin because i don't have cubectl running inside of this container now i have cube ctl and if i say cube ctrl get nodes we can see we can list the nodes this is because cubectl uses my localcubeconfig which has cluster admin permissions so let's go ahead and create a brand new cubeconfig file so to do this i'm going to tell cubectl to look at a new file i'm going to say export cubeconfig and i'm going to create a new cubeconfig file in the cube location under my users directory and i'm going to call this one new config and i'm going to set that environment variable and when i say cube ctl get nodes we can see that there's no cluster defined so it's not going to be able to connect to a cluster we can use our nano text editor and look at that new file that we just created and we can see that it's empty it does not have any content so the first thing we're going to need to do is create a cluster entry so what we have to do is go to our cube config file where we have our existing cluster get the master address so we want to get this https address which points to our kubernetes master and we want to go ahead and set a cluster so the way we do this is we say cubectl config because we want to interact with the cubeconfig we call the setcluster command and we're going to call this one dev cluster and set the server address to the one we copied from our cube config and then we're also going to set the certificate authority which is the ca certificate and we're going to embed the certificate so that it's inside the cube config file making the cube config file portable so i'm going to take this command paste it to the terminal we can see that it's going to give us a warning saying config not found but that's fine because it will go ahead and create the file and then it sets out dev cluster so now we have a cluster entry if i use nano again to edit and look at that config file we can see it's created a blank cube config with a single cluster entry it has the certificate authority it has the location of the master the api server and the name called devcluster we can also see that the context is blank because we haven't added one yet and we don't have any users so now we've learnt about the cluster entry in the cube config next up we need to create the user entry which is the user certificate that we signed earlier so to create the user entry we're going to say cubectl config because we're interacting with the config we're going to say set credentials and we're going to call this one bob this is going to be the user entry in the cubeconfig file then we're going to specify the client certificate which is going to be the bob certificate we signed and created earlier the private key and we're going to embed the certificates to the cubeconfig file to make it portable so if we move the cubeconfig file around we don't need to move the certificates along with it so i'm going to copy this paste it to the terminal and that will create a user called bob in the cubeconfig file to review that change i can run nano on the cube config file again this time we can still see the cluster entry we don't have any context yet but we have a user we can see we have a user called bob as well as the client data and the key it's also important to notice that this name of this user called bob is not the user that is in the cluster the user that's in the cluster is part of the certificate common name which is in the user certificate that we created earlier and that we can see in the previous command that we ran when we created the certificate signing request where we say the cn the common name of the certificate is going to be bob smith so this is the user string that kubernetes will see so now we have a cluster in our cubeconfig file as well as a user entry the next entry is the context which binds the user and the cluster together remember we can have a dev context and a prod context because we can have multiple clusters and multiple users in the same cube config file so to create a context i'm going to say cube ctl config set context i'm going to call this dev and my cluster that i'm going to use is dev cluster that we created earlier and my name space is going to be shopping that's my default namespace that i want to give bob access to and i'm going to say user is bob that is the user we created earlier as part of the set credentials so if i copy paste this to the terminal we can now see we have a dev context set to understand what that looks like i can open up the config file using nano again and we can see we have our cluster entry we have our user defined here and now we have a context where we say the context is called dev and it uses the dev cluster and the bob user and its default namespace is shopping that means any cube ctl command that bob runs will access the shopping name space by default bob can still access other namespaces if we give him the role and role binding for that namespace and also notice that the current context is blank so we're not pointing cube ctl to any context yet so that means if i say cube ctl get nodes we can see that it's not connecting to any cluster correctly because there's no context set cube ctl doesn't know which cluster to point to so to point to a cluster we say cubectl config use context and we set it to dev this means a development team can access devcluster by setting the dev context if they want production access they can set the current context to prod and access the production cluster this means you can use the same cubeconfig file for multiple cluster access but this also introduces risks because developer can accidentally run a command in production so the way to avoid that is by having separate cubeconfig files so the developer has to explicitly define that they want to access a specific config file before running a cubectl command so if i say cubectl config use context dev that will go ahead and set my context to dev and if i say cube ctl get pods notice that we get an error because we don't have any permissions yet to access anything in kubernetes kubernetes trusts us but it forbids us to run any commands because we get an error saying forbidden pods is forbidden user bob smith cannot currently list pods in the api group blank in the namespace shopping so the error clearly tells us what's wrong and notice that the user is bob smith this is the value that matches the common name in the certificate this name does not exist in the cubeconfig file it's embedded within the cert now we've given bob smith access to the cluster but he doesn't have any permission to interact with kubernetes now to allow bob smith to access objects and to run cube ctl commands we need to define our back objects in kubernetes so we need to define a role which tells exactly what it is that bob can do and then we have to bind that role to the certificate bob using a kubernetes role binding and then we'll deploy that role and role binding to the shopping namespace so bob smith will be restricted to the shopping namespace only now currently inside of this container we're using bob's cube config file and we need cluster admin access to give bob access to our cluster so to do that i'm going to create a new terminal i'm going to change directory to the kubernetes rbac folder and i need to define a role to define what it is that bob can do if we take a look in the kubernetes rbac folder we have a role.yaml and in here this is what a kubernetes role looks like you give it a name as well as a namespace so in this one i'm going to say manage pods to allow bob to manage pods and deployments so generally roles can have a list of rules and a rule has an api group a resource and a verb if you've been watching my kubernetes series you would have noticed that there's a lot of kubernetes objects such as deployment pods config maps secrets services ingresses all of these objects have an api version or an api group so you would have had extensions for deployments or apps for deployments which is the api group and then you have the actual resource which is the deployment or the pod or the config map or the secret or the ingress or the stateful set so generally for pods the api group is blank and the resource is pods for deployments the api group is apps and the resource is deployments if you take a look at my deployments folder under kubernetes i have a deployment.yaml and here i have api version on the yaml you can see the setu apps v1 so apps is the api group and kind is deployment which is the resource and then the next part is the verb this is the command that you want bob to be able to run if you'd normally say cubectl getpods or cubectl getpod or you say cubectl createpod or cubectl deletepod those are verbs so you can see here i allow bob to get pods watch pods list pods create and delete pods for deployments i allow get watch list delete and create as well now if you take a look at the area we got when bob ran the command it clearly tells you what you need to add and build so you can build the roles based on the errors or you can use that to troubleshoot your existing roles so we can see we got forbidden pods we knew he was interacting with a pod resource we know the user is bob smith so we know what role binding to set up and we know that he's trying to list so the list verb is what he's trying to do so he's trying to list pods in the api group blank in the namespace shopping so when we build our role we know exactly api group needs to be blank we know the resource is pods and we know he's trying to list so adding the list verb here will make it work so this is how you define a role in kubernetes [Music] so what i'm gonna do as a cluster admin i'm gonna go ahead and i'm gonna create a namespace called shopping so bob can start deploying his applications and then i'm gonna create that role by saying cubectl in the shopping namespace apply and i'm going to apply role.yaml i go ahead and do that and that'll create the role but this will not give bob access yet in order to give him access we need to bind his user to that role so to do that we're going to create a role binding so in my kubernetes rbac folder i have a rolebinding.yaml and if we take a look at this this is what a role binding looks like a role binding binds a subject to a role reference so our subject kind as user the name is bob smith which matches the common name in the certificate and we want to reference a role and we are going to bind it to the role called manage pods so this is what a role binding looks like now in managed kubernetes it works very similarly so in amazon you might have a user id instead of bob smith which might represent an amazon user or you might use a group if you're using something like aks and you're using microsoft azure active directory you might have a group id so instead of kind user you would have kind group with a group id instead now to finally give bob access i'm going to apply the role binding by saying cubectl in the shopping namespace apply minus f and i'm going to apply the rollbinding.yaml when i run that that will set up the permission and bob will be able to run the command i can go back to bob's terminal and i can rerun the getpods command and we can see it now succeeds there are no pods in the namespace i can also do get deploy because there's deployments as well and we can see there are no pods in the namespace so bob has now capability to manage deployments now so far we've covered rbac for users but what about applications now most businesses will not be writing applications that talk to kubernetes api so it's not needed for your general micro services but you may be building ci cd tools or monitoring tools or auto scanners or maybe even kubernetes custom web books or you might be using an open source product that needs access to the kubernetes api for that we'll need to create service accounts service accounts are similar to users but they don't use a cube config file they use what's called a service account token and then we can create our back roles like roles and role bindings cluster roles or cluster role bindings to give service accounts access so kubernetes has a document which talks about configuring service account for pods service account gives pods identity so similar to how we had our user certificate we can create a service account which an app can use and that will set a token for a pod that the pod can use for authentication so let's go back to our cluster admin window that we can create a service account that bob can use to manage his applications so service account looks pretty simple in the kubernetes rbac folder we have a service account.yaml and all that a service account has is a name so i'm going to create a service account called shopping api because bob wants to be programming and building a shopping microservice so to deploy the service account i'm going to say cubectl in the shopping namespace applytheserviceaccount.yaml this will go ahead and deploy that service account to the shopping namespace now we can go ahead and deploy a microservice that uses that service account so in the kubernetes aurabac folder i have a pod.yaml and this pod is just going to be running nginx as a test but we can see that we have a service account reference so we're referring to the shopping api service account so since bob can manage pods let's go over to bob's section and create that pod so bob can create his pod micro service by saying cube ctl apply in the shopping namespace and apply pod.yaml and if i do that we can see pod has been created i can do cube ctl in the shopping namespace and i can get pods so we can see bob has access to pods now that shopping api that bob has deployed will have access to the kubernetes api because we've defined a service account which will deploy a token that that pod can use now by default the shopping api will not have much access so we need to define a role and a role binding to allow it to access so let's go inside of the shopping api pod and test its access now to give bob the capability to go inside of the pod if we take a look at our roll.yaml we've provided some extra permissions we've provided resources pod slash exec so this allows bob to run the exec command on pod so that he can go inside and get an ssh terminal so in bob's terminal we can go ahead and clear that and we can run cubectl in the shopping namespace exec minus it to get an interactive terminal the name of the pod and we can pass in bash this will give us a bash terminal to that part and look what happens when we run that we're now inside of that pod now by defining a service account in kubernetes and binding it to a pod just like we did we'll create a token and it will create it under the var run secrets kubernetes dot io service account folder if we do alice minus l in that location in the pod we can see there's a ca search and there's a token with a default namespace so applications can use this to authenticate with the cluster now since we don't have a real application here i'm just going to use curl so what i'm going to do is i'm going to create an environment variable that points to the location of the kubernetes api which is running locally in this cluster i'm going to set an environment variable that points to the service account the token we specified i'm going to set a namespace environment variable just pointing to that exact location that has the default namespace i'm going to read the token so i'm going to set an environment variable for the token and i'm going to also set an environment variable that holds the ca certificate and then i'm going to list the pods through the api by using curls so i say curl pass in the ca pass in an authorization you can see here i'm passing in that token for the service account and i'm going to call the kubernetes api and i'm going to call the pods api to list all the pods and if we run this we can see we get failure forbidden and we get the similar failure that we did when bob tried to initially list pods so we say pods is forbidden the user which is a system service account called shopping api cannot list pods in api in group blank in the namespace shopping so similarly our cluster admin needs to provide access roles and role bindings to the service account so to do that i'm going to go back to our cluster admin area and i'm going to apply two files one is a service account role and the other one is a roll binding and they look very similar to the roll and roll binding we had before the only difference is i'm going to restrict the access a little bit more i'm only going to give it access to pods to list pods and the role binding also looks the same all i'm going to do is this time my subject is not going to be a user it's going to be a service account and the name of the service account the shopping api and then the role reference is going to be a role which is called shopping api so that'll bind my role to my service account so to deploy that very simple cubect i'll apply minus n in the shopping namespace i'm going to apply the service account role and then i'm going to bind that role to the service account by deploying the role binding and now if i hop back into our pod and i re-run that curl command notice we get a lot more json back which is the full json from the api which lists the pod in the shopping api namespace now cluster roles and cluster role bindings look exactly like roles and role bindings the only difference is you don't have a namespace in the role and cluster role and cluster role bindings exist across all namespaces so if we use that for bob we'll be giving bob access to list pods in all namespaces so be careful when deciding when to use a cluster role versus a role so hopefully this allows you to understand the basics of kubernetes access control and our back objects if you liked the video be sure to like and subscribe and hit the bell and be sure to check out the link down below to my kubernetes beginner's guide as well as the source code so you can follow along and if you want to support the channel even further be sure to check out the link down below to the patreon and the community page or you can even hit the join button below and become a youtube member and as always thanks for watching and until next time peace [Music] you
Info
Channel: That DevOps Guy
Views: 1,417
Rating: 5 out of 5
Keywords: devops, k8s, kubernetes, rbac, access, control, security, tutorial, sysadmin, containers, development
Id: jvhKOAyD8S8
Channel Id: undefined
Length: 33min 29sec (2009 seconds)
Published: Mon Sep 20 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.