Kubernetes Crash Course - 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody welcome to the channel and i am very excited to present one of the most comprehensive kubernetes crash courses on youtube we're going to cover a ton of kubernetes concepts i'm going to explain them in great great detail throughout the crash course with a lot of diagrams and we're also going to practically use kubernetes by deploying a application locally on our kubernetes cluster so in terms of prerequisites i do expect you to know a little bit of docker so if you know absolutely no docker i highly suggest pause this video read some docker documentation or watch my docker crash course on youtube i have one on my channel as well so with that being said let's actually go through what we are going to be learning in this crash course so the first thing we're going to do is we're going to introduce kubernetes and we're going to explain what is kubernetes and why would we ever want to use it over here i abbreviated kubernetes with k8s and that's basically just an abbreviation of kubernetes so k is the first name s is the last name eight is all the letters in between and we're gonna see that throughout the crash course so this basically stands for kubernetes the next thing we're gonna do is we're going to explore the kubernetes cluster and the components within it so that is the next thing we're going to explore and then we're going to install kubernetes on our local machine so we're going to figure out how we do that after we do that then we're going to explore cubectl which is the kubernetes cli next thing we're going to explore our very first resource type known as pods and then we're going to start talking about services which is another resource type in kubernetes and then we're going to start talking about networking and how we can have pods communicating with one another in our kubernetes cluster then we're going to talk about another resource type known as deployments and then we're going to talk about a very specific service known as ingress and then we're going to talk about persistent volumes and persistent volume claims and then we're going to talk about storage classes and then we're going to talk about another resource type known as secrets and the last two things we're going to talk about are requests and limits so i'm going to cover everything here in such great great detail and if you want to watch one over the other i have timestamps in the description below so you could watch if you want to learn about ingress and you don't really care for learning about services and pods then you can go ahead and skip to that time stamp however we're building on top of everything that we have learned so really i highly suggest watching the whole video but if you want to basically learn about storage classes or persistent volumes i try to make those sections as comprehensive as possible and not really dependent on other things so you could very well do that now that is what we will be covering in this kubernetes crash course and i like to well teach you guys by doing something so we're going to deploy a very simple application on our local machine not on a cloud provider so we're just going to deploy on our own kubernetes cluster and if you don't know what kubernetes cluster is completely fine but this application is very very simple we have a client which is going to be built with react and typescript and this is going to be a server right over here and then we're going to also deploy a mongodb database and this is going to be inside of our kubernetes cluster and when i deploy it to our kubernetes cluster because the environment is going to be very similar the same configuration is going to apply for aws or any cloud provider so you do not have to worry about that all right so this is the application that we are going to ultimately be deploying with kubernetes and is ultimately going to look something like this so it's just a very simple application we can basically check you know the habits have we done them today or we haven't done them today literally these side navs they do nothing i just put them there just for a design and then essentially now what we can basically do is we can add a habit in if we want to so let's add another habit let's say i don't know make youtube youtube video so this is another habit and we can add it in there and we can also check this off now if i refresh this well it is going to persist because we are saving it to our mongodb database now i have created the images for the client as well as the server so you don't have to worry about no coding you don't have to worry you can be a complete noob coder you don't have to have any coding knowledge i already created all of the images and i published them publicly on docker hub so the two images that we are going to be using is lathe hard slash server and lathe hard slash web app this is going to be well the react typescript application and then this is going to be well the server this one you can neglect i'm going to delete this a little bit later but these are the two images and then we're also going to use of course the mongodb image that is hosted on docker hub now if you ever get stuck or you want a point of respirance please go to my github page at heartblade 7 k8 app at the moment it is private but i will make it public once i publish this video and over here we can see basically the client code if you do want to take a look at it as well as the server code but really what you're going to be working with is the infrastructure directory over here so click on infrastructure then click on k8s and then you're going to see all of the manifest files that are going to exist inside of this crash course so all of the manifest files so you can basically look at these manifest files for reference if you want to now i also branched everything out so you know you can basically go back to previous versions so if you want to go back to maybe the first time where we created our first manifest file you can go over here so you're not overwhelmed by at all you know the final product so you can basically kind of step by step by going to different branches so i hope that kind of gets you excited with kubernetes this crash course really took me a long long time to make and i hope it becomes really valuable valuable for you guys to learn k8's kubernetes i'll see you in the next section now let's start talking about what kubernetes is and what kind of problems it ends up solving why would we ever want to use kubernetes now kubernetes is a container orchestration tool that manages scaling deployment and recovery of our containerized application now that might not make a lot of sense so i have a few diagrams that will hopefully kind of clear up what kubernetes is ultimately trying to do so let's say here that we have an application and this application is consistent of three running containers and these three containers are inside of some sort of server some sort of virtual machine you can think of this yellow box as maybe an ec2 instance that we can find on amazon cloud services so these containers are running in this virtual machine and everything is fine and dandy these are the containers that are needed to run our application now everything is fine but what if sometime in the future one of the containers goes down so let's say that this container container two it goes down and at this point we only have container one and container three running but we don't have container two and let's say we need all three containers to be running for our application to run properly well in this case if you're not using any sort of orchestration tool you're just deploying maybe docker containers into this instance well at that point what you would have to do is you would have to manually check the container oh see that it has crashed and then restart or spin up a new container you would go ahead and have to do that manually now the problem with that is there's going to be down time from when the container has crashed to when the container has spinned back up there's going to be a significant amount of downtime now you can say okay no problem i only have three containers in this application so i can just consistently check this and just spin up any any container if anything goes and and fails well what if a container failed at like 3 a.m in the morning so if it failed at 3 a.m in the morning and you woke up at 7 00 a.m in the morning and you went ahead and checked your containers and you realized that this has failed well that is a significant a significant amount of downtime and that is something that you do not want to have in your application now this is a relatively simple application this is a very very simple application so most applications look a little something like this they have multiple containers that reside in multiple servers multiple virtual machines and to actually go ahead and manually check every single container check the health of every single container and check if one has crashed and then manually updating it is pretty much impossible with large scale applications now this application itself has 33 containers and it is already big and you can already see how hard it can get now typical applications for large companies have much much more running containers than this across many many more virtual machines and for instance google has billions of containers running and even smaller companies can have thousands if not millions of containers running and to manually do these checks is pretty much impossible so how do we fix this well this is where kubernetes comes in kubernetes to the rescue so what kubernetes does is it automatically checks the health of every single container and if a container fails so let's say container 15 crashes or it fails what it does is it checks the health of this container and it's going to automatically either restart it or replace it or spin up another container so what it does is it ensures ensures that our containers will continuously run and it will automatically restart them if they fail and that right there is essentially what we mean by an orchestration tool it does a bunch of different things now this is just one example let's look at another example of where kubernetes can help us let's go back to this over here we have three three containers in our application and let's say that we have a lot of traffic going into container two and so because we have a lot of traffic we might end up with a bottleneck if we're only running one container so in that case what we would have to do is we would have to realize hey container 2 is getting a lot of traffic and then we would have to essentially configure a multiple multiple instances of container two and then we would have to configure a load balancer that is going to balance the load across these containers now this is well again it's very tricky to do and we probably don't want to do this now well just so happens that kubernetes can do this for us so kubernetes can essentially watch and basically see okay how much traffic are we getting and if we get a lot of traffic into a specific container kubernetes will just automatically spin up multiple instances of that container so at some point kubernetes is gonna be like okay well i'm gonna horizontally scale this application and we could just be in bed and we would have literally no idea that kubernetes did this but it did do it and it can basically configure a load balancer and essentially distribute the load accordingly and this is a lot better than well having to manually do it with our own docker containers so that is another benefit of kubernetes now there's so many more benefits of kubernetes and and i'm not really doing justice of kubernetes with just this one video but there's so many more benefits another benefit of kubernetes is that there's easy rollback so let's say we go ahead and we update our application and we realize that our application has well it's failing there's there's a bug in our application with kubernetes we can easily roll back to a separate version of our previous version of our application another benefit is not restricted to any cloud provider so essentially we can easily very very easily if we have deployed our application in aws we can very easily move our application to google cloud or move our application to microsoft azure because it's not restricted to any cloud provider all we really have to do is just provide the yaml files and we'll talk about that a little bit later to whatever cloud provider that we're using and there we go we have just deployed our application so it's it's really great in that sense and also in terms of development testing and production it is very very similar each environment is very similar to one another if we are using kubernetes another benefit is it automatically configures your infrastructure so you don't have to go in there and manually create load balancers and all the all the kind of complex things kubernetes will automatically just do that for us and and we and it will do that for whatever cloud provider that we use because all the cloud providers have a lot of kubernetes support at at this point at least the big three had that now it will also very much speed up deployment so we can very easily deploy things with kubernetes we can set up continuous integration again because the environment is so similar we can set up a good testing environment staging environment you can do that all with kubernetes very very easily and last thing is well it allows us to build more complicated applications now as our application grows we're going to have multiple containers and the only real way to manage all those containers is with the orchestration tool like kubernetes and kubernetes allows us to do that now with the popularity of micro services micro services are very typically deployed with a kubernetes infrastructure and that's because we have multiple services and we have to manage each one of these services and we typically do that with kubernetes so these are just some of the benefits and there's so so many more benefits of kubernetes and we're actually going to see them throughout this crash course but we i might also miss some because kubernetes does just so so much so i hope that gets you excited and i'll see you guys in the next section now that we have a good understanding of what kubernetes is and what problems is trying to solve let's dive deep into the kubernetes components and to truly understand kubernetes you have to understand what a kubernetes cluster is and a kubernetes cluster is essentially a cluster of all of the components all of the resources needed to run your kubernetes application so let's start looking at each component in great detail so the first component that we are going to talk about that is comprised in the kubernetes cluster is the worker nodes and we can have multiple worker nodes in a kubernetes cluster but we need to have at bare minimum at least one worker node now worker nodes you can basically think of them as computers as machines that essentially are going to be used to run our containers so we have a worker node and it is going to be used to run the container in our application now in kubernetes there is nothing known as a running container on its own containers are always wrapped around with pots and that is basically what you see over here so you never run a container in isolation it is always wrapped around with this thing known as a pot and the pod is the smallest unit in kubernetes now a container and a pod are typically a one to one ratio but it is very possible to have multiple containers that work very similarly and work well together in the same pod so we can have multiple containers in the same pot but in practice is almost always a one to one relationship and in this crash course it will be just a one to one relationship all right so so far we have our nodes and we can have multiple nodes and within these nodes we have containers running inside of these pods now within the nodes themselves there's also a bunch of software and tools that are needed to run our kubernetes cluster for one we would need to have something like docker so if we are running docker containers our worker node our virtual machine we need to have an instance of docker installed in order to run these containers now another thing that it has is the cubelet and the cubelet does a bunch of different things but the main two things that it does is it manages the containers inside of the application so it manages the pods inside of this node worker and another thing that it does is that it communicates with the master node so it's in consistent communication with the master node and we'll talk about the master node in a few seconds so don't worry all too much about it also there's something known as the cube proxy and the cube proxy is essentially it maintains the network rules on the node and it allows for network communication so it allows for network communication outside and inside of the node all right so i hope that kind of clears that up now let's start talking about the next component the master node so the master node contains a bunch of different things so we could have one or many master nodes as well in this example we are we only have one master node and the master node is pretty much responsible for maintaining all of the worker nodes and the pods that are running within them so that is basically the responsibility of the master node now the master node contains the api server and this is basically going to be used to communicate with the cubelet so it's going to be used to communicate with the cubelet and we can also commun we can also communicate to the masternode through the api server so we can have either ui interface to communicate with them or we can communicate with the api server with something known as cube ctl which is the cli for kubernetes and this will allow us to communicate to the master node and then the master node will communicate to the worker nodes accordingly so this is just the main way of communication another thing that we have are schedulers and schedulers are basically used to well schedule in certain pods in certain nodes for instance let's just get rid of this pod over here and let's say that you know we told our master node that we want another pod inside of well one of these worker nodes we want to run another pod now what the scheduler does is it basically looks at all of the resources inside of this worker node all the available resources inside of this worker node and it looks at all of the available resources inside of this worker node and it looks at the resources needed to run this pod and what it does is it basically decides where to place this pod now if this let's say if this doesn't have enough resources then it decides to place this pod right over here in this worker node so basically it is a way to essentially place pods into their correct location and another thing that the scheduler is responsible for is eviction so let's say that this pod is now using so much resources that it has essentially is taking up more resources than is available inside of this worker node then it is responsible for the algorithm for evicting pods so it would go ahead and evict pots all right so that is the schedule over here and then the control manager basically is very important for detecting changes inside of the kubernetes cluster so for instance if this ends up failing so if this ends up failing and crashes the controller would go ahead and see this change and then it would communicate with the scheduler saying hey we need to spin up another instance of this pod and that is basically what it's doing and so it just basically may tries to maintain the state of our kubernetes cluster now all together all of these things so the master node the worker node the pods within it are going to make up the kubernetes cluster so this right here is the kubernetes cluster and how do we create this kubernetes cluster well we create this kubernetes cluster by defining all of the resources and components that are within our kubernetes cluster and here are just some of the components that we are going to be defined now there's a lot of different words for all of these things some people call them resources some people call them components some people call them objects so be careful i might use either one interchangeably i typically just call them resources but we basically define all the resources that are needed inside of our kubernetes cluster in these files known as yaml files and then we essentially give them to whatever cloud provider or whatever local environment that we are running our kubernetes cluster on and it would then create this kubernetes cluster so in some cases we have to create the worker nodes and then it will create all the resources and start using all the worker nodes and the master nodes that we have created or we can basically use other cli tools that create these master and worker nodes for us but essentially all we're really doing is we're defining these things and i only i only show you these things over here where they're going to be defining more throughout the crash course and there are so much more that i won't even cover but these are kind of the main resources that we are going to be defining so we have seen pods already we haven't seen services we haven't seen ingress we haven't seen the other ones but do not worry we will cover each one and i will explain each one in great great detail along with some other ones that you don't see right now so i hope that kind of clears it up and i hope that makes sense and i hope it gets you excited for the next few sections now enough of the theory it's time to actually start using kubernetes now to do that we first have to install kubernetes on our local machine however that kind of provides a little bit of a problem and the reason for this is because kubernetes usually runs across multiple machines so over here we have multiple worker nodes and we can potentially have multiple masternodes and in your local environment this is pretty much impossible to configure so to get around this what we do instead is we run our kubernetes cluster on just one node and within that node we have our master and our workers and this is known as a single node cluster and this is possible to do in our local machine and this will allow us to actually run a kubernetes cluster and start working with it and learning it locally on our machine so that right there is the single uh node cluster now to communicate with our single learn node cluster we're going to use the cube kubernetes cli which is cube ctl and essentially this is going to communicate to the api server inside of the master now this is not just used for local development this is also used for production so this will also communicate with the master node inside of a large kubernetes cluster as well so this is exactly the same so we're not really missing out on by using a single kubernetes node cluster so that is fine now how do we get this single node cluster well to do that we have two options we can either go this route or this route so the first route is docker desktop so essentially we would just install docker desktop and we would enable kubernetes to create this single node cluster or we can use something like mini cube to do that now in this crash course we will be using docker desktop to enable kubernetes and the reason for this is because it's so so so easy to do so that is how what i am going to show you however if you want to go with the mini cube route i will provide some links in the description below and there isn't going to be much changes across these two so you can still follow along accordingly you can really use either or however i highly encourage you if you can to use docker desktop because that is what i will be using in the crash course to install docker desktop just go to docker dot com dash products dash docker desktop and over here you can see that this is the official home page of docker desktop now i am on a mac so i'm just going to go ahead and click on mac with intel chip however if you are on a windows or linux machine just click on one of these and follow the instructions accordingly now i'm just going to continue with mac so i'm going to quickly just click this button and this will take a little bit of time so i'm just gonna pause the video and wait until this is done this is done so i'm just gonna go ahead and click on it and hopefully this doesn't take a lot of time but i'm sure it will so i will again pause the video and just wait until it is over so now that that is done i'm just gonna drag and drop this right over here in to my desktop so let's again i'm gonna pause the video and wait until this is over so once that's done go ahead and open up docker desktop and you should see a gui that looks a little something like this and now we actually have docker inside of our local machine and you can see here that docker is running appropriately now if we want to go to kubernetes then we would just go to the settings over here and then we would just very simply go to kubernetes and then we would just say enable kubernetes and to enable kubernetes we have to apply this and restart it so let's go ahead and do that and this is going to take a little while so again i'm going to pause the video and i'll be back once it's done okay there we go so we should now have our kubernetes single node cluster on our local machine now to double check that everything works we could open up our terminal and then right cube ctl so if i write cube ctl we should see all of this and cube ctl is the way that we are going to communicate with our kubernetes cluster it is the kubernetes cli now the reason why we got this is because this doing this would install cube ctl as a dependency and that's why we got that on our our local machine so if you do cube ctl and you get all of these possible commands that you can do then congratulations you have kubernetes inside of your local machine let's start interacting with our kubernetes cluster through the kubernetes cli cube ctl now a quick reminder as to what cube ctl is cube ctl is the kubernetes cli that will allow us to communicate with the master node and thus ultimately our kubernetes cluster and we can tell the master node a bunch of different things for instance we can tell the master node to create a resource so let's say we want the masternode to create a pod we would tell it that and then the scheduler would just schedule it to one of the worker nodes if we want to delete a specific pod we would just tell the master node that and it would go ahead and delete that pod so on if you want to edit a pod or edit any resource for that matter it doesn't have to be a pod it could be a deployment it could be a service and we'll get into all those a little bit later we would just do that through the cube ctl commands so again cubectl is a way that we can interact with the master node and manipulate our cluster accordingly so let's actually start exploring some of the commands that we could execute with cube ctl now remember if you installed docker desktop or mini cube you should be able to just do cube ctl and see all of the different commands right over here now there is a lot of different commands so what i like to do instead is i like to use this cheat sheet over here because these are pretty much the commands that you're going to be using most of the time and it kind of omits a lot of the extra ones that you'll probably never use like i have no idea what this does to be quite honest so most of the commands that you're going to be using are going to revolve around cubectl get which allows you to see resources cube ctl edit even though you're probably not really going to be using this one and i'll tell you guys why in a little bit cube ctl delete is a very common one cube ctl create you're not going to be using this one all too much and again i'll tell you why in a bit cubectl rollout and cubectldescribe is something that you guys will be using quite frequently and what we would do is we would say cubectl get and then the specific resource that we want to get or the specific resource that we want to edit so in this case there is a resource or object known as a daemon set and here we're trying to get that similarly we can do the same thing with pods so we can do cube ctl get pod cube ctl delete pod and you know similarly with with services as well as secrets as well as as replica sets so as long as you know your resources and you understand what these commands are which are very intuitive cube ctl get cube ctl describe and cube ctl uh delete create and get you should be fine you should know most of the cube ctl commands and i know i said that you guys won't be using create or edit all too much which seems well kind of crazy because how am i going to put resources in to the kubernetes cluster and i'll tell you guys a little bit about that later so don't don't worry all too much all right so let me just quickly clear this and let me just do a cube ctl and i'm going to do get all all right and this is going to get us all of the resources in our kubernetes cluster now beware that i have deployed a kubernetes cluster on my local machine so i'm going to get a different output than you the reason why i did this is because i want to show you how it would look like so i'm going to do get all and you can see here that we get a bunch of different resources so over here i have my pods so i have two pods and i can see that okay they're running they haven't restarted so so i get a bunch of additional information i also have a bunch of services the only thing that might appear on your screen is this over here the default kubernetes service and over here we can see here the type the cluster ip and all things of that nature again don't worry about this all too much we have another resource that i have called deployments and i also have resources called replica sets so that is what happens when i get them all and this is pretty pretty useful and we're going to be doing the get command quite a bit now let's do cube ctl get and let's do get pods so let's just do get pods well to do that you can see here that you only get the pods if you don't want all this extra stuff you can only get the pot similarly if you want to get all the deployments you would just do cube ctl or get deployments of course you would just say get deployments you can see here that well you get all the deployments now let's say you want to learn more information about a particular resource let's say i want to learn more information about this pod well how would we do that well we would use cube ctl describe and then we would describe that particular pod and you can see here that you get a lot of information about the pod so you can see here we have the pod ip we have the image that is associated with the pod we have the image id what else other information do we have here we have you know this over here which is pretty important and we'll talk about that a little bit later uh but yeah you can get a lot of information and you can describe the pod accordingly if you want now if you really want to debug it what you could possibly do is do cube ctl logs and then that pod so this is basically going to output the log as if you would just do it in local development and you can see here that this is just a typical react with typescript applications you can see here typescript and you have the use effect hook is defined but never uh used so you can see we have some warnings over here so this is how we can actually get the internals of our uh kubernetes resources all right so what about well what about these other things what about uh um you know deleting so deleting is something that we often actually do declaratively or we do through the cube ctl command so let's do cube ctl and let's just say get all and let's say i want to delete uh i want to delete this pod right over here or you know what i'm going to delete this pod so i'm going to delete this spot and so i'm going to do cube ctl delete and then so by so if you want to create a delete a particular resource typically what you would say is you would say the resource name so let's say you want to delete a deployment and then paste it but i believe for pods you can basically omit the resource name so and it will just automatically default to resources so over here you can see okay it has deleted this pod so let's do a quick cube ctl get all and you can see that the pod is still running and the reason why it's still running is because um is because kubernetes noticed the control manager notice that it was deleted and then it went ahead and just restarted the pod so let me just do a quick uh let's do it let's do another delete as well so let's try to do this again i was actually expecting the restart number to increase for some reason i don't know why it's not doing that so let's do cube ctl delete pod and we're gonna delete this pod right over here uh let's get rid of the pod okay and let's do a quick cube let's do a quick cube cto get pods all right there we go okay so i caught that so right here you can see that this is terminating and it actually ended up creating another one so it didn't actually restart it it basically deleted this and it ran another one and that's again the power of kubernetes so the control manager noticed that this was failing and it was terminated and the control manager knows that hey i need to have at least one pod running with that is habit depot and you can see here that it has basically spun up a new instance but we'll talk about that a little bit later that's just another thing that you can do now let's say you want to go ahead and you want to create or you want to edit a pod how would you do that well typically you think you would probably think you would just do something like you know cube ctl edit or cube ctl create however we typically don't create or edit resources in this manner let me explain so there are two different ways of creating and editing resources and let me just quickly zoom in here so one way is the imperative way and this is exactly how we've been doing it thus far we would basically outline the set of steps that we want our master node to complete so we would just say hey do this step then this step then this step and then this step so this is something like cube ctl create and then well all the resource information and this is the imperative way of doing it now in kubernetes we typically almost not almost never but but very rarely do we do this way of creating resources we almost always use the declarative way and essentially the declarative way is basically specifying a file saying hey we want our pod to look like this and cubectl here is the file and i want you to just figure it out and create a pod or a resource that looks exactly like this we would do that through cubectl apply dash f whatever file that we want to specify and this is typically how we create resources so a quick example and we're going to be creating these files quite extensively throughout the crash course so if you don't understand any of this do not worry we will cover it but this is a pod that is going to run an ngx image and so what we would do is we would specify all of the things that we want that part to have and we would basically give this file a file name so let's say nginx.yaml and then we would give it to cubectl we would say hey just apply cubectl or or sorry nginx.yaml so cubectl apply.fnginx.yaml and you just figure it out and create that pod and it will just go ahead and magically do that and we are always going to use this way for creating most of our resources and the reason for that is because once we delete everything we don't want to go ahead and just recreate it our way instead we want to create just one file and then whenever we delete it we would just apply our file much easier and another reason why we'd want to do this is because well this is a lot cleaner and it's better documented so it's a lot less error prone we can actually see exactly what we want inside of our pod or our resource so that is another way that we want that's another reason why we want to do this so we are almost never going to see the cube ctl create and cube ctl edit but all the other commands we are probably going to see so uh and and that i hopefully explain to you the reason why we want to do this now there are certain cases where we would want to use the imperative approach for instance what if we want to have some sort of secret so a secret you can think of it as an environment variable and we don't want to have it inside of a yaml file we could do it in a imperative approach rather than a declarative approach but we'll get to probably why we don't even want to do that regardless in a bit once we get to the secret sections so i hope that makes sense i hope you got a good understanding of cubectl now in the next sections we're actually going to start coding out our yaml file so that is pretty exciting time for the moment we have all been waiting for we are going to be creating our resources and putting them into our kubernetes cluster now we are going to start creating our resources with pods now remember pods are the smallest unit in kubernetes and essentially they are going to contain the containers that will ultimately run our application so that is what we are going to be starting with and we're going to start with creating the pod to run our react typescript application now a quick reminder we are going to be deploying an application that looks something like this so we're going to have a client we're gonna have a server and we're gonna have a mongodb in our kubernetes cluster now to run each one of these we have to run them inside of a container unless we have to create a pod for each one of these services okay so beginning with the client that is what we are going to do right now now remember there are two ways that we can create resources we can do it imperatively or we can do it declaratively we are not doing it imperatively for this instead what we're going to do is we're going to create a manifest file that's going to describe how we ultimately want our pod to look like and then we're just going to tell cubectl create a pod that looks something like this so to do that the first thing that we are going to have to do is open up our text editor and then in our text editor that is where we are going to create the file so i am opening up vs code i opened up a directory called k8s tut and essentially now what i'm going to do is i'm going to create a manifest file now the manifest file is going to be a yaml file so hopefully you do know some yaml if you don't that is completely fine i'm sure it's super easy you'll pick up on it as we go through the many ammo files that we have created that we will create throughout this crash course so let's create a manifest file we're going to call this clientpod.yaml all right so let me just quickly zoom in here let's zoom in a little bit less and over here we're going to create basically the specifications of that client pod now if you remember we had that engine x a specification that i kind of showed you and this is going to look very very similar now i'm going to quickly just go through it i'm not going to explain what i'm doing but then after i write it all down i'm going to explain every single line in great great detail so right now you can just follow along but don't worry i'll explain every line in great detail a little bit later so the first thing that we're gonna want to do to create our client pod is specify the api version now this is going to be v1 now one thing i want to tell you is with yaml files the spacing is super super important it actually interprets the ammo file differently depending on the spacing and the tabulation so make sure it is exactly like this with the spacing with with this basic exactly like mine all right so the next thing we're going to do is we're going to specify the kind and the kind here is going to be a pod you can probably imagine what that is and then we're going to specify the metadata and this is just going to be a colon and then we're going to tabulate and then right now because we've tabulated we're inside of the metadata section and in here we're going to specify the name we're going to call this client pod and then we're also going to specify the labels and then over here we're going to tabulate again going inside of the labels and now we're going to say app client all right so now we're going to go all the way back over here going back to the metadata section and we're going to specify the spec which stands for specification then we're going to tabulate and then we're going to specify the containers so this is going to be the containers running inside of our pod now this is going to be an array entry to specify an array entry just tabulate and then you would just do this right over here the dash and then we want to give our container a specific name so we would say name client and then let's tabulate again image and then the image is going to be an image that i have already created so i already created this image for you it's in docker hub and it's completely public so this is the image that we are going to be using lather web app so we're going to do latharb web app and the version that we are going to be using is v1 for now so we're just going to use the v1 version so that right there is pretty much it and we can actually go ahead and apply this file relatively easily now so let's go ahead and let's just save this now what i'm going to do is i'm going to go open up my terminal and the first thing i'm going to do is i'm just going to do a cube ctl get all and now you can see here that it kind of looks a little similar to yours because i actually deleted all the resources if you're curious as to how i did that i just did cube ctl delete all dash dash all and that deletes all of the resources alright so now it looks a little similar to that so now let's actually apply this file right over here to create this pod okay so let's go ahead and do that so to do that what we would do is we would do cube ctl and then apply dash f and then the name of the file so this is going to be client pod pod.yaml so let's go ahead and let's do this and you can see here pod created so now let's just do a cube ctl get all really quick and you can see here that hey we have just created a pod and you can see that it is actually not running yet and the what it's doing right now is just well it's creating the container and this might take a while because it is a react and over here we can see the other specifications now let's go ahead and let's just do this again just to see it and this again will take a little bit of time so let's actually just close this terminal off or maybe uh go like this and now let's actually just start explaining what i have done here all right so so you guys have a good idea of what we're doing and then you know that will buy us some time and hopefully at that point our container will start running all right so what how what am i doing here well i'm going to start off with kind okay and then then i'll move on to api version so kind is basically the kind of resource that we want to create now remember there's so many different resources so if i go back here uh there's so many different resources and this is actually an oversimplification of how many resources we have we have pods we have services we have ingress we have deployments and actually let's do just a quick little search over here actually you know what let's not do that because i i have something pulled up over here and this basically showcases all of the resources that we have so these are all of the different resources that we actually have in kubernetes and there's actually probably some that are missing from here as well so we have a lot of different resources now in this case we are going to be creating a pod so this is why we have specified the kind of pod because we want to create a pod all right so that makes sense now if you want to create a deployment we would just do something like kind deployment if we wanted to create a service then we would just do kind service so this is very simple we're just specifying the resource all right so that makes sense but what does this do what is the api version so i like to think of the api version as a folder that contains certain resources that we can use so for instance let's actually go back over here and let's go here and basically you can see here if we specify the v1 version we only have access to a certain amount of resources so we have access to pods we have access to secrets and we have acts or services and we have access to secrets along with some other ones that i'm missing but we do not have access to deployments because that is in a separate api version and so again you can kind of just think of these as folders that contain separate resources so if we actually needed to create a deployment we wouldn't do the api version of v1 we would do api version of apps slash v1 and then we would change this of course to a deployment all right so that is basically what the api version is and i know i keep throwing around deployments and all these other resources again do not worry we'll talk about them later in great detail all right so that is basically the api version and i just kind of feel that the api version is pretty annoying so what i typically do is i want when i want to create a new resource i either look at an example manifest file for that resource and then that way i can basically see whatever api version it is or you can just go to a website like this that specifies the kind as well as the api version now this website personally i think is a little out of date because deployments are not extension v1 beta1 i mean you can find them there but i typically typically everyone uses apps v1 but you can you know you get what i mean you can go either search manifest files or you can look at certain websites like this or you can basically search the api version of certain resources so that is basically that all right so what is the next step well over here we're describing the metadata and the metadata is basically a kind of a label and name that we can give to our resource so over here we're describing the name so over here the name and we basically arbitrarily just call this client pod and you know what's great about that is because now you can see here when we do a get you can see here that it's a pod and it's called client pod so that is just basically the name this can literally be whatever it is that we want but typically we want this to be something meaningful and then we have labels so over here we have the labels section and we can have multiple labels attached to any sort of resource especially a pod now why do we want to do this well we might end up creating multiple other resources that need to interact with our pod for instance we might create services that need to interact with our pod we might create deployments that need to interact with our pod and the only way that we can interact with our pod is by giving that pod a label and telling that other resource to interact with the pod with this specific label and this label can literally be any key value pair that we specify it could be bananas it could be bananas and monkey like it could be literally whatever it is that we want and we can again assign multiple labels to it and uh labels do not have to be unique they can be consistent throughout multiple pods but again they're just kind of an identifier for other resources to use so we can basically say i'm going to go ahead and just say app client that is kind of the typical convention of naming things but to quickly kind of illustrate this you can see here that here is our pod and we gave it a label of app clients now if we ever create a resource and telling it hey you know interact with the pod with app client with the label of app client then it will know exactly which pod to interact with so that right there is the label so let's go back over here so the last thing we have to talk about is well the specs section and the spec is basically the specification of the pod or and we're going to see this throughout all the resources because we're going to have to define the specification of each resource now in here in the specification we're defining the containers that are going to live inside of our pod and over here we have an array entry so we can actually have multiple containers remember a pod can have multiple running containers so maybe we can have i don't know another container like the server for some reason running in the same pod this is completely valid however pods and containers usually come in a one-to-one ratio so that's why we only see one in this case now again over here we're specifying the containers and then we're just gonna give the container a name this can be anything this doesn't really matter this is for logging purposes and then we're going to give the container an image and this is of course very important this is going to be the image that is going to be at the create the container inside of our pod now this is just going to be the one that i created lathe harp dash web app and then the v1 version so i hope that makes sense i hope that was long enough time for us to just do a cube ctl get all and now cool so now we can see that our application is up and running all right that is absolutely terrific so if you know react typically if you run it in development what you can do now is just go to localhost 3000 so i'm just going to go to localhost 3000 and your application should run however it's not running okay why is that why isn't it running it says running right over here it says that it's ready so why is it well not running well i mean there's a very very very good reason for this and let me just quickly go back to the diagram and let's go back to our cluster our pod is running in our kubernetes cluster that is completely isolated from our local machine so it is running and it is running in our kubernetes cluster but not our local machine so we can't do a local host 3000 to access our kubernetes cluster however what we can do what we can do is we can do something like cube ctl logs and then we can basically log our container just to see what it looks like and you can see that this is a typical react application so you can see here you know react start script logs and everything of that nature so this seems to be working completely fine and it is running it is truly running inside of our kubernetes cluster however we don't have any access to it using our local machine so we need to find a way to access our kubernetes cluster and access that specific pod inside of our kubernetes cluster and how do we do that well we do that with a different resource type known as services so we have created our pod but you can see that we don't have access to it inside of our local environment now in order to get access to it we're going to have to create another kubernetes resource known as a service to just quickly explain what a service is a service is basically a way that we can interact with a pod inside of our kubernetes application so this is just a quick example that we have here we have our browser now browser is going to make a request to our kubernetes cluster so you can think of this as a worker node that contains the pod that we ultimately want to see which is the react application so the browser is going to make a request to the cube proxy the cube proxy is going to forward that request to a service and then the service is going to know exactly what pod it has to forward this request to so then it forwards it to the pod over here and then what it does is it sends back that pod at a specific port and that way we'll be able to access it inside of our local machine now in kubernetes there are four different types of services that we can specify a node port a cluster ip a load balancer and an ingress service we're going to talk about cluster ip and ingress a little bit later but for now we are going to be dealing with node ports node ports are essentially the way that we can actually interact with our pods in our development environment if we wanted to interact with our pods in a production environment we don't use node ports however we use something known as load balancers however for development we will use node ports so let's actually go ahead and create our service so to do this we're going to create a new manifest file and i'm going to call this client srv standing for client service and again this is going to be the service that is going to expose the client pod so the first thing that we have to define is the api version now for the kind of service the api version is v1 which is similar to the one for pods so the kind that we're going to specify is well service and then we're going to specify the metadata and so the metadata is basically just well just a description of that service resource that we are creating so over here we're just going to create a name of well client service and we know we don't have to put any labels in here then we're going to specify the specification so let's go ahead and tabulate and over here we're going to have a bunch of different things so again i'm going to kind of just go through it and then i'll explain it in detail a little bit later so the first thing is we're going to have to define one of the types that we're going to be using are we going to be using a node port a cluster ip a load balancer or ingress what are we using over here we're going to say that we're going to be using a node port so we're going to be using a node port and then we're going to specify selector so this is selector and i'll talk about that later do not worry and this is going to be app client now as you can imagine this is very similar or exactly the same as the label that we've specified here so you can probably imagine what this is doing okay so the next step is to specify the ports and this will be confusing i can pretty much guarantee you that this is going to be an array entry because we can specify multiple boards we're going to say port 3000 target port target port of 3000 and then the last thing is going to be a node port we're going to do this 30 seven so thirty thousand and seven all right so that right there is the file for our service our service resource so what is going on here well the first line makes a lot of sense this is just the api version so just a quick reminder again think of the ap api version as a folder that's going to contain all of the resources that we want so for v1 we have pod service and secrets among others so we would just use v1 over here we're specifying the kind which is service over here we're just specifying the metadata we're calling our service client service so that when we do a cube ctl get all that is the name of it this doesn't matter again we can call it whatever it is that we want but it's fine and if we don't specify this we don't have to specify this it will just going to give us a random name and we probably don't want that now in here we're going to write the specification of the service so the first thing that we're going to be doing the first thing that we're going to be doing is specifying the type remember we have four different types so we're going to be specifying the type of the service so over here we're going to be using node poor and then this is where kind of the magic happens this is where we're going to see how important the labels are so essentially this service is a completely separate resource and what it's going to be doing is interacting with one of our pots because we want to expose that pod into our local environment now how in the world is it going to know which pod it needs to interact with well remember we have given this pod a label of app an app client so the key is app and then the value is client so what we can basically do is say hey you node por service i want you to expose all of the pods with the app client label we can have multiple pods with the app client label but right now we only have one and this is how we can basically connect a service to a pod so that is right there is what the selector is doing so now let's start talking about the ports the ports are pretty confusing but hopefully i can kind of clear them up for you so essentially what we're doing here and we're really just going to be dealing with these two ports this port is basically how we can get pods internal to our cluster interacting with other pods that contain this particular port so let's just not worry about this for now so right here the target port is the port that is exposed inside of the container inside of this pod and in a typical react application by default that is going to be port 3000 now what is this so this is a special port that we only specify of type node port and this is going to be the port that we are going to use to actually see our react application so this is going to be 3007. now for node ports essentially there is a range that we can use you can only use from range 30 000 to arrange 32 767 so we can't go any lower than 30 000 and we can't go any higher than this so this is the node port now we're gonna get a quite a bit of a funky url here but well i'll show you guys how it will look like in a bit so essentially we're going to have something like localhost and i unfortunately can't zoom in so what i'm going to do is just i'll just write it over here so we're going to have a url to actually see our react application we're going to have something like localhost and then colon three zero zero zero seven all right and this is pretty awkward to be quite honest this is this is pretty awkward because well when we want to go to a particular domain we want to we don't want to append this node port we don't want to append this port for instance we just want to go to google.com if we want to go to google we don't want to go to google.com this port and this is one of the main reasons why we don't use node ports in uh in production instead we use typically an ingress service and we'll talk about that later either in ingress or a load balancer all right so that is pretty much it so i hope that kind of makes sense so again what we're going to do is we're we have this port that port 3000 and we're going to be exposing this particular port inside of our local machine all right so i hope that makes sense and now what we are going to do is we are going to apply this cube ctl file this manifest style right over here so we're going to do cube ctl and we're going to do apply dash f and we're going to apply the client srv.yaml and if we give that a quick second you can see here that it has been created the service has been created so if we do cube ctl get all we should see we have a node port created right over here along with our running application so now do we have access to it in our local machine yes we do we absolutely do so but the way that we're going to have access to is going to be different depending on whether you're using mini cube or docker desktop if you're using docker desktop you can just do localhost so you can just do localhost let me just quickly you can just do localhost dash whatever that node port that you specified was so localhost thirty thousand 3007 however if you are using mini cube you're going to have to use the mini cube ip so what you're going to have to do is you're going to have to write the command mini cube ip and this is going to give you an ip now i don't have mini cube installed so i don't have an ip and whatever that ip is just replace localhost with that ip all right so now i'm using docker desktop so i'm just going to cut this i'm going to save this and now what i'm going to do is i'm going to go over here and instead of localhost 3000 i'm just going to paste localhost and that node port i'm going to enter and there we go we have our react application and we have used a service to cr to basically have access to it inside of our local machine so this is a real react application we can add habits if we want to so add yeah maybe go for a run so we can go ahead and add habits we can change them however as you can imagine if i refresh this nothing is persistent so we actually have to create our server and our mongodb database remember our server and our mongodb database to actually persist this data so let's actually do those in the next section and in the next section we'll actually have uh will actually be exposed to another type of service known as the cluster ip which is very very important so far in the course we have created a react pod and we was able to access it through the creation of a node port service and we were able to access it in an external fashion however sometimes we're going to want internal communication between pods not external so how do we do that well we don't do that with node port services instead we do that with another type of service known as a cluster ip and that's what we're going to be talking about in this section so a quick reminder as to how our current architecture looks right now so so far we have created our client pod and we have created this node port service right over here that allows our browser to communicate with this client pod right over here and have access to this client pod and essentially this node port is allowing us to externally communicate from our browser to the kubernetes cluster however we're going to want cases where we really don't care for external communication to that particular pod for instance we really don't care for external communication to this mongodb pod so we're really not going to assign a node port service for this mongodb pod instead we care about internal communication so instead what we want is we want our server pod to be able to communicate to the mongodb pod that are both inside of the same kubernetes cluster now we don't do that with the node port service instead we do that with the cluster ip service and that is the purpose of the cluster ip service cluster ip service is used for internal pod communication not anything external that is up to the node port in development or the load balancer in production or even the ingress which is used in both development and production and is actually the preferable method and we're going to get to that actually a little bit later so you don't worry about that too much all right so so far we have this structure right over here but we haven't created our server pods and our mongodb pods we'll do that a little bit later but then once we create it what we're going to do just very temporarily we're going to expose our server pods to our local machine just so we can play around with it and use it really what we're going to want to do is we're going to want to just expose this server pods to the client so the client can make a request to the server and then the server to the mongodb database but for now just so we can play around with the server pod we're going to create a node port service and we're going to expose it to our browser and then after we do that the very last thing is we're going to create a cluster ip service for this mongodb pod and then any pod any internal pod that wants to have communication with this mongodb pod would then basically forward the request to the cluster ip service and then that would forward it to the mongodb pod now over here i have the server communicating to the mongodb pod but very similarly if we for some reason we want to do this the client pod can communicate with the mongodb pod by basically forwarding the request to the cluster ip and then the cluster ip to the mongodb pod all right so the first thing let's that we have to do is we have to create the server pod and the db pod so let's go about doing the server pod first all right so to do this what we're going to do is we're going to create another file we're going to call this server pod and this is going to be extremely similar to what we had before so we're going to specify an api version of v1 we're going to specify the kind of pod we're going to specify a metadata of name and then we're going to call this pod well the server pod and we're going to give it a label remember labels are needed when we want to connect a service to a pod so we're going to do app server that's what we're going to give it the label again the label can be whatever it is that we want as long as we're consistent and then for the specification over here we're gonna define the containers and then we're gonna have the name of server and then the image is going to be a lathe hard this is an image that i have created and pushed to docker hub and you should have access to it dash server and v1 is the version so if we go ahead and we just do a quick cube ctl apply dash f to the serverpod.yaml we should see that we have that created all right next step is let's create our pod so we're going to call this pod now we're creating a lot of files here it's probably not the best idea to create this many files especially for all these resources we'll talk about a better way to organize the file structure a little bit later but for now i'm going to separate the concerns just to kind of illustrate everything a little bit better okay so over here we have an api version of v1 a kind of pod this is getting a little bit repetitive a metadata of pod and then we're gonna give this a labels so remember this is very important we're gonna give this app and then for the spec what we're gonna do is we're gonna define of course the containers that are going to reside within the pod this is going to be an array entry we're going to give the container a name of and the image is going to be so the image is going to be and how do i get this well i got this from well this image right over here this is basically the default mongodb image so we can basically access that with well just all right so that's pretty much that so let's just do e cube ctl apply and we're going to do the pod this time terrific okay so we have our pods created so we are basically at this step right over here where we have our pods created which is terrific this is awesome now what we want to do is we want to expose our servers we want to expose our server to our browser so we need to create a node port for this so let's go ahead and let's do that right now so how do we do that well we would just say the server and this is going to be the server service.yaml and in here we're going to have very similar configuration that we had with our client server or service rather sorry okay so we're going to have an api version of v1 we're also going to have a kind of service we're going to have a metadata and this metadata is going to be of name server srv now when it comes to the service the name over here is going to start getting very very important so we can't really just put random names and i'll show you guys why a little bit later well you can put a random name but when whenever you want to access it especially with a cluster ip we're going to be using this right over here so this has to be a meaningful name now if that doesn't make any sense don't worry we'll get to that a little bit later all right so we have the server srv and then we are going to have the spec over here we have to define the type as a node port service then we have to define basically hey what pods we are going to be essentially forwarding requests to and this is going to be the pod with the app server label so we're basically selecting the app server label all right so next step is to define the ports this is going to be an array entry now one thing that we can do is we also can specify the protocol if we want to just tcp or whatever it is that we want to i didn't do in the last section because by default if you don't specify it then what happens is it just automatically does it by default tcp now i'm just going to do it just for documentation purposes but you really you don't have to specify if it's going to be tcp all right so the port is going to be 3 000. now how do i know that the port is 3 000 well a few reasons uh because i built the application that's pretty much the reason so you can see here that this is exposing port 3000 now one way that you can really tell is by doing a cube ctl get all let's do a quick cube ctl get all and then you can basically access that server pod so maybe you could do something like cube ctl logs and then that server pod and you can see here that is listening on port 3000 so that is one way but really that's something that you would probably have the discussion with with the developer now the target port similarly going to be 3000 lastly we need the node port remember that's the port that we're ultimately going to expose and it's going to be within a range of 30 000 to 32 000 and something i believe now we are already using 3 30 0007 so we can't use that so what we're going to do instead is we're just going to use thirty thousand and five all right and i believe that is three hundred thousands yeah that is three thirty thousand and five okay so let's go ahead and let's save this and let's just do eq cto apply dash f and essentially now what we're going to do cube ctl apply dash f and we're gonna specify the name of the manifest file that we want to apply there we go now we have created it so can we access this service through our local machine yes we can so let's to do that all we have to do is do local host 3005 now if we're using mini cube it's going to be whatever that mini cube ip is so you can see here that well it works so you can see here that there is no route slash get and that's why we're getting this but if you do something like slash api then you can see here that this is the habit app api so this works perfectly fine and if you want to explore the api itself it is written in express and javascript and you can see here it's a very simple api we have this one route to slash api we have this other route to slash post and this other route to slash get right over here and this is getting all of our habits this is posting habits and creating habits all right so let's actually do one thing before we create the cluster ip service because right now what we have created is this right over here so we have created this but now what we want to do is we want to create the cluster ip service in order for our server to communicate with the mongodb pod so we have to create this now before we do that let's actually go here and let's try to post a route and you can see here that posting a route is only going to be done through mongodb because right here you don't have to know mongodb just take my word for it we are basically posting a route and we need to have a connection to mongodb done to do that so just to prove to you that it is not going to work what i'm going to do is over here i have a post request and this is going to be the rec body and i'm just going to go send this off right now so i'm going to just send this off and you can see that it hangs forever now it's probably not best practice this hangs forever the server wasn't built properly really to be quite frank i really just built it very quickly because i wanted to explore kubernetes over the server but you can see here that it's failed because we don't have a connection to the mongodb pod now let's create the cluster ip and then we're going to try that request again so let's go ahead and create the cluster ip so and this is going to be srv.yaml and then we're going to create the cluster ip now the cluster ip is going to be still extremely similar to what we had before so we're going to specify the api version of v1 the kind of service the metadata the name now the name is going to be extremely important here and i'll and you can't just put in a new random name now you can but you would have to again use this name accordingly and i'll show you guys why in a bit but i'm going to call this srv and then we're going to use the spec and then essentially here we're going to basically define the selector so this is going to be the app so we want to basically have this service be attached to the pod with this label which remember again we created right over here okay and then the next step is to define the ports now one thing you may have noticed is that i forgot to assign the type of cluster ip and the reason for this is because if you don't define the type then by default it is cluster ip now i'll just leave it there for documentation purposes but you don't have to really worry about the type if it is a cluster ip okay so now let's define the ports now the port is going to only contain the port which is an array entry of course and the target port it is not going to contain the node port because we're not exposing this to our external environment now what are these ports going to be well they're going to be 27 017 how do i know that well i just did a little bit of research and this is the mongodb default port this is the port that it exposes so if you're using something like postgres you would do a little bit of research and you would figure out that it's 5432 i believe so it's really just dependent on how the pod was created all right so now let's create this over here so let's do e cube c t l so cube ctl get not get sorry cube ctl apply and we're gonna apply the srv dot yaml okay so now that we have created this what i'm going to do now is let's just first double check that everything is there so let's do cube ctl get all and so we can see here we have all of our pods running as well as we have our cluster ips and everything is running perfectly so let's try to do this request again hopefully this time it works sometimes there is a little bit of a lag so let's just give it some time okay let's try to send this off again for some reason it isn't working surprisingly i am actually very surprised that this is not working okay so why is that not working so let's just let's try to make this request again there we go okay so it's literally just it needed some time to spin up but you can see here now it is working now it is absolutely working so now we can do something like do my bed or maybe like a diet because you know i you know i'm starting to gain a little bit of weight i want to diet you can see here that this actually ends up creating well the service now how in the world so i created this service so i created this service right over here but how in the world are we basically telling our server pod to communicate to this cluster ip service how is that done now i'll show you guys how that's done in the next section because there we're gonna have to explore namespaces as well as d and s as well as the ips of these clusters so i'll talk about that in the next section so we have created all of our services right over here however i bet right now we're just questioning how in the world is this server pod communicating to the cluster ip and then eventually communicating to the mongodb pod well let me kind of explain that to you right now so in the code what we have is this line right over here and this is the server this is inside of the server and this is the line of code that is going to where we use to connect to the mongodb pod now over here you can see here we're using mongoose which is elibrary.connect and here we're providing the url path so this right here this first part is always going to be consistent mongodb colon dash dash and this last part is just going to be the collection name but whatever mongodb instance that we want to connect to would be basically provided right over here with the url we created all of our services but now we're just questioning how in the world is this server pod communicating with this cluster ip which eventually communicates with the mongodb pod well let me explain that to you right now the connection inside of the server is done through this line right over here this line of code so we're using mongoose to connect to our mongodb instance so mongoose.connect and over here we have basically the url that is going to define the mongodb database that we want to connect to now the first part of the url is always going to be consistent regardless of whatever mongodb database we want to connect to so it's always going to be mongodb colon dash dash and the last part is just going to be the collection name so you don't have to worry about this but right here the mongodb url this middle part right over here is going to be the unique identifier of that mongodb database that we want to connect to so what is that in our case well in our case this right here is going to be the ip of the mongodb service the cluster ip service that we have created so it's going to be that ip all right so just to kind of show that to you let's just do a quick clear and then we're going to do a cube ctl get services we're just going to get the all the services and let me just zoom out a little bit so it can be all in one line you can see here we have all of our services this is just the default kubernetes service and you can see here all of these have ip addresses so right here we have well this address right over here this is the mongodb srv and we have this address right over here so really what we're doing is something that looks like this so that is how we are connecting to this service and then this service is obviously going to forward it to this pod however this is not really what we're doing and the reason why we're not doing this is well let me show you so i'm just going to keep this right over here and let's say that something happens and this can very well happen somehow someway this got deleted and needed to be restarted so let's say cube ctl some sort of thing happened and it destroyed that particular service so we'll do cube ctl and we're going to go ahead and delete the mongodb we're going to delete the service and we have to specify that we were deleting a service so we have deleted it i hope you have deleted it there we go we have deleted it now remember this is what the service the cluster ip was before now let's go ahead and let's just recreate it so we're going to apply dash f the srv dot yaml so now it is recreated so now if i do e cube ctl get services you can see okay well this is the cluster ip now is this the same cluster ip no it's not no it's not it is not the same cluster ip just to prove it to you let's go back over here and let's i don't know let's just try to paste this somewhere over here and you can see that it is not the same cluster ip so every single time a service or or pod crashes it's ephemeral the things don't persist with it there's gonna have a completely different ip address and so we really can't connect in this way because every single time our thing goes down we have to reconfigure this right over here so what do we do instead well this is what we do instead instead we use a hidden service that we haven't seen thus far but this service does exist known as the dns service and then this service is pointing to a d and s pod and essentially this pod is going to contain a key value store of the service name and its associate cluster ip so right now right now we would do something like this it would look something like this we have the srv and it's going to be associated with this cluster ip so that is what's happening here now if this goes down for some odd reason and it comes back up well we're going to have the srv key but then we might have a change to the uh the the actual ip address so instead what we do is we basically use this name and tell the dns service to basically fetch whatever the value is of this key so instead we use this right over here so instead it's going to be srv which is exactly the name of the service that we have specified so now the srv inside of this pod right over here is gonna have a key value pair and regardless if this is changing this is always going to be consistent and that's great because this is also always going to be consistent and that why and that's why if you go to our code you can see here that i'm using srv and that's why it actually worked automatically so i hope that makes sense now you might be wondering okay well i kind of get that but i've never seen this service as well as i've never seen this pod so when i do a cube ctl let me just quickly clear that and let me do a cube ctl get all you can see here that okay well i see all of my my services here i see my pods i don't see that service that you're talking about that dns service and that's because it lives under another name space so namespaces is something that we're not going to cover extensively in this but it is important to understand essentially if we have many pods and many services and many resources what we ultimately might want to do is separate them into different concerns for instance if we have a lot of services and resources associated with our client we might want to put it in the client namespace and we can create a namespace if we want to now if we want to have a lot of resources associated with our server then we want to put that in the server namespace and that way we can basically separate our concerns a lot easier especially when we're dealing with a lot of different resources so you can really think of namespaces as folders that allow us to organize all of our resources so by default we actually have quite a few namespaces so we can do a cube ctl get namespaces name spaces and we can see all of the namespaces we have the default namespaces you might not have the ingress nginx but you can see here that we have the cube namespace we have the cube public namespace and the cubesystem namespace so right there that is a bunch of spaces and now when we do a cube ctl get something and not define the namespace it always deals with the default namespace so when i do a cube ctl get all it gets all of these services in the default namespace if i do a cube ctl apply whatever then it applies it to the default namespace however if we want to get resources inside of these other namespaces then we actually have to define the namespace so we can basically say cubectl get all and then dash n for namespace and then define that namespace so over here we're going to look at the cube system namespace so let's go enter that and you can see here well we have that cube dns that i was talking about it is right over here and it was all hidden from us and then over here we can see that we have the dns pods right over here and that is basically where all that key value pair lies now in the remainder of this section because we literally just have a few resources we don't have a lot of resources we're just going to be working with the default namespace but that is just something that i wanted you to understand so hopefully now you have an idea as to how we basically have this communication and that basically shows how important this name is because if i were to change this name to like this for instance then that key value pair let me change it to something smaller like just lathe that right there is going to be the key right over here and then consequently we would actually have to change that inside of our code so we would have to basically change that if i go right over here we'd have to change it right over here with this would have to be lace and that is how we basically communicate with our cluster ip so i hope that makes sense you got a good idea of how to how networking works in kubernetes as well as i introduced you to namespaces so that's awesome let's actually move on to the next section where we're going to talk about another resource type known as deployments time to introduce another very important resource type known as deployments and to explain deployments what i'm gonna have to do is we're gonna have to look at how we have been creating pods thus far so when we ever wanted to create a pod all we would do is we would basically specify the pod that we want to create the manifest file and it would go ahead and create that pod for us however if that pod goes down or it go gets deleted we would have to manually reapply this pod configuration for example let's look at the server pod so let's do cube ctl get all let's wait a little bit and there we go we have gotten them all and let's say that this pod goes down or it has crashed or we have accidentally deleted it so cube ctl delete pods and we're going to delete the server pod now if i do a get all on that again so if i do get all on it again and not now please but do we get all on it again then you can see that this pod is completely gone it is not there anymore however we probably want our pods to spin back up on that automatically if it crashes or it gets deleted so that is something that we probably want right now we will just have to do a cube ctl apply dash f of the server pod.yaml so we would just go ahead and do that and now it is up and running again but again we want to automate this process if we delete this or if we uh or if we basically if this crashes we want to go ahead and spin it up another thing that we might want to do is if we're getting a lot of traffic we might want to automatically just replicate the amount of pods that we have we want to horizontally scale the amount of pods so this might be another thing that we ultimately want to do and how do we do that well we could do it manually again but that is pretty difficult a much better approach is to define a separate resource that is going to be in charge of running the pods so typically we never define the pods on their own instead what we define is a deployment and a deployment is basically going to be a resource that is going to be in charge of pods and it's going to be in charge of maintaining a set number of pods so what we're going to do is we're going to define a deployment define the pod that that deployment is in charge of and define the desired state of that pod so the desired state could be we always want three of that pod running or one of that pod running and what the server what the deployment is in charge of then is basically looking at the desired state and looking at the existing pods that it is uh that is responsible for and essentially trying to ensure that hey the desired state is always met so if the desired state is to have two server pods up and running and then one of them gets removed then the deployment server is going to be in charge of spinning that up again and it will do that automatically and that's why we always have our server deployment instead of pods we never really create pods on on their own we create deployments that are in charge of pots so let's go about creating the deployment right now and we're going to start off with the server pod so we're going to start off with the server pod so the first thing we're going to do is we're going to not define pods anymore we're going to define deployment so let's just change this to server dash depot which stands for deployments now this configuration is still very important because we're going to define the pod inside of the deployment but i'm going to just comment it out for now just quickly comment it out for now but we still do need it okay so now let's start defining the deployments so to define deployments we need to specify the api version the api version is a little bit different so it's going to be slash apps v1 the kind of resource that we are defining is a deployment and then we have to have some metadata for that deployment this is going to be well the name we're just going to call this server depot which is deployment now we're going to define the specification for the deployment remember this line right here is for the deployment so i'm going to quickly just comment that right in there spec for deployments so in here we're going to define one thing and this is going to be a little bit different this is going to be defining the replicas and basically the replicas is how many replicas of the pod that this deployment is in charge of do we want up and running now typically it is usually one but we could specify three if we want to in this case let's actually leave it at three just so we can see how it looks like all right and then the next thing is the selectors and in here we are going to basically match the labels of the pod to that selector and this can be a little bit confusing because the pod is going to exist in the same file right over here and it can be a little confusing but again we're creating a completely new resource type that is in charge of another resource type so we have to link those together through labels now the way that we do is a little bit different than the way that we have done it in services because we would just do selector and then we would just specify the key value pair there's just a little bit of an additional step it is instead going to be match labels match labels and then we're gonna do app server so map server and the reason why we have to match labels is we can actually have multiple different ways that we can select a specific pod so in this case we're just going to do the match labels way all right the last thing is inside of here we also have to define the template and the template is basically the pod that we're trying to create and so it's going to contain the metadata as well as the spec so let's go ahead over here and let's just cut this out and let's just paste it right in here and let's just uncomment it tab tab and then let's go back one there we go so this is how it is going to look however inside of the template we're always going to be defining pods so we do not the do we do not put the api version or the kind because it's always going to be a pod and there's really no point of specifying that so over here we have the metadata of the pod as well as the spec for the pod not the deployment so i hope this makes a lot of sense i know this can be very very confusing so let's let me go ahead and let me let me just say that this is the spec of the pod okay so just i'm going to quickly reiterate through this deployments are kind of confusing i 100 100 understand that and you might need to go through this a few times to truly understand it but again we're stressing on the api version we're specifying the kind which is deployment and then the metadata for the deployment and then this is the specification for the deployment we have replicas then we're basically matching the deployments to pods using the match labor label selector and then the template is basically the specification of the the the pod or the pod that we're trying to create so over here we have the metadata of the pod along with its label and the specification that contains the container so hope that makes sense we're going to go ahead and run that very very quickly now before we run it what i'm going to do is i'm just going to do a cube ctl delete and i'm going to delete all so i'm going to delete all of the resources inside of our cluster so it seems here that this is not working and that's because i forgot the it's two dashes actually so now we're deleting all of the resources inside of our cluster now that is going to take a little bit of time so let's just wait that out and now what i'm also going to do is i'm for each deployment we're going to create pods and for each pod we're going to need a service to expose it in some way whether it's a node port or a load balancer or a cluster ip so instead of creating two separate files for the server depot and the server service what i like to do is i like to put this all in one file so this over here i just like to put it in the depot because we always have a service with a deployment not always but most of the time we will have that so to do this we can definitely specify two configurations in the same file however we would have to separate them with a dash dash dash so three dashes so here we have the deployment and here we have the service so if i were to do cube ctl dash f server depl it's going to create the deployment as well as the service so now we really don't need this anymore so we can just go ahead and delete it so we can go ahead and delete this let's move it to the trash all right so let's just now actually apply this and then later on we'll actually work on the other ones so let's just do a quick cube ctl get all and we should get all of them and we have nothing other than the default service so now let's do a cube ctl apply dash f and we're going to apply dash f the server dash devil.yaml so let's do that so it has created the double and has also created the service so now if i do a cube ctl get all you can see here that we have a bunch of things running so the first thing that's running is three instances of that server pod so here we have our pods and it's running three instances of it and that's because we have specified three instances and hosel created the service which makes sense that was the other config file it also has created the deployment and it says that three out of three are up and running and also created another resource type known as a replica set and a replica set is a resource type that is going to help out and it's going to perform some of the actions that we have performed here so it's going to basically create three if we want to and if we end up deleting it it's going to go ahead and save it or or spin up another instance so this is what the replica set is for typically we create the deployments because they end up creating the pods as well as a replica set so we never really deal with replica sets but if you are interested go ahead read some documentation on it okay so now let's actually look at something interesting let's say i go ahead and i delete this pod over here so let's do cube ctl and i want to delete this pod so pods and i'm going to delete this pod so let's give it some time it has been deleted which is terrific so let me just quickly exit out of this and let's do a cube ctl get all so you can see here that this has been terminated but then it was like okay i'll just go ahead and spin up another one so now we're always going to have a desired state of three let me see if i can just do this really really fast so that so that we can actually see the desired state b2 so cubectl delete pods and we can go ahead and delete this and then it quickly oh my goodness this is not quick enough let's see hopefully we can catch that oh there we go awesome we did catch it so you can see here that okay this is so one got deleted and now you can see here that it's it's two out of three so now the deployment is basically unhappy but over time it's going to basically try to satisfy the state so you can see here now it is happy and that's because we have three running pods and this is great so this ends up ever crashing then that's all good it's going to go ahead and just create the pods again and you can see here that this pod has a smaller age than these other ones because well this one was spinned up again all right so that is pretty much that let's actually go ahead and let's create the pods or deployments for these ones over here because again we always want to have deployments instead of pods so let's do that right now let's go to the mongodb dot pod and let's create the uh let's create the deployment for it so over here we're gonna have the api version and this is going to be of apps v1 we're gonna have the kind of deployment we're going to have the metadata this is going to be the metadata of the deployment which is named depot and then we're going to have the spec for the deployment let's have a replica of one and similarly over here let's change this back to one it was just for demonstration purposes where we go here we go let's just change this back to one we don't really need three so let's save that okay so now over here we're going to do the selector and we're going to match labels of app and then lastly we're going to define the pod itself that this deployment is in charge of inside of the template to do that well you would just do this right over here okay cool so that right there is pretty much that so now what we can do is we can basically get the service over here let me just copy this and let's actually paste that in there as well so we don't have multiple files there we go terrific let's rename this to depl so we're going to rename this to devil and we're going to delete this service so we're going to delete this service okay cool so now we have to do the client i highly encourage that you try to do this on your own but what i'm going to do now is i'm getting a little bit lazy so i'm just going to copy this part right over here go to the client and then just paste that in there so i'm going to get rid of the api version and the kind just paste that in there and then just tabulate this accordingly now over here i'm just going to change this to client and i'm going to change this to client all right now for the service we're gonna basically cut that out and we're gonna go ahead and do dash dash dash we're gonna spin it up like that so now we can basically save all this and we can delete this file as well because we don't need it anymore just move that to the trash all right so we basically have all of our deployments let's go ahead and apply them now now we could apply them one by one but a better way of doing it if you want to apply all of the ammo files is to do cube ctl apply dash f and instead of specifying the name we specify the directory where all of our all of our yaml files are and basically what happens in that case is it's just going to apply all of the yaml files in that directory now right here in the terminal we're in that same exact directory so we can just do dot and there we go we can go ahead and apply that and you can see here that it has created the client depot the client server it has also created the depot and the server and it has configured the server double so because we configured it basically means that it has edited it because remember we changed it back from three to one and over here this was completely unchanged so now if we do eq ctl get all give it a little bit of time hopefully it doesn't doesn't uh freeze on me in it okay it didn't which is great you can see here that we have all of our these are so these are our deployments we have our running pods right over here we have all of our services we have deployments and we have our replica sets so that right there is deployments and again we always create deployments and not pods because we want to have that automatic change in case of some sort of sort of some sort of uh change that is not desired we want to basically kubernetes to automatically do this as well as we want to specify how many replicas we want a lot more easily so we always really deal with deployments so that right there is basically this now i just noticed here that i'm gonna just change this over here to uh deployment instead of pod but it's fine it has configured it appropriately anyways okay so that is deployments and that is really really great that is really really great now the next step is to look at another service known as ingress so we talked about this a little bit later but now we actually want to use the ingress service we talked about this a little bit before but now we're gonna really dive deep into it and this is known as the ingress resource type and this is a way that we can basically network our kubernetes cluster in a little bit of a better way than we have been doing it thus far to kind of illustrate how we have been doing it thus far our application kind of looks a little something like this so we have our browser and in order to get access to our client we have a load balancer now again in our development environment this is a node port but in production it's going to be a load balancer so i just changed it to a load balancer so we would just go ahead and we would access our client pod with this load balancer service however if we wanted to have access to our server pod then we would have to configure another load balancer now as you can imagine if we get thousands of pods that our browser needs to have access to then we would have to create 12 thousands of load balancers and this is kind of annoying and is also not that great so instead we can actually solve this problem with the ingress resource type and how does it solve it well it changes the architecture to something like this so now all we have is one load balancer and we always are going to forward our request to the ingress resource type and then the ingress resource type is going to read that request and then it's going to have a set of rules that is going to follow and then with that rules it's going to essentially distribute it to the correct pod for instance if i make a request like habit tracker tracker.com basically saying hey i want to see the website itself let me just go ahead and increase the size of this i want to see the website itself then what's going to happen is it's going to basically the ingress is going to get this and the route rule says okay if this doesn't have any slash or anything appended after it then go ahead and forward this to the client pod if there's nothing after this it's going to go ahead and append it to the client pod however if i want to basically access the api so like api dash habit or whatever then it's going to basically read that rule it's going to say oh this actually hasn't slash api so we're going to forward this to the server pod and this is a lot better this is much much better and the reason for this is because now we don't have to configure a bunch of load balancers as well as this is going to be exactly the same environment in production as it is in development which is terrific we always want to have similar environments in both development and production so i hope that makes sense and let's actually go ahead and start creating this resource type right now now to create this resource type it is a little bit complicated so what we're gonna have to do is we're gonna have to go to uh ingress engine x to create a bunch of resource types associated to this ingress type right over here now to to find this just go to google and just click or just search ingress nginx so ingress nginx right over here and then what we're gonna do is we're basically going to click right on this page over here kubernetes.github.io so once we click on this then we're going to go to this page right over here and then we're going to go to deployments so in order to create this resource there is a mandatory command that we have to execute and this command is going to be different depending on the environment that we're in i'm using docker desktop but you could be using mini cube so if you're using mini cube click on this and if i'm going to click on this because i'm using docker desktop now you could also be using a cloud provider like digitalocean or azure or aws or google cloud so you might want to basically click on this if you are in a production environment right now i'm going to click on this right over here and this is the mandatory command that i need to execute in order to run that ingross resource type okay so what is this command well this command looks like well a cubectl apply command that we have been doing thus far so let's see here i'm going to just copy this and it seems to be an http link and i'm just going to paste it right in there and you can see here that this is just a bunch of yaml configurations over here we have a namespace that we talked about over here we have a config map that we will talk about and just a bunch of different resource types that are needed to run that ingress resource type and that's basically what we are doing right here now if you're on mini cube that is this is basically an extension so you would just or an add-on you would just enable that add-on so you can just click on this command so i'm going to go ahead and just paste this in here and just wait a little bit and you can see for me everything was unchanged because i've already created all those resource types before but for you it might all be created created created created so once that's done we can actually go ahead and start creating this right over here and how do we do that well we create it with manifest files of course so let's create the ingress and then the ingress srv.yaml okay so the ingress service.yaml so the first thing we have to do is specify the api version this is a little bit weird it's going to be extension dash v1 dash v1 beta 1 and then we're going to have a kind of ingress we're also going to have a metadata and this metadata is going to contain a name of ingress service and then we're going to have something else called annotations annotations and in the annotations we're first going to say that hey this ingress service is an engine x in regress service now we do this with kubernetes dot i o dash ingress dot class dot engine x now this is i know it's super super strange really really strange but don't worry all too much about it this is basically saying that the ingress service is using nginx and later on once you have done this you can just literally just copy and paste it so you don't really have to remember this the next thing is that we want to be able to set regex rules inside of our ingress service and the reason for this is because what we want to ultimately do is anything that has slash api in it whether it's slash api habit slash api bananas slash api whatever we want to forward it to the server pod but then if it's just a slash or slash anything that does not start with slash api we want to forward that to the client pod and the only real way we can actually set up this rule is by using regex if you don't understand regex don't worry all too much about it i highly suggest maybe reading a little something about it but you'll see you'll see it in use in the rules in a second now to say that we want to enable regex we would do engine x dot ingress so engine x dot ingress dot kubernetes dot io dash use regex and we're going to set this to true so please please please if you're following along make sure that everything is typed in properly this was a very kind of complicated uh set of lines that we have done okay so now that is out of the way now let's define the specification of the ingress service and in here we're going to define the rules so in here we're going to define the rules so the first thing that we're going to have and we can have multiple rules so this isn't going to be an array entry and so the first thing that we're going to have to provide is the host right now the host of our application is localhost and unfortunately we can't use localhost on our as our host in the ingress nginx service rules we actually have to use a real domain name so we can either register a domain name or we can basically trick our current machine right now we can trick our current machine right now basically saying that hey this is a domain name that we're using but really just link it up to our local host now how do we do this well to do this what we would do if you're on a mac and or linux machine you would just go to your terminal and you would open up a folder called dash etsy dash host so dash etsy dash hosts so you can see here that this opened up this right over here and you can see here that this basically is uh the localhost api and it's linked to localhost so now what we can basically do is we can basically copy this down we can go over here and we can basically change this to let's say habit tracker.com so habit tracker.com so now whenever we go to habitracker.com it's going to go to this localhost ip so let's go ahead and let's save that and we're going to have to save this as sudo so we're gonna go retry this and i'm gonna have to put in my password to my actual machine so i saved that so now we can actually use this so we can actually go ahead and use this host and we can basically trick our ingress service to say that hey this is the domain but really is connected to our local machine now if you're on windows the step to get to that etsy folder is going to be a little bit different i'm not on a windows machine nor do i have the ability to record on a windows machine so what i'm going to do is i'm going to show you the steps that you have to take to get to that folder so the first thing you want to do is you want to go to that start button and you want to run it as an administrator so go to the start button write command prompt right click on it and run it as an administrator and then move into the windows system32 driver etsy folder so move into that folder move into that directory right over here so when you're running as an administrator you're probably going to go to windows system 32 so then you would just cd into drivers and then cd into etsy and once you cd into that execute this command in the terminal notepad hosts and that should open a notepad instance that it looks very similar to what we have over here and then you would just do the exact same thing right over here okay so i hope that makes sense so that is what we are basically doing terrific all right so now that we have that let's actually go ahead let's close this up let's set up our routing rules so the first thing we're going to do is we're going to say http because this is going to be http rules and then we're going to specify the paths so this is going to be an array entry and we're gonna say firstly the first path is if it goes to slash api slash and then here's where the regex comes in slash anything else so this is basically saying this is saying that hey if the pass is slash api slash anything else this is basically how we define anything else then what i want you to do is i want you to forward this to the to the service that we have created and this is going to be the service in charge of the uh uh the the server pod so we want you to forward this request to the service that is in charge of the the server pod so now basically what we want to do in the server pod i know right now we have a node port so we have a node port in the service port but we probably don't want this anymore we actually want to use a cluster ip because now all the communication is internal so let me just quickly illustrate that all the communication is going to be internal so we can basically get rid of this if we want to and so we want to basically forward this to this right over here the service srv and remember if it's cert it forwards it to the service srv then it's ultimately going to service forward it to the pod itself so to do that we will basically say back end and then we basically want to say we want you to forward this to the service name of service srv and then we want to specify the service port and this is well three thousands so remember over here three thousand okay so that is the first rule and now the second rule is well let's define the other path so the path is going to be well if it is just slash and then anything else so if it's slash and anything else that is not slash api because api is going to be hit first then we want you to forward this to the back end and this is going to be the service name of the client srv the client srv and then the service port so the service port of three thousand okay so now let's actually go back to the client service and let's change this to a cluster ip and let's get rid of the node port right over here okay that is terrific and that is pretty much it now we have set up the routing rules so one thing that we want to do now actually is we want to go to the client and i want to change this version to version two because this is the version that actually utilizes that uh that ingress service because before it wasn't utilizing it so let's just change this to version two all right so that is terrific that is pretty much it so now what we can basically do is we can apply all this so let's do cube ctl let's just do a quick clear here let's just do cube ctl apply dash f and then dot all the files in the directory all right so we have configured configured some of them are unchanged because we didn't really do anything with the mongodb unable to recognize a no match kind inversion okay so this hasn't worked so let's actually try to fix this up and the reason for this is because this is sorry apologies apologies apologies is going to be extensions not extension so that's why it can't find it so let's let's save that and let's go ahead and let's apply this again so over here is saying okay unknown spec and the reason for this again my goodness this is supposed to be not inside of the metadata it is supposed to be outside right over here so hopefully you caught that sorry things can get a little bit tricky when you're creating all these files so again we got the api version this should be extensions and then the spec shouldn't be inside of the metadata and that kind of illustrates how important the indentation is in yambo files so hopefully there's no more errors let's do cube ctl apply and we are still getting some more errors so unknown field spec off camera i was scratching my head wondering what in the world is wrong with this config file only to realize that i did not save this so please remember to save and then once you save just apply this over here so cube ctl apply dash f dot and then once you do that you might have to wait a minute or two you will be able to go to habit tracker.com and you should see the application now now if you see some sort of error page saying that hey this is not secure that's only because we are using http instead of https and this makes sense we obviously don't have an ssl certificate to get around it anywhere on the web page just click anywhere on the web page and just type this is unsafe without any spaces just this is unsafe and then you should be able to see this now i see this because i've already typed it a million times before and if you don't see it that's great so now you can see that we have our application which is terrific so right here if i do something like slash this it's always going to just forward it to the react app if i do slash api however you can see that it forwards it to the api instead you can see that now our ingress service is working the way that we have specified it which is terrific so now what we can do is we can go ahead and let's go ahead and let's add a habit uh a a new it whatever and now we can save this habit you can see here we can save that and what's great about it is if i refresh this that habit persists that habit persists and the reason for this is because this is stored in our mongodb database now let's say we run into a problem our mongodb database goes down let's say that this happens so let's do a quick cube cto so let's do cube ctl get the pods so remember our pods is going to our mongodb database is going to exist in this pod over here and let's say this goes ahead and it crashes so it crashes so let's do the simulate this by doing cube ctl delete pods and we're going to delete this pod right over here now what's great about this is now essentially what's going to happen is our pod is going to start up get up and running again so now we have a different pod so to kind of illustrate this remember this is uh this was our pod before and you can see that the identifier is a little bit different you can see here it ends with 2k over here this one ends with two pv and so this is completely is a completely different pod but our deployment created that because it was deleted however now if i refresh this our data is gone our data is completely gone and i'll talk a little bit about why this is in the next section and we're gonna talk about how we can actually persist data in that section as well we finally got our application up and running but we noticed a problem if our mongodb pod goes down and then gets restarted again our data does not persist and that is a very huge problem because we have to 100 assume that our mongodb pod will crash eventually and need to be restarted so how can we persist our data knowing that our mongodb pod will eventually crash so before i explore some of the options that we have let me tell you why we don't persist our data if our mongodb pod crashes so over here i have our db pod and in here of course we have our mongodb container and inside of the container we have a bunch of files and folders within it and particularly we have a directory slash data db that is very particular to mongodb and this is exactly where all of our data is being stored so if i were to add a habit it would store it over here if i were to add another habit it would store it in that exact same directory and if i ever want to basically request data well that data will be located here now if that container goes down and needs to be restarted however what ends up happening is it restarts the container in a completely blank slate and all the data that we had in there are completely gone and that's exactly why when this pod crashes or a container in this pod crashes we lose all of our data so how do we fix this how are we going to fix this problem because we again 100 have to assume that this pod will eventually go down so how do we fix this because persistent storage is very important well one way to fix this is through something known as a volume so essentially in a volume what we can basically do is external to the container we can have some sort of storage external to this container and every single time we want to add data into this container over here we want to add data we also add it into the storage so we add it into this storage over here and basically this directory this directory over here is mounted to this external storage so this this uh directory is mounted to this external source so it basically has access to all this data and this external storage is located inside of the pod but outside of the container so if the container ever crashes if it ever crashes and has to be restarted again that is completely fine because now it can just get the data from this external storage inside of the pod now you might be noticing a problem with this and it is a huge problem what if the pod crashes and if the pod crashes then we lose all of that data inside of this external storage because this volume is located inside of the pod itself so this is not a very good solution yes you know what it it protects against the container crashing but it doesn't protect against the pod crashing so this is not a very good solution let's find another solution well another solution is a persistent volume and this is where the storage is located external to the pod and so essentially now what we can do is when we want to add something to it well we add it to this storage and then this directory over here is going to be mounted to the storage and therefore it's going to have all that data now if the whole pod crashes completely fine that is okay we can just spin up another pod and our data will still be located in this storage right over here and this is well the ideal way of doing things especially when it comes to databases so that is what we are going to be doing however we're going to be doing something known as a persistent volume claim and a persistent volume claim is not really a way of storing data so over here we have a way of storing data essentially a persistent volume claim is a way of asking for a persistent volume so for instance right over here we have basically three options we have three options over here we have either one gigabyte of storage two gigabytes of storage or three gigabytes of storage and these right here these options are persistent volume claims so they're just options that we potentially have and essentially what happens is these options are here and then we would have to go ahead and ask for an option so i can say oh i want one gigabyte of persistent volume for my mongodb container and essentially what kubernetes will eventually do is create a persistent volume and it's going to figure it out somehow it's going to be like okay well you want you want this one gigabyte right over here and you want it persistent volume so it's going to create this persistent volume over here and of course mount it to the mongodb container so essentially what we're going to do is we're going to create persistent volume claims which are a bunch of options that we potentially have for our kubernetes cluster and then we're going to basically pick whatever persistent volume claim that we want to use for our container so that is what we are going to do and let's actually go about doing that right now okay so let me just quickly zoom in a little bit here and let me just do a little bit of a clear there we go okay so now what we're going to do is we're going to create a persistent volume claim so and i'm going to call this pvc for persistent volume claim and this is a persistent volume claim so we'll leave it in here so the first thing that we are going to do let me zoom in some more here the first thing we're going to do is of course api version which is v1 the second thing is kind and this is well going to be a persistent volume claim so this is the persistent volume claim the second thing we're going to specify is the metadata now the metadata is just going to have a name we're going to call this persistent volume claim all right now we need the specification of that persistent volume claim and this is where it gets a little bit interesting the first thing that we're going to do is the access modes so the access modes and we're going to this is going to be an array entry and we're just going to specify read write once and apologies oh my goodness and this also has to be a capital right here so read write once now what does this mean right over here well if you go to the official documentations of kubernetes you can look at all the access modes basically right here we have three different access modes so read write once is we allow so the volume is mounted as a read write by a single node so we can read and write data from a single node and this is basically what we want because our pod is always going to be on one node because we're only going to have one replica of it anyways but if you want other options so read only many so the volume can be mounted and it can be read by many nodes that is definitely a possibility so we could actually add this if you want many nodes to be able to to read from our volume you could also add this however i don't really want that and then we have read right many so the volume can be mounted as read write by many nodes so over here you would either pick one or the other as if you want your if you want your volume to be mounted and read and written by by many nodes and you would use this over here okay so i hope that clears that up so that is the access mode and then we're gonna basically well define the resources over here so remember if i go back here this is not storage this is basically a bunch of options that we have because this is our each one of these is a persistent volume claim so we're going to basically say that hey i want to choose this option or i want to choose this option i want to choose this option so as you can see here this option has one gigabyte of storage this option has two gigabytes of storage this option has three gigabytes of storage so what i'm gonna do is i'm gonna say okay i'm gonna create the options and i'm gonna basically define the resources for each option so the resources and i'm gonna basically request so request and i'm gonna request a storage of one gigabyte now i can create multiple persistent volume claims i'm just gonna do one for this case but i can very easily create multiple persistent volume claims maybe give this another name of two and then i can do another one of three and then i get to pick which option from my container we'll see how we can pick them right now actually all right so now that we have created the persistent volume claim now let's actually go about using it inside of the mongodb container okay so remember the mongodb container is going to be resided in the mongodb pod which is basically right over here this is the specification for the mongodb pod so the first thing that we have to do is inside of the db pod specification we have to define all of the potential volumes that we are going to be using and we can use multiple different volumes but now we're only really going to be using one so let's just define all of the volumes and this is going to be an array entry and we're gonna call this volume well storage so that's what we're gonna do and then what we're going to do is we're going to well define the actual volume now the volume is coming from well the persistent volume claim so we would just say persistent volume claim and then we would do claim name and this claim is going to be the basically the name right over here that we have specified so we can basically copy that name and then we can just paste that in there so this right here is basically saying okay well there's these are some of the the the volumes that are located in the mongodb pod these are some of the options that we have however now we need to actually allocate it to the mongodb container well to do that inside of the container level what we basically do at this point is we just say hey we want to mount this volume so volume mounts and this is going to be mounts with an s because we can have multiple mounts we're going to say the name of the volume that we want to use now the name is going to be identical to the volume that name that we have created right over here in the pod level so then we say storage and then very importantly we basically have to define the path where we want that data to be mounted to now what is that path well it's going to be very dependent on the database that you're using but in mongodb the path is slash data db how did i figure that out i literally just researched it up so it's it's it's that's basically how you would figure it out it would be probably a different path for a postgres container a different path for mysql container so we would say host path and basically the host path is going to be slash data slash db okay so that is pretty much all that we really have to do so let's actually go ahead and let's do a cube ctl and we're going to apply everything so i'm just going to keep ctl-f apply so hopefully no problems are arising and there is a problem of course so we have some sort of error here so the double unknown field host path and that is because let me see here unknown where is this host path okay so this this is so it's failing right over here and of course it's not hosts path apologies it's mount path apologies for that hopefully uh you guys caught that or if you didn't it's mount path it's not host path sorry so this is basically the path that we actually want to mount inside of the persistent volume all right so hopefully that's okay now so if i do a okay so it seems like everything has been created uh his persistent volume p is invalid the only reason why i got this error is because i have already created a persistent volume like this and i had it at two gigabytes so i basically just changed it to two gigabytes but high chance that you probably are not getting this error okay cool so that is pretty much it so we have basically configured our persistent volume which is which is pretty great so now if we do e cube ctl get all we should see well of course all of our resources all of our replica sets as well as our our deployments and our services and our wall pods but we don't see our persistent volumes to see our persistent volumes just do cube ctl get pv and you can see here that we get have one persistent volume so let me just quickly uh let me just quickly zoom out of there a bit just so we can see the table a little bit better you can see here that the capacity is two gigabytes which is terrific and then we basically have a status of bound which is says hey i'm being used and then we have basically well the claim that it's using so remember the persistent volume is the actual storage location so this is the persistent volume that was created from our persistent volume claim now over here we have something called storage class and i'll get to that in the next section so don't worry about it but right now you can see that it says host path which is cool so okay so that is pretty much this so and then basically right here it's using the persistent volume claim that we have created now to see the persistent volume claim we can just do cube ctl get pvc and then this is the persistent volume claim the mongodb you can see that it's bound we can see the volume that's associated with it and we can see the storage class the storage class is very very important and i'll get to that in the next section but now let's see if it actually ends up working so let's go back to our react application do a quick refresh and we can see here that okay well i have this data right over here i added this before but let me add another one let me say clean my room okay so if i save this and then i refresh it all right terrific so well this is fine this is what we had before but now let me go ahead do a cube ctl get all and i'm gonna go ahead and i'm not even gonna delete the container i'm gonna delete the whole pod so i'm gonna delete the whole deployment rather so i'm gonna delete the whole deployment so i'm gonna go ahead and do a cube cto delete deployment delete deployment so typically the pod is going to be deleted not the deployment but just to prove to you that the pod is completely gone so we're going to delete that deployment we're going to do a cube ctl get all so you can see here that now we are terminating this pod right over here so this pod does not exist it is completely gone and basically simulating it crashing so right now we basically don't have our data and that makes sense this is this makes sense because we still don't have our pod back up and running so now let's just do a cube ctl apply all so let's say now that everything is back up and running our pod is our pod is is back up so now if i do a cube ctl get all so we can go ahead and we can basically see okay our mongodb pod is back up and running now if i do a refresh let's do a quick refresh there we go so it took some time but our data is still back which is terrific so that it was great the only reason why it took so long is it probably took the pod a little bit of time to get up and running again but you can see here that our data is persisting and actually the way that we did this here is going to be consistent with the way that we actually do it in production with an actual cloud provider and we'll actually get to why that is through well that storage class that i was talking about so i'll get to that in the next section in this section we're going to explore what storage classes are because they're very very important and the only reason why we didn't see them in the last section was because we just relied on the default version and that's probably what you're ultimately going to be doing with almost all of your applications just relying on the default however it is still good to know and understand all right so let's go back to this diagram over here so remember we have a bunch of persistent volume claims remember these are just claims they're not actual persistent volumes and so these are basically just options and then inside of the container we basically are going to say that hey i want to use this persistent volume or this persistent volume or this one and then kubernetes is responsible for actually creating that persistent volume so over here i'm going to say okay well i want to use well one i want to basically use this persistent volume over here for my mongodb container kubernetes create me a persistent volume with one gigabyte of storage well how is kubernetes going to do that well kubernetes needs to find a location to actually create that persistent volume now for us that location was well our hard drive on our local machine because so kubernetes figured out that we're running this cluster on our local machine and it's going to say okay well i am going to create this persistent volume inside of our hard drive on our local machine because hey i figured it out you also didn't specify a place for me to create this persistent volume in so i'm just gonna do it here and that right there the location where the persistent volume is going to be created is the storage class and if we go back over here and we do cube ctl get well let's do persistent volume so the one persistent volume that we have created we have a storage class of host path so this is basically what the the host our current computer that we're working on we're basically using this to create our persistent volume claim and that is pretty much that now once you go to cloud providers there's many different storage classes that we have for instance for microsoft azure we have azure file or azure disk for aws we have elastic block store for google cloud we have a bunch more and so essentially what we can do is we can specify the exact one that we want or we can just let kubernetes figure it out for instance if we're running our kubernetes cluster in aws then by default it's just going to use elastic block store if we haven't specified anything else similarly with azure and that's what i basically like when we have a simplistic example like mongodb database we're probably just going to want kubernetes to pick the default one however when we really have a fine-tuned application and we need to really pick the one that we want then that is when we specify the storage class so that is basically storage classes we're not going to be using them we're not going to be defining them right over here but you can basically see that this is how we would define it we would basically have some sort of uh um yaml manifest file and then we would just bind it to the volume however we're not going to be doing that we're just going to be relying on the default but if you want to do it please feel free to read about storage classes in this webpage right over here to introduce a brand new resource type known as secrets so in this section we're going to talk about secrets and secrets are actually relatively easy compared to all the other resource types that we have been learning so don't worry all too much about it and along with secrets we're going to learn about environment variables and how we can pass environment variables to our container okay so let's say that we got an update from our developers our developers that were in charge of this server over here basically said hey we have a new version of this server up and running so over here we have v2 and simply the only changes that were done to v2 was that they just passed the uri as an environment variable so before it was just plain text but now it's an environment variable and what they want you to do is to simply just add the environment variable to that container so to the server container and so you could do that relatively easily to do that all you really have to go is to go to that container which is going to be in the server depot and in the spec of the pod and what you can basically say is okay well you want me to pass environment variables and we can basically a name of uri so to pass environment variables in the container section we put past the end over here and then this will be an array entry of name and values so we can basically say uri so uri and then the value of this would just be well the value that we had before so this would be db colon slash slash srv now slash habits now this works completely fine and this this this will work however let's say that this right here is sensitive information that we do not want to commit to github we don't want to have it right here in our file inside of the depo now in this case this is this isn't really sensitive information because we're connecting to the mongodb inside of our cluster and there's really no way anybody else can do that unless they have access to our cluster itself but let's say we were connecting to mongodb atlas which is a cloud provider well this would be very very sensitive information because it would contain the username along with the password along with other things so we probably do not want to save this inside of our depot because we ultimately we don't want to commit it and have anybody have access to it so what do we do well we do create secrets so that's what we're ultimately going to do we're going to create a secret that is going to house this information and we're going to create this secret in another manifest file but that manifest file we're going to deliberately not connect it or not commit it to github so it's not out there for the world to see okay so let's go about creating it right now so the first thing that we're going to do is we're going to change the version to v2 because that's the version that has the environment variable and then we're going to create a secret okay so to create the secret extremely simple so what we're going to do is we're going to do secret dot yamo and so over here what we're going to basically have is an api version of v1 we're also going to have a kind of secret we're also going to have a metadata and we're going to give this secret a name so we're going to call this we're going to call it credentials so credentials and then we're going to provide it with that key value pair now we can have multiple key value pairs and so over here we would say something like string data and the reason why it's string data is a secret has to be base64 encoded now we don't want to encode it ourselves what we do is we want to provide the string and we want the kubernetes to encode it for us so that is exactly why we provide string data over data now if we wanted to encode it ourselves then we would just say data and then we would have the key value pair so we're going to say uri and then well whatever that uh that value is so i'm just gonna copy it right over here and i'm also going to just quickly double check that that is completely right yes i believe so so however again because we are passing in a string and we want kubernetes to base encode it then we just pass well string data there we go and we can again we can pass as many things as we want in here of course the the keys have to be different but we can pass whatever it is that we want so in this case we're just gonna pass in one and so this is going to create our secret for us now how do we use the secret right over here so what i'm gonna do is i'm gonna get rid of this and we're going to basically have to use the secret in a different way so the name is actually going to stay the same the name is going to be the uri but the value is going to be different because the value we want to get it from the secret itself so the value instead of using the value key we use the value from key and then we have to specify that hey we want to get the value from well the secret key ref and that basically says that hey we want to get the value from one of the secrets that we have created and then well we have to specify the secret name and so this is the secret name right over here the credentials and the reason why we have to specify one of the secret names is because we can have multiple secrets we have to specify the secret name and then within that secret we have to specify the key that we want to use remember we can have multiple keys we can have multiple keys maybe this is i don't know postgres for some reason we're storing postgres url in here we're storing another secret over here so we have to specify which one we want to use in this case we are going to use the uri and so we basically specify that key and that basically achieves the same exact thing so now what we can do is we can commit the server double to github but we don't commit the secret ticket hub and now if somebody ends up seeing the server depot well they're not really going to get a lot of information from here because okay you have this environment variable but we have no idea what the actual well url is all right so let's actually do that and okay so that is pretty much that and let's just make sure again make sure that this is version two for you so what i'm going to quickly do is i'm going to just do a cube ctl i'm going to delete all my resources just to start from scratch okay so we're going to delete all my resources and i'm just going to apply them again i really didn't have to do that but whatever i did it anyways so if i do a cube ctl we get all you can see here that well now we have we still have our pods because they're terminating let's just do a get all now now we don't have anything let me just do a quick clear and then do we get all you can see that we have nothing okay so let's just go ahead and apply everything cube ctl apply dash f dot everything has been created awesome so over here we have our secret which was created and now if i do a cube ctl get all get all you can see here that okay our server is up and running so what i'm going to do is i'm going to quickly log this server so i'm going to do a cube ctl logs and i'm going to log this pod right over here and you can see here that it's still connected to mongodb despite us having the environment variable and that basically means that hey this works nice and well now one thing about secrets secrets are not really that secure if you have access to the kubernetes cluster if some malicious user has access to the kubernetes cluster they can figure out the uh the the secrets themselves like what the value of the secrets themselves and that's because they're only base64 encoded and they're not actually encrypted with a key so really they're just basically used for well an additional kind of layer of security so we can basically say that hey now a person can't easily figure out what the uri is or what the environment variable is with secrets but again if the user has access to the kubernetes cluster and has access to the secret they can very easily actually figure it out so that was just one thing that i quickly wanted to note so that is pretty much this uh or pretty much that i don't know why i keep saying that now in the next section and where we're really we're really reaching the the end of this crash course we're going to be talking about requests and limits okay welcome back to the very last section of this crash course if you made it this far well i am extremely happy thank you so so so much in this section we're going to be talking about requests and limits and requests on limits are not resource types so let's just get that clear right off the bat i'm going to try to explain them through this example scenario right over here so let's actually go way back when we talked about our kubernetes cluster a kubernetes cluster is going to be comprised of multiple worker nodes so over here we have multiple nodes in this example we have two and inside of the worker nodes we're gonna have our running pods now one thing to note is that we have a certain amount of memory and cpu inside of this worker node so for node 1 we have 500 memory and then for cpu we have 300 inside of this worker node now we can never exceed that amount because if we do then our node inside of our kubernetes cluster starts to fail and that is not good we never want that in our kubernetes cluster so to basically avoid this what happens is the scheduler basically assigns the pods accordingly so let's say we have this pod and this pod uses 200 memory and 200 cpu and it basically assigns it to this node right over here so now basically the available memory that is left is going to be 500 minus 200 which is 300 and cpu is going to be 300 minus 200 which is 100 okay great so now let's say that we have another another oops let me quickly copy and paste this we have another pod that uses the exact same amount and we tell our schedule that hey we want to deploy this now the problem here is is that the schedule has no way of predicting how much it is going to use right here we can see that it's going to use 200 but it could very well use 600 we have no idea of figuring it out and similarly the schedule really has no idea so it is likely that the scheduler can put it into this node and everything is fine and dandy but it also could put it into this node right over here so we could put it into here and now we basically exceeded the amount of cpu that we have and it could cause this to fail right over here now it's not really the schedule is not going to really try to make the node fail what it's going to do is quickly basically evict this pod and then just schedule it to something else but you can see here that the schedule has really no idea absolutely no idea as to the amount of memory and cpu that this pod is going to take so it has no idea so it's basically a guessing game it's gonna go through it in this pod if that's fine nothing crashes okay that's good but it's really a guessing game so what we can do to make this schedule's life a lot easier is we can basically define a request so over here this is another pod and within that pod we're defining the requests and and really we're defining the uh uh the requests inside of the container in the pod not really the pod itself and basically this is saying that hey this is going to use around 200 uh memory and then 200 cpu this is this is basically what we're requesting so now what the scheduler can do is be like oh okay you're requesting this now okay so it actually so i can put it into node one if i'm looking at the memory but i can't put it into node 2 because we don't have enough cpu so basically what happens here is it's like okay well i can actually go ahead and put it into node 2 because that basically passes everything so over here we're basically saying to our scheduler that hey this is possible uh we're giving our scheduler a lot more information and that way it can manage manage the pods inside of the nodes a lot more easily so now we can basically decrease this to 300 and we can also decrease this to 100. however with requests it is not a hard limit we could actually end up using more memory requests are basically kind of an estimate we can say hey we expect that we're going to use 200 of memory and 200 of cpu but we could exceed it so we could go to like 300 for instance so we could go to 300 and if you do go to 300 then well now we actually only have two available so 200 available okay so that that is basically what requests are now if we want to be more strict and let me just copy and paste this right over here if we want to be more strict what we can provide are requests and limits so basically here what's happening is we're providing that request so we're saying that hey we're going to use this and we're also providing a limit and a limit basically means that if this ever exceeds it so if this ever goes to 205 or something like that then what it's going to do is it's going to bring down this whole pod and it's going to restart it so that you know the memory can go back to 200 so so the request is basically saying that hey you know we estimate that we're going to use this and then the limit is saying that hey no this is always going to use it and if it ever exceeds it we're going to actually bring down this pod and restart it so a limit is basically saying that hey this is pretty much guaranteed to to use of maximum 200 memory and 200 cpu and this is definitely the best thing for the scheduler because here the scheduler can really figure out exactly what to do with this one because now it knows 100 that it's going to be maximum 200 memory maximum 200 cpu now let's actually talk about this a little bit now so i'm going to quickly just copy this and i'm going to just cut this out over here because this diagram these diagrams are a little bit better so so these are the three different uh these are the three different uh basically pods and containers that we can have we can have one where we don't define anything and then we can have one where we have basically defined the request only and we can define one where we have the request and the limit now it just so happens that that kubernetes what it does is depending on what we do it assigns that particular container or that particular pod equality of service class equality of service class and we'll see this in a bit now if we don't define anything then this is going to be given the quality of service class of best effort so of best effort if we do just define the request then it's going to give it the quality of service class of burstable and this kind of makes sense because you know what hey we're defining 200 but it could burst up to like 250. however if we provide the request and the limit and the limit is exactly the same as the request so over here this actually has to be changed to 100 and the limit is exactly the same as the request then this is going to be guaranteed so this is going to be guaranteed and that basically says that hey this guarantees this guarantees that this will always be of maximum 200 memory and 100 cpu now why is this important well this is important because the scheduler is going to basically use these quality of assurance classes to evict these pods and it's going to start off with evicting the best efforts pods first and then burstable pods and then guaranteed pods so what do i mean by that well if we go ahead and i basically add this node right over here or this pod to this uh this node so this plot to this node at this point now we are exceeding the limits so the scheduler instead of basically crashing the node what it's going to do is it's going to evict the pods now which pod is it going to evict well it's going to evict this pot over here which is the best effort pod and it's going to leave the guaranteed pod and it's going to try to reschedule this pod somewhere else and similarly if we have over here the uh i know this is kind of getting big but if we also have here the uh this is the burstable pod and you can see here that it's basically uh taking up too much space it's going to evict the burstable pod and then put it over here so if you want you want to basically ensure that one of the pods is not going to be evicted first or evicted last in the chain then you want to start specifying the requests and the limits so i hope that makes sense now let's actually well do that in our manifest files right over here so doing this is really really easy it was just understanding the concepts that was a little bit more difficult so to do this we basically have to go to the pod where we want to specify these resources so to do that we would just go to let's start off with the let's start off with the server okay so let's start off with the server and inside of this container we're going to specify the resources so we're going to do over here re-store says and basically this resource we're going to define the requests and the limits so over here we have the requests and then the request here is going to we're going to have a key value of memory and here we're going to define 200 mi and then for the cpu we're going to define 100 m so that is pretty much here so here we're basically defining the requests so we're defining the request but we're not defining the uh the the limit so so it could actually be bursting up to 250 possibly but we're saying we're giving it kind of a rough estimate so this is going to be a burstable pod now let's actually try to do the same thing but now with the mongodb container so in here let's specify the resources and then we're going to define the requests and then for the memory let's just do 200 mi as well as for the cpu we're going to do 100 m and then we're also going to define the limits here and this is going to be exactly the same as the uh the the requests so we have cpu 100m all right and then for the client pod we're just going to not define anything okay so that is pretty much that so now let's just do a cube ctl apply dash f dot and you can see here that our depot was configured as well as our uh our so our deployment was configured as well as our where is the other one okay as long as along with our service deployment so our service deployment which is i can't seem to find it right here okay so that's a service deployment right there uh and that is unchanged for some reason i wasn't expecting that uh okay well uh hopefully hopefully it did end up changing if it didn't then i'll i'll fix it again but the best way to actually check if it changes is let's do a cube ctl get all and then let's actually go to the pods themselves so what i'm going to do is i'm going to basically copy this polygon this is the client depot this is the client depot but really this is the client pod over here this is just the pod name so over here what i'm going to do is i'm going to basically describe this pod so i'm going to do a cube ctl describe and i'm going to describe this pod right over here so if i enter that and of course i always seem to forget that it's described then i have to define the resource which is pods so over here i want you to notice something let me quickly zoom in here let's increase this for a bit so i want you to notice something so over here if i scroll all the way down you can see that the quality of service is best effort so that right there is basically what i defined right over here and that's because we didn't define anything for the client pod now let's actually see it for the service so or for the server and this should be burstable so let's do a cube ctl get all and then let's go to the pods and we're going to get the server we're going to do a cube ctl describe pods and we're going to describe this one okay i did this a little too fast i added an extras and then you can see here that this is burstable so that is burstable now you can imagine that the very last one so let's do a cube ctl get all and then we want to get the mongodb the pod so we'll do cube ctl describe pods and we'll describe this pod and you can see that this is guaranteed so that is the very last thing that i wanted to discuss and i highly suggest that you actually do provide the requests and the limits for each pod uh so that the scheduler has a better idea of exactly what the memory and the cpu is going to be taken up by that pod and so that the scheduler can basically assign it to the appropriate node and you might be thinking okay how do i derive these well it's really going to be dependent on your application if your application is very big and it's taking up a lot of memory and cpu then it would have to be well that a big number whereas the client actually is something that doesn't take a lot of a lot of memory and cpu so this would be quite significantly less you can probably read a lot of documentations as to arrive at how as to how to arrive these values but this isn't uh kind of in the scope of this course so i think that is pretty much it so if you made it this far thank you so so much i hope you learned a lot of kubernetes and uh i'll see you guys in the next one
Info
Channel: Laith Harb
Views: 5,343
Rating: 4.9821429 out of 5
Keywords:
Id: llf65JSPmDY
Channel Id: undefined
Length: 179min 43sec (10783 seconds)
Published: Mon May 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.