Getting started with Kubernetes service accounts

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone and welcome to a new video on this channel this time about kubernetes service accounts now before we get our hands dirty let's take a step back and look at secure access to the api server what are the pieces of that now first of all of course you have to authenticate to the api server and for a regular human like hopefully also yourself that will be through a user or a group but if applications need to authenticate to the api server we typically use a service account for that now after you authenticate to the api server you also have to have the proper authorization to do what you want to do for example suppose that our service account needs to list spots in a namespace then we need the proper roles and role bindings we'll see more about that later that give us that access right and another way to secure access to the api server is by using admission control these are things like web hooks which are called when you do a call to the api server and the webhook then decides looking at your call if what you want to do is allowed or not this video is not looking at the admission control part in detail now how can we authenticate to kubernetes how do we do that well this is done via plugins and there are several different ways that authentication can happen probably the most common way is using client certificates the certificate is typically in your cube config somewhere and that's how you authenticate to the cluster in most enterprise environments you will more often than not link with an external identity management system that's done through open id connect for example in an aks environment so azure kubernetes service it is very easy to integrate that with azure ad for instance so that makes it easy to use users and groups defined in that azure active directory now for this video we'll focus on the second option and it is using an authentication token typically a java or javascript web token or jaw.jwt right and that is mostly used for service account authentication it's important to realize that kubernetes has no api to define users and groups these users and groups have to be defined externally for instance when you're using certificates the users and groups are defined directly inside the certificate if you're using something like azure ad and you connect it via open id connect then the users and groups are defined within azure ad now this is different for a service account kubernetes does have an api to define service accounts and they are created in a namespace so they are namespaced objects now what is the service account used for it's used to allow a process and a pot to access the kubernetes api server now if you've never defined a service account or you never thought about this you should realize that there is something like a default service account if you check inside a namespace and you list service accounts you'll find that there is a default service account but that default service account has no access to the api server it hasn't been granted specific access rights so if you are creating an application and you know that a process in a port needs to connect to the kubernetes api server you should create your own service account never give access rights to the default one of course when you create such a service account you will then need to give it the proper access rights i will do that with roles and role bindings i will see more about that in a moment the service account can then be used to obtain an authentication token naca certificate to connect and authenticate to the kubernetes api server now you're probably thinking how does that work well automatically your service account gets a kubernetes secret as well and the secret contains this information but that will become more clear when we start working with it on the cluster as a side note if you deploy kubernetes in azure and you're using azure kubernetes service or aks you might want a process in a pot to access the azure apis as well now there's a different mechanism for this which is the azure ad pot identity which is totally separate from this service account that has kubernetes api access but those two can actually coexist so you can create a service account and use that inside the bot to connect or talk to the kubernetes api and at the same time use aad bot identity to talk to the azure apis and do whatever you need to do there right now let's get started creating and working with these service accounts okay let's get our hands dirty and we'll start with just running an alpine pot we didn't specify a service account for this spot so the default service account should be used so i'm running that alpinepod and getting a shell to the alpine pot now we can go to the following folder that's var and then run secrets kubernetes dot service account because this is where the secret that's associated with the service account is mounted and that secret contains yeah three pieces of data in this case what we want to work with what we need is the ca.crt and the token if i cut out ca.crt this is a standard certificate and we can use this to validate the tls connection to the kubernetes api endpoint yeah for example if you're using curl and you don't have to use the dash dash insecure option to create your or make your connection let's clear this out and do ls again we also have the token and this is actually this jwt or jawed uh that we get and this one contains everything that is needed to properly authenticate to the cluster as the as this default service account now what we can do here is we can take this token so i'm going to just copy this and i have on my machine here i have the jolt or the jwt cli installed i can run that and then paste the token after that and what you'll see is that indeed this token contains the following header that you'll see here but the payload is indeed it's a kubernetes service account in the namespace default the secret that's associated with the service account is indeed default token and then this value here and the service account is indeed default so it's clear that the token contains information to identify the service account that is being used here let's create a service account and i'm going to use the cube cuddle command here which is alias to k we can just use create service account and then the name of the service account if you want to know what the ammo has to be that you have to submit to the api server you can just use drive run with the option to output to yaml and this would be the manifest to create the service account i'm going to use cube cuddle anyway so i'm not using the yaml and create the service account with kget sa i can see the listing of service accounts and we see that fsa is now created next to the default one that you always get in a namespace we also know that we get a secret noun secret contains three pieces of data you can see this is linked to the app service account or app sa service account let's check out the secret here and look inside the actual yaml look at the data pieces so the data inside the secret is ca.crt we have a namespace and we have the jwt token now if i'm selecting this token you should know that this is base64 encoded as secrets are in kubernetes so we can just echo this and pipe it to base 64 dash d and that decodes the value and here it starts with e w here or e y actually not w i'm just gonna copy this and i'm going to pass this to the jwt application i installed on my machine um you can just do npm install so you need npm for this and then the jwt cli package you have to install and you install it globally with the g and i just want to see what's inside this uh token and here it is the token the payload let's focus on that contains the information that this has to do that this is linked to our service account with the name app assay it has a uid as well and it has all kinds of other identifying information that kubernetes will need later to decide what are the roles assigned to this service account so to know what the service account can do at the api level so now that we know that we have our service account and we have our our secret is there we need to create a pot or we need to have a pot where we specify that we want this service account to be used yeah how do we do that so how do we say don't use a default service account but use the app sa service account but in my case i have a deployment i will just cut this out with the cut and then deployment sa yaml and what you'll see here that in the spec of the pot for this deployment you'll see that there's a service account name section and there we specify that we want to use the app sa service account now this deployment just deploys one container replicas one of the image by this user using alpine curl because i want to use curl to basically do a request to the api server now we have to first get these spots or this spot running so we're going to use k apply minus f and then deployment sa yamo this has now been done let's clear this out do k get deploy and there is a deployment let's do k get port and there we see we have our alpine deployment pod running yeah it's ready and it's in the running state i've now started k9s and i'm on this the pot from that alpine deployment and i can use d to describe it so let's just do that let's do d and let's check out a little bit lower here what the mounts are and as you can see the secret which is sa token as we have seen before with this value also appended has been mounted on the file system in the varan secrets and so on the service account folder so that means that our application can now access the certificate but also the token to do authenticated calls to the kubernetes api server let's just try and do that i'm now in a shell of that pot that we just deployed which has the secret mounted for our new service account so we can now grab a reference to our ca.crt file just by saving that into an environment variable and the first thing we can try is we can do a curl to the kubernetes api endpoint so we can do this as follows and with the dash dash ca cert we can tell girl hey you know what you can verify the full tls uh connection uh you can trust the certificate that is presented to you by the kubernetes api endpoint right we're going to use a get to the https colon slash kubernetes and kubernetes is just a service defined inside your cluster basically and that gives you access from inside pods to the api server now if we do this we'll get the following error user anonymous cannot get that bad because indeed i did not identify who i am i have to specify this token for this to work so let's grab the token as well which is also mounted as we have seen earlier via the file system to get that token i'm going to use the following command and let me just grab that and copy and paste it into this shell here and it's important here that you don't just get a reference to the file now you have to cut out the contents of that file and store that in the variable in this case the variable token if you forget that cat and just use the same approach as with the cia the ca dot crt file that won't work now let's go to my back to my copy and pasting again here and i can indeed use the following command now to specify the same thing as before but we're passing also a http header which is the authorization header and we specify the better token to authenticate as the service account app essay let's do that and now in this case we get this response which is expected by the way what happens if you don't specify the the ca cert just to give you that as well if you remove the ca cert here girl will actually say well this this is not this is not secure i cannot verify the certificate i get from the kubernetes api endpoint now you can specify dash dash insecure to just tell girl you know what don't worry about it right that would also work great that means we now have used our service account we've used the secret that is mounted inside the pod for this service account to do a successful authentication to the kubernetes api server although we can successfully authenticate to the api server we cannot really do that much because we haven't been granted the correct access rights to do anything suppose i want this service account to be able to list bots inside the default namespace well then according to the rbac system inside kubernetes i have to create a role and a role binding first the role with a role you give that role a name and then you specify the verbs that you are allowed to use and the resources you're allowed to use those verbs with so in this case i want to do a listing of a type of resource which is pots okay now to know what kind of yaml i need to submit for that we can again use the driver and client and the output to yaml and this would be the yaml i have to submit to the cluster now i'm not going to do that so i'm going to create the role directly and i'm going to create it like this that's the role but of course the role itself is not enough i need to bind this role to the service account that i created earlier you will use a role binding for that now we'll use the same approach as with the role what we'll do is we are going to use k create roll binding and i think i did it yeah yeah i made a small mistake here so i'm going to use dryer and minus o yaml that's a pasting mistake but i'm going to leave it in in the video happens to all of us so k create role binding this is the name of the role binding i'd like to bind the service account which has to be named namespace colon service account name i want to bind the service account to the role pod lister now to know what kind of yaml i need to use for that i use this and indeed i should use dry run is client because that is deprecated so this is the correct command and this would be the the yaml i need to submit to my cluster if i want to create this role binding via a manifest i'm not gonna do that now so i'm gonna just create the role binding uh from the command line and this is the role binding that is now created yeah so if i'm not doing k get role you'll find that there's a role in the namespace called potlister and if i do k get roll binding i have a role binding called app sa-pod list this should be enough to go inside the pod and to basically do a curl to the api that gives me a list of the pods in my namespace let's just do that and to do so i'm going to show you all the way how it's done i will use k9s which is easier in day to day work so i'm going to go here to my alpine pot i'm going to grab a shell in the alpine pot and i want to just as before i want to get the certificate authority and the token in environment variables so just as before i'm saving the ca here i'm also saving the token for my service account and now i'm going to do a curl command to give me a listing of pots let's do that and we'll do it with this command over here same as before so curl we specify the ca cert we do a get by the way there is no list verb of course we use list in the role but we use get in the actual curl command and in this case i want to list the pots in the default namespace so i have to use uh behind api slash v1 slash namespaces slash name of the namespace and then slash pods and of course i'm going to authenticate and present my token to the api endpoint and i'm using head here as well i will actually specify the number of lines i want to see like 20 lines i want to see because it's quite a long list that you'll that you'll get here let's see if this works and indeed we see that curl has done the request and i'm getting an array of items back from the api server and this is basically the first bot that i'm getting back metadata name this is my alpine bot if there are more pots of course they will all be listed you have just seen how to do this request with authentication to the kubernetes api server using curl most of the time though you will write some software in some kind of language that does what you need to do for example if you write coding go or you write code in python you'll probably want to use these techniques from within that application now you don't have to do this all by hand here because the kubernetes client in this case the one for python it has the following load in cluster config option here and that basically uses this uh the same approach to get the token from the secret mount and so on to properly authenticate to the kubernetes api endpoint so we use this load in cluster config then we get the the client which is using the core v1 api and then here you see that it does a list pot for all namespaces basically so you would need a different a different different role binding here at cluster level to do this across all the name spaces yeah so keep that into account we've seen it with curl that explains how it works under the hood but of course there are some abstractions in the languages that you use like in this case with the kubernetes client in python and it's similar for go and other kubernetes clients and with this we have come to the end of this video about kubernetes service accounts thanks for watching and see you next time
Info
Channel: Geert Baeke
Views: 7,503
Rating: undefined out of 5
Keywords:
Id: keoYFZhtg0U
Channel Id: undefined
Length: 21min 54sec (1314 seconds)
Published: Tue Feb 02 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.