Running a .NET Core application in Kubernetes - high level walk-through

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey folks as lately i've been even less regular with the videos because i've been studying a bit about kubernetes i thought i might as well take advantage of that and make a quick video about running a.net core application in kubernetes not a tutorial or anything like that just a basic like intro so if anyone doesn't really know what kubernetes is and he's interested in a quick quick look just to understand why everyone always talks about this this is it i will just grab a simple application and put it running with kubernetes using just some of the features because there are a lot and briefly explain some things but without going into much detail it's just like a quick overview of some of the interesting things and why everyone always is talking about kubernetes right now so it will be kind of like live coding but not really and i'll make a lot of use of the kubernetes documents to copy paste stuff and then adapt to what we need and as a sample application we'll use a hang fire sample i did on the twitch stream some time ago it's something really simple we have an api which is basically just an end point that we send a job and it queues the job and then we have worker which just handles the job which is basically just logging and waiting for 30 seconds just to simulate that it's doing a lot of work uh and that's about it this is the the sample application and it's enough for us to see some how to deploy this to kubernetes and see things working i already prepared some docker containers as we need some containers to run kubernetes one for the api and another for the worker mostly the same they are already created so if i go to the terminal and do docker images image ls grip and fire you see already a fire sample api and a fire sample worker so we basically will have these two containers plus a container for sql server and we'll see how all of that interacts and eventually you will see the application in the browser so as my head over here in the bottom is not really important as i'm not streaming let me just change this to [Music] hide it and let's get started so let's start we'll create a yaml i already created the yaml i'll call it all.yaml so we can create our resources for kubernetes in a bunch of ways i prove normally we prefer to use the yaml so we have all the things and put in source control and stuff like that and we can put them in multiple yaml files or we can put them in the same ml file separated by three dashes that's what i'm going to do to just to keep it simple so let's start with the sql server container so let me go to the docs and let's create a pod so a pod it's is the basic thing that we run in kubernetes so a pod can run one or more containers and so let's go over here and this is an example of a pod and okay not a lot let me see a lot of docs alternatively to just create the yaml we can in the terminal we can create a pod i don't the exam was like two weeks ago so i forgot most things uh just so you are not surprised when i do k it's the same as i if i did cube ctl because i created an alias so k run and we want the sql server pod sql server container so i say yeah so okay run sequel server image equals this one let's say i want run equals client and output yammer okay so the dry run means that i don't want to apply this immediately and the dash o is output so i want to output as yaml so now i have a basic yaml here i can copy and put over here so let me move some stuff not needed and i want this this so this is the basic thing now for sql server container if we go to the docker hub sql server this is not really kubernetes it's more docker and stuff but if we want to run this we need to provide some parameters like password and stuff like that so i'll just copy what i have already prepared over here okay so this is being annoying i don't know why code is annoying like this but let's ignore that so this is a pause where we can put multiple containers in this case we want one container so sql server and this is the image and as environment variables we're going to pass this to accept the euler we're passing the password so basic password and of course we shouldn't have this in plain text in a file but this is our demo and i'm saying that i want to use sql server in developer edition now another thing we do here is we mention the parts that this container will use and that should be it for the sql server pod let's see if things are working go to the terminal and if we want to apply that file we can do okay apply file all okay apply file oh so we see that the container is running we can't do anything with it but it's running so we can now get rid of this by doing a delete now this is cool but for other containers to be able to access or better yet other pods or containers inside other pots to be able to access sql server they will either need to know its ip directly which is not great or we can create a service which will its name will act as a dns internally to kubernetes so when we are in the other containers we can just reference sql server given the name of the service so let's go back to deluxe and search for service if we go over here to the service blah blah blah blah blah blah and we have an example so if we copy this here go back over here to service the name of the service i'll say sql server svc and the selector is the way for us to tell the service you will forward things to the pods which have this selector if we see here the label for this body is run sql server so we'll grab this and put over here now we have let's put the same port that we put over here so it matches or better yet this part is what the clients will use and we'll put the clients as this is the default sql server the clients will connect to 1433 and it will just forward to 1433 if we wanted we could put 14 34 and put target port target part 14 33 but it's not useful to be inventing like this so now back to the way here apply hit all and now we see we have the pod sql server which is running and we have the service sql server svc and the other pods will be able to reference it let's delete this again so everything starts at the same time which is not needed but now that sql server is kind of done it's not done we'll be back for some changes but let's go to the start looking at the api so now for the api instead of using pods directly as you see i use the pod directly for the for sql server but we can use some things in this case we'll use a deployment to be something that's above the pods and controls what's going on so let me go back over here no not here over here and we'll see what is a deployment and also i didn't mention but this is not a way to create a database in production of course because everything would when the container goes down everything goes down so in production that's not the way to use databases and many times we don't really put databases in in kubernetes maybe we'll use something like a managed database that the cloud provider provides but it's also possible to have the databases in in kubernetes but not the way i did so this is a deployment an example so it's in this case an nginx deployment and so it has containers nginx and it says it has three light replicas which means it will have three engine x's running at the same time let's copy this and go back here and let's adapt i'll use run instead of app or better i use we use app because i think most of the examples use this app and over here okay and now we're looking at the deployment let's start with one replica match labels api this will be our api api and the name will be again api no it doesn't need to have the same name i just did and the image will be ang fire sample the slash 1.0 i think let me check let me check yeah or better yet comparison api not two that's correct so this will be the same for the worker this will change okay and container part 80. so this is mostly should work api deployment api deployment so this should work emphasis on should so let's go back to the terminal and let's try to apply and you can see there is an api deployment over there uh let's do one thing and let's see the logs of the api deployment maybe it's all good okay didn't complain don't know how he didn't complain but let's see that so let's delete this again and now like we did for uh sql server we need a service to expose this so we can access it so it's again a service in this case we'll call it api service it will match api it will go to port 80 right now and in this case we'll do is use type load balancer let's see if the docs mentioned it don't mention it because this is the deployment no this one yeah so let's go back to service service load balancer okay so we the services can have multiple types like cluster ip so exposes a service in an ip which is internal to the to the cluster node part so it will expose the the service on the same part on the nodes or load balancer which in this case will use what i'm using for docker desktop and expose it for s2c outside with a load balancer but if it was in a cloud environment it would use something from the cloud provider for instance azure or aws which will would give it would map it to a load balancer that the provider has available so in this case we don't need that because i'm doing things in desktop but that's it and then it's an external name so i think this is to map for instance to some external for instance if we wanted to go to google but not be tied to google.com we could create something like inner google which would map to google.com or something like that but in this case load balancer so now let's go back to the terminal and apply let's get all it's all running apparently so let's go to the browser and do local host dashboard okay get logs let's see the api forget k logs and now we have exception because we created sql server we created the ink file api the api using a fire but we didn't provide the connection string so it has no idea of things how to get things working i thought it would blow up immediately when it started but apparently only on the first request so we need to provide the connection string if we go to the code currently the connection string is over here in app settings over here but this connection string is for when i was running this outside of the container now we need to and outside kubernetes so i need to actually provide a connection stream correct which is not local host so we have some options and what we'll use let's go back here secrets so secrets are way to provide secrets in this case we want to provide a connection string and we can use cube ctl create secret blah blah create generic stuff and secrets is one of those things that probably we don't want in yaml because it we don't want that in source control but in this case we'll do it just because it's demo and i prefer to have everything like in source control so anyone can clone the repo and start things as a demo if it was production of course we don't want this so let's copy this go back to the code i'll put this closer to sql server so can be here secret here let's call it sequel server secret we'll probably use more than one i'll change this data to string data so we don't need to do this encoding stuff and let's start with a connection string we'll need we'll use more things later but right now connection string and i'll just copy this from another place i have this already done and that's it so we'll call the databasing fire sample sql server service if i'm not mistaken sql server service yeah and user id sa and password the same password i put up there now we have a secret and now we need to map it to the api let's go back to the docs where is that okay over here and if we want to use the docs yeah yeah great secrets great secrets i know i want the using secrets we can mount the secret as a volume or we can mount them as environment variables environment variables so that's what we want over here so let's get back to over to the api deployment to the container and we want this so the name will be connection string and we want to go to sql server secrets connection string so these two didn't need to match they just met because i wanted but we could call this whatever as long as it matched what is up there in the in the sql server secrets and now this will be mapped as an environment variable and as you might be aware asp.net core automatically puts any environment variable so overrides what comes from the app settings so now if you run this it will not work but the reason will be different so let's clear okay apply so okay get oh we see it's everything's running so we can go back and grab the spot deployment stuff you you see the other part as a simple name because we created the other pod by itself but in this case because it's using a deployment and we can have multiple parts from a deployment it has this weird stuff generated we'll see more about that later so let's okay logs this let's put dash f to follow okay okay so now the error is different because the database now the it was able to connect to sql server but not to hang fire database because the database doesn't exist and then fire doesn't create it automatically so we'll need to create a database for it to use and this is an interesting mission for something in kubernetes called init containers so heat containers are containers that run before the normal containers in the pot which can prepare stuff so what we'll do is create an init container that creates the database or ensures the database is created before that we could do that inside our enfire application but and i don't think there's anything wrong with that but with all that separation of concerns and all of that it's interesting to do this do it this way so the application is the application assumes everything is prepared for it and also probably in real production we don't want an application creating the databases automatically probably devops or something like that will create the database before so this kind of simulates this but in in a demo environment so because i don't know all this is weirder not the init container stuff but there is this thing i think there's a them some tools there's a container with tools for sql server which is called ms sql tools if we try to find it no okay and this has command line tools to access the sql server database so we'll create a container an init container based on this to check to ensure the database is created so let's go back to over here and create some init containers so you need containers we'll call name create database image will be the one then what we'll use we'll use a comment so it will basically tell this container run this command and i'll copy paste this because it's a bunch of stuff let's see so this is just to execute a shell script that comes next and then we go to sql tools sql server service with user sa password that we'll need so it's an environment variable and then i'm connecting to master check if the young fire database exists if it doesn't exist create the database so by using the neet container the other containers these ones will only start when they need containers are finished now we need this password how can we do it let's go back over here and besides the connection string let's just say password and we'll copy this over here and now we can map it the same way we did for this one so copy this i'm missing the end and it should be no it's correct instead of this we call password and password and okay i think it should work now back to the terminal okay get all okay logs okay logs for this one seems to be up seems to have no errors so let's go back here and we have hang fire working so servers there are no active servers because we didn't create the workers but hang fire itself is working now this is really not needed here but since we can do this in the context of the demo let's do one thing that is there is one thing called let's go back here liveness probes yeah so we can configure this in our pods so that the service knows when other containers are ready or not uh not only the service one of the interested parties it's the service so it can forward or not new containers in there that requests to that container so let's see we can have liveness probe in multiple types so get http get yeah that's what we want so we'll put liveness pro i'll copy all of this and go back over here and let's add elf port 80 no need for this and we'll say initial delay seconds let's say one it will wait one second before trying and then every five seconds we'll see if it's already up let's put one second just to be faster and we can create something that's basically the same but these uh readiness probe i think every thing configured is basically the same so the difference is right in this probe is to check if the the container is ready to receive traffic while the liveness probe is after it is ready is it still able to do that so if i didn't put this in the wrong place let me just check yep let's try again get all so it's if you see it takes a bit it's in it because they need container is running and creating stuff and now things are working let's do one thing okay not the logs this time okay describe this part so if we see over here initialized it mentions the the probes it seems to all be working now let's do another thing let's go back to over here and then let's point to 81 let's apply again battery let's delete so we see things but as you see what was happening is because we did changes on the container what kubernetes does is start a new one try to start a new pod and when it's done delete the other one so it's a rolling update not going to touch that subject but so let's apply and now okay get all so it's the need container now it seems to be taking longer so let's do okay play describe so it's failing the readiness probe so now we see there's a crash loop back off because and it's restarting because it's not able to reach it and even though it's working if the readiness and liveness probes are reporting that it's not good then kubernetes tries to restart the pod to try to have things working as they should so if we go back to over here back to 80 and apply again okay at all it's creating a new part wrong it's creating new path initializing running so the old one is terminating and now we have things working and we can go back to over here and this is working and we can go to local host local host health and it's healthy so all good now the last thing that's missing is the worker because right now if we send some requests let me open up the app insomnia so let me put it back here which is huge let's create what happened i think it's liking this scaling so new request it is a post i think let's just check the code startup so a post to queue and some id which is irrelevant but let's pretend it's not opposed to http local host job id x okay okay okay so now if we go over here there are a few jobs but because we haven't started any worker they're just there so we need to start the workers so let's go back to the ammo yemo and we'll basically copy this just so it's quicker [Music] copy copy this to here this will be again a deployment in this case a worker deployment worker or curve worker we can let the same init container as it has the same dependencies over it will be worker we don't need to expose any parts we could but we don't need because the worker i think i didn't implement any api in there or even if i did let me check just in case now in fact there is the the dashboard is there and there's a hello world so we could use the liveness probe but no need so worker worker worker stuff no worker and use the connection string again stuff like that so let's go back over here we don't need to start to delete the other things we can just okay get all and now we have the worker deployment and it's running immediately only the init probably was faster because the database is created as we don't want to access the worker we can we don't need to create a service the worker is just there running in the background so let's go back to the browser and it's processing so immediately the worker started connected to the database and started working on things and they are succeeded all good no jobs there now as you noticed at the beginning i showed that the handle job is basically just waiting 30 seconds so that means that if we enqueue a lot of jobs it will start to the queue will start to grow so let's see that in action i'll go back to insomnia and i think there's a option here that i discovered today repeat on interval and i want like every half a second so now it's doing requests and we go over here it's in queueing prior dashboard should be things happening or not no not really okay stuff in there whatever but if we go over here to the jobs we see there are 20 processing which i think is the default and fire processes 20 jobs in parallel per node and the jobs keep keep getting enqueued so the queue will start growing if you go to the servers we have a sample worker and the jobs are growing because insomnia keeps keeps going you can wait a bit and this will grow and stuff like that but then there's where it's where we can go over here let's go back over here and there's this replicas so let's put two in here and let's go back to the terminal and apply so if we do get all now you see there are two pods for the worker and we just changed one to two and kubernetes apply the configuration one is older three minutes the others three seconds now if we go to the dashboard now there are 40 jobs working in parallel and there are two servers same name but different grids i say yeah look at the jobs so now it's able to keep up with insomnia creating the jobs is there a way to make this faster repeat on interval zero dot 25 no okay so this should start growing i think or not okay now it's growing so for the processing the queue growing a bit not a lot maybe not fast enough now it tries because there are no errors servers jobs stuff like that so if we want to adapt things we could either over here change the replicas or the terminal we can case scale deployment worker deployment replicas one so if we do get all now one pod is terminating and if we go back to end fire we have one server the other went down this job was aborted apparently it was because the pod went down it will be retried eventually so but this is zenfire stuff not really kubernetes but interesting to see and if we see that this is we need more we can three replicas and now eventually we'll have three servers and processing 60 at the same time and the queue and all of that and i guess this is enough for this brief intro that's probably long but hope it's useful for someone who has no idea what is this kubernetes how this relates to the applications we we develop every day so i hope this is like some little enlightened enlightenment and if you're continuing to be interested you'll look for more resources that you can learn a lot more but this is just like uh to poke your brain and say okay this exists and this is why it matters even if not everyone should worry about this but if you're a back-end developer it's maybe interesting not needed but interesting to know what's going on and okay that's all hope you enjoyed it and hope to see you in the next one see yes
Info
Channel: Coding Militia
Views: 1,043
Rating: 5 out of 5
Keywords: dotnet, aspnet, dotnetcore, aspnetcore, coding, programming, c#, csharp, kubernetes, k8s, hangfire, containers, docker
Id: moMK6iPAIRA
Channel Id: undefined
Length: 47min 54sec (2874 seconds)
Published: Mon Sep 14 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.