Deploy Node.js Microservices on AWS With EKS & Helm

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey there today we're going to look at how we can deploy node.js microservices using aws so we'll use aws eks to deploy microservices to a kubernetes environment and we'll be able to access an externally available api using a load balancer we're gonna go ahead and deploy the microservices we built using nasjs in the previous video so if you haven't seen that video yet i highly recommend you check it out i'll include a link in the description so let's go ahead and get started in deploying these microservices i'll see you there so firstly we're going to go ahead and clone the existing project that we have already completed in a previous video i'll include a link in the description to the github repository to where this project lives as well as a link to the video itself if you'd like to take a look at how we set this project up so once we have the url for the repository we can go ahead and clone it so this is the nest js rabbitmq microservices that we have already created now we should be able to ls and then we can cd into this folder here and then we can go ahead and feel free to open up our code editor and view this project so as i mentioned before this is the project we've already created with our three different microservices off billion orders and inside of each project we have a docker file which lays out the set of instructions for how to actually build and deploy this application inside of docker which we're going to need to be able to actually deploy our application to aws so in order to help us deploy our application in a kubernetes environment on aws we're going to use a package manager for kubernetes called helm now if you're not familiar with helm or how to install it i'll include a link in the description where you can read more about what it is and how to actually install it which is quite easy to do if you're on mac like me you'll be able to run brew install helm and simply install it locally quite easily i already have it installed so we can go ahead and continue now before we go ahead and continue i'm going to go ahead and check out a new branch on our existing repository to eks and so all of the code for this video will be on this specific branch if you'd like to check it out and follow along you can feel free so with that on a new branch we can go ahead and actually create a new folder in the root of our project called helm and this is where all of our helm charts are going to live so now that we're ready to move forward let's go ahead and create a new folder in the root of a project called helm which is where all of our helm charts for this application will live which are the set of instructions for how to deploy a given application so back in our terminal we can do ls and we can see our new helm folder let's cd into it and now we can use helm to actually create a new chart we can use helm create and then call this bordering app we can see it's gone ahead and created ordering app and now back in vs code if we open up helm we can take a look at what helm has created for us in this ordering app directory so firstly it's created this chart.yaml file and this chart.eml file is essentially the base manifest to describe this application we have the api version for helm the name of the app a description type version and application version and importantly we're going to use this chart.yaml to include dependencies on other charts that we want to bring into our application later on moving forward we can see we've created a templates folder now the templates folder are the list of the kubernetes resources that we actually want to get deployed when we deploy this helm chart we're not going to actually use any of these out of the box so we can go ahead and actually delete everything in this templates folder for now and lastly we have a values.yaml file which lists the overrides for our templates here so we can specify different values that we want to be populated with in our templates when we deploy a given chart we don't need any of these preset values here so we can go ahead and remove all this information as well and then lastly we have a helmet nor or just a set of files we want to ignore so now we're ready to go ahead and actually set up the instructions for our own applications so to do that inside of our templates directory here let's go ahead and create a set of folders for each of our apps so we'll have one for orders billing and off of course because these are our three microservices so the first template we're going to create of course is the deployment itself which is going to describe how to actually run our application so now we need to specify the deployment and if you're not familiar with kubernetes deployments and how all this ties together i will include a link in the description so you can read a bit more we're going to go ahead and get started by describing the api version that we want to use in kubernetes this will be apps v1 with a kind of deployment we'll give the metadata here and provide the name so we'll just call this orders so now we can provide a spec here and we'll specify how many instances of the orders app we want running i can say three to start off and then importantly we're going to provide the selector here so that our deployment actually deploys the correct application so we'll say that we want to deploy the app with a label called app orders and so we'll use this in a second here when we define the second section which is the template which is the actual information about the application running so we'll give some metadata here now metadata and this is where we provide the label for the actual pod that will be running and this is how this gets matched up here so we have an app orders app orders for our labels here and then we can specify the actual spec for the running application we'll provide a containers section here where we'll provide the information for the running containers so our first container and only container will be the orders container so we'll call it orders and then now we need to provide the actual image for this container we want to be able to deploy this and pull an image from anywhere when we actually deploy this whether it's locally or in amazon eks so to do that we're going to have to go ahead and build our docker images and push them to a central repository in this case we can use docker hub so i've gone over docker hub in a previous video but you can navigate over to hub.docker.com and once you sign in or create an account you have the ability to go to the repositories page and then you want to create a new repository for each one of our microservices so you can see here i have one created for ordering app underscore orders ordering app underscore auth and ordering app underscore billing you simply just need to create a repository with your account give it a name and you can go ahead and create it make sure it's public because by default you can only create one private repository in order to actually push our images up to our docker hub registry we can go into our apps directory and for each one of our apps we can go ahead and use the docker file to build the docker image and then push it up so if we were to go into orders we could run docker build and then we specify the root context which will be two directories up at the root of our project and then we can specify the docker file which is at the root and then we give it a tag so this should be the same name as our repository in docker hub so in this case it's mg ordering app underscore order after your docker image has finished building you can then run docker image push and then provide the name of the repository assuming it's your repository this will allow you to push the image up and then use it in your deployments so once it's public and you have all three of these we can then go back and actually specify in our deployment that we want to pull this from your account name so in my case this is mgue you could use my account because it's public or you can use your own whichever you feel more comfortable with and then we can specify the ordering app underscore orders image which will pull from that docker hub repository so next we'll go ahead and specify ports here so we know we have a container port for this ordering image that will be running on port 3000 listening for http requests and our final section here will inject some environment variables for the running container now of course the first one we know out of the box we'll have to specify the port and we'll give it a value of 3 000 now we also have a couple of other rabbit mq environment variables and if we want to go actually and check in our apps orders dot m-file we can see all the environment variables that we need to inject here of course we'll need to inject mongodb and rabbitmq uris but for now we don't have these running so we'll come back to them later for now let's just go ahead and provide these q names here in our m file so we'll go ahead and add a couple more environment variables here one for the billing queue and so you can see here we have our robin mcq billing queue and our auth queue so that our orders application can successfully communicate with billing and off so this is everything we need really to actually deploy this application of course we still need our mongodb and rabbitmq running but for now this is a basic deployment let's go ahead and set this up for billing and off quickly so i'll call it deployment.yaml again for billing and to make things a bit quicker we can simply just copy over our existing deployment here and so this will be the set of instructions for how to deploy the billing application so most of this is going to stay the same we'll of course change the names here to billing we can keep three replicas and make sure we just change the label app to billing the name here will be billing as well and make sure our image repository is pointing to the billing repo make sure you've also created this if necessary now of course billing is listening only on rabbitmq so we don't have a port here we can remove this section here as well as removing the port environment variable similar to orders we'll have to come back and specify the rabbitmq and mongodb uri in a bit but for now this is everything we need for this deployment so let's go ahead and set up our final deployment for the off microserver so as we've done before i'll go ahead and paste our existing deployment in here and we can go ahead and simply change the name of the app here to off so we'll go ahead and change all of this information change the image over here to app underscore off as well we will go ahead and also add a port section now because we have a container port listing on 3001 for http request now additionally if we go ahead and look at our auth project here on the dot m file we can see we have a few more m variables we need to inject we need the port of course but we also need the jwt expiration and the jwt secret so let's go ahead and provide these i'll go back to the deployment here and i'll go ahead and add these additional environment variables now importantly we don't normally want to actually explicitly provide the jwt secret or any secret sensitive information as a hard-coded environment variable here and then commit it to a git repository this is bad practice in production normally what we want to do is actually create a kubernetes secret and then we can reference that secret directly here in the environment section now i'll leave a link in the description for more on kubernetes secrets in environment variables so you can implement this yourself but for now this basic example will allow us to proceed with our deployment so our final environment variable we need now is the port so i'll go ahead and provide the port of the value of three thousand and one okay so with our three deployments running we can go ahead and actually try this application so of course make sure you have docker running on your system and once it's running we can go ahead and open up our terminal and in our helm project make sure we cd into ordering out and then we can simply run helm install the name of the application one installs in this case it'll be ordering out and then the path to the helm chart in this case it's in the relative path it's right in this directory so we'll just put a period here and then we can go ahead and deploy this application so when installing we can see we have an error here on line 16 of our off deployment so let's go ahead and check that out so helm will automatically tell us if we have any issues with our deployments so looking at line 16 we can see our indentation is off for this section here all of our container-related information should be indented one more block and we'll have to go ahead and do this same for the billing make sure the indentation is okay and again same for the orders deployment here make sure indentation lines up as so so we'll go ahead and try installing again with helm install ordering app and provide the path here we can see we have a duplicate name rabbitmq authq but that's just a warning and then our chart was successfully deployed in our default namespace so now uh making sure that our docker desktop is running with kubernetes of course we should be able to run cubectl getpods and we can see we have some new pods running with some errors being thrown most likely because we don't have mongodb and rabbit mq running so going back into our off template here we can remove this duplicate off cue because we have this specified twice and if we go ahead and take a look at our pods well we can see our auth pod is running so let's take a look at the logs here we can see we're having trouble connecting to the database and of course this makes sense because we don't have a mongodb instance running right now and so if we look at billing as well we can see we have a config validation because our rabbitmq uri isn't provided so let's go ahead and fix these errors by setting up rabbitmq and mongodb so as i specified before we're going to use third-party helm charts to implement our dependencies on mongodb and rabbitmq so i'm going to use this service called artifacthub.io where we can find install and publish kubernetes packages using helm so to see what i mean we can look up mongodb and we can see the bitnami mongodb helm chart here which is what we want to install so in here we can see all the information about this helm chart and we can also see how to install it with the command line but more so we can also see different parameters that we can override using that values.eml file we looked at earlier so we'll go ahead and override some of these values in a bit for now let's go ahead and actually include this chart in our project which is very easy to do we just need to open up the chart.yaml here let's scroll down and add a new section called dependencies inside dependencies we can list the other charts that we want to install with this chart so in this case we know we want mongodb and then we want to provide the version of the chart that we want to bring in so let's go ahead and look at the latest version we can see it's 12.1.20 so let's bring it in 12.1.20 and then we need to provide the name of the repository repository where this chart actually lives and so if we look at the repo that we're adding using the command line this is the same chart url that we want here let's copy this and paste it in here so now we have a repository for mongodb we're going to go ahead and do the same exact thing for wrap and cue we're going to use the rabbit mq bitnami chart as well so we'll do the same thing we'll call this rapidmq we'll go ahead and grab the version back in artifact hub let's look up rabbit and cue we want bitnami and we can see the latest version is 10.1.8 so let's go provide that and the repository will be the same as our mongodb coming from charged up bitnami so let's go ahead and just paste this in so now we are bringing in these charts we want to override some values like the password and the architecture for mongodb so as i said before we're going to use the values.yaml for this now if we go into the helm chart for mongodb for example we can see that in order to implement a replica set for example we need to provide that value in the values.yaml so we'll provide architecture replica set here and if we also look for root password for example we can see we need to override the auth.root password to provide the root password now as i said before when providing the gwt secret it's not great to list out the password in plain text if we want to commit this code to a repository instead we could also use auth.existing secret to use a kubernetes secret with the password now we're not going to do that just to keep things more simple but you can easily use this approach as well if you'd like to keep your helm chart a bit more secure so let's go ahead and implement these overrides so in order to specify an override for a dependent chart like this we will use the same name that we provided here so in this case it's mongodb so let's go ahead and override some mongodb values now firstly the root architecture value we can override as we saw and we can provide the replica set architecture now this is because we need a replica set running for database transactions as we've seen in the previous video and we can also provide the off section here as we saw we want auth.root to override and we'll just give this a plain text password of one two three now as i said before we can also use secrets uh to make this a bit more secure for now this will work and then we'll go ahead and do the same for wrap mq rabbitmq has a off section as well if we look at the rabbitmq bitnomi chart we can see off dot username password and we have the same pattern where we can provide a password secret as well we're going to use plain text to keep things more simple here so we'll have auth and then we'll have the username i'll give a username of user1 and a password of password123 so with this we should be able to include mongodb and rabbitmq with some overrided values here now so let's go ahead and open up the orders application to start so now that we have these dependencies part of our helm project let's go ahead and firstly we can use helm ls to view our existing deployments so let's go ahead and actually uninstall this deployment because but when we bring in mongodb and rabbit and q i want this to be on a fresh chart so i'll go ahead and make sure we use uninstall correctly here on install so ordering app is uninstalled so we do the same command we did before helm install ordering app now you should see you get an error because we have missing dependencies in our charge directory now in order to actually bring in these dependencies we specified we need to run helm dependency update and so it's going to go ahead and grab the dependencies from the charts that we specified and now once we've done this we should be able to run helm install ordering app and we've actually gone ahead and deployed this chart now and if we look we should now see our mongodb pods running as well as our rabbitmq pod now the important piece we want to look at now is to run qctl service because we need to look at the services in our cluster that will be used to communicate to these pods so in this case we want to actually use the ordering app mongodb headless service here to communicate to mongodb this service will allow us to communicate to the mongodb pod on port 27017 and for rabbitmq that chart creates a rabbitmq service for us to communicate to rabbit and q on port 5672 so let's go ahead and use this information to create some connection uris so let's open up our orders deployment and we'll firstly go ahead and add the mongodb uri and so we'll give this a value okay and the value here of course is still going to be that mongodb connection string format now we're going to provide the username and password so by default in the bitnami chart the username will be root you can override this in the values.yaml if you'd like and then the password of course we know is password123 because we overrode that with password123 now similarly this is insecure if you want to provide a secure way to inject this we can use kubernetes secrets but now we'll continue with this and so now we use the at symbol to specify the host that we want to connect to now as i said before we want to connect to the ordering app mongodb headless service so this name will always stay the same so that's why we want to copy this host here and actually use this host in our cluster to communicate and it will provide that port of 27017 so now we should be able to connect to mongodb using this connection string so now we're going to do something very similar with the rabbitmq uri so the value here will be amqp colon slash user1 which is the username we provided with password123 at now we need that service name ordering app for revenue and queue and this will be 5672. so now we have these two connection strings let's go ahead and provide them to our other services as well so we'll just simply go ahead paste these in to the auth project here and make sure our indentation lines up we can do the same thing for auth as well so now all these new environment variables have been added let's go back to our command line now we can clear out our existing output and if we don't want to uninstall our chart each time that we make changes we can run helm upgrade and then we can provide the name so ordering up and the path so now we've gone ahead and upgraded ordering out and so it will redeploy any pods that have changes detected so in this case it'll redeploy orders off and billing so after we give our application a few minutes to bring up and allow things to start up properly we should be able to look at the logs now for each of our apps so look for apps for our auth app we can see that our nest application successfully started so we're listening http okay and our nest microservice started so we were able to connect the database and our rabbitmq service which is awesome so let's go ahead and look at billing as well make sure this all looks okay that looks good and finally we'll look at our ordering app let's take a look at that looks like we've started okay which is good to see so let's go ahead and actually test our app out in postman so right now we don't have any of our applications exposed through any services we have our mongodb and rabbitmq exposed internally with through services but our actual apps themselves aren't so let's go ahead and fix that we can run cube ctl expose deployment off give it a type of node port and node port will allow us to communicate to our app outside of our cluster and so we have that type of node port which is important and then we can give the port so we know auth lives on port 3001 so we've gone ahead and exposed it so now we're going for cube ctl get service we can see we have an auth service with a node port and we want this larger port here this is the one we're going to use to communicate to it on 31378 so now let's open up postman and we should be able to run a post at localhost with that port name that we copy over and we can run a route on auth dot users to create a new user i have an email and password and if we go on hop and send this request we can see we have our user created because we've gone ahead and sent this to our node port service which will then route the request to the auth pod one of the three pods running because you remember we have three of them running so we're able to create a user and we can try even logging into our app now so we've logged in and we can get that authentication cookie that we know we get and finally we can go ahead and expose our other deployment and this will be the ordering app so let's go ahead and change the port to 3000 here and we'll expose orders so let's go ahead and qctl get the service and look at orders you can see our orders app is listening on three two three four eight let's get that port now we can send a request to create a new order and this will use the authentication cookie that we have you can see here and we're able to create a new order we can try creating a few and then we can launched a get request to look at the orders so we can see that they're persisted in our mongodb database so now at this point we've pretty much deployed our entire application using helm locally so before we set up aws eks you need to make sure you have an aws account and that your aws cli is authenticated and configured so i will go ahead and include a link to this documentation here for how to create an account and set up the cli now secondly we're going to use a tool called eksctl which is a amazing command line utility for creating and managing clusters on eks it'll simplify the whole process for us and make it extremely easy now i'll also include this link in the description to how to set up eksctl on your computer uh there's simple instructions here for how to install it so in order to move forward you should be able to run ektsctl version here and see that you have a version outputted and so we can simply run a command eksctl create cluster and i'm going to give it a name of ordering app i'm also going to specify the region here to usb1 because that's the region closest to me you can specify whichever region is closest to you so we'll go ahead and create this cluster and by default this cluster will use two middle tier m5 nodes which are relatively inexpensive and will work exactly for our deployment so this will go ahead and create a cloud formation template for provisioning all the resources we need in our cluster they'll go ahead and create a control plane node as well as two managed nodes that have all the resources we need to deploy our app and it'll automatically update our cube config for us so we can communicate with this cluster so go ahead and just let this cloud formation stack complete which may take a few minutes so in order to create a load balancer for application we're going to use a kubernetes ingress resource and take advantage of the aws load balancer controller which will automatically provision us an application load balancer which will take external http traffic and send it to our underlying kubernetes deployments for us so in order to do that firstly we're going to need some services running for the deployments that we want load balanced so let's go ahead and open up our helm chart again and in our templates folder firstly we'll create a new service for orders we'll go ahead and create a service dot email here and so this api version will be b1 kind service we'll give this a metadata and we'll call it name borders and give it a spec here so this would be a simple spec with a section for ports this port we know of course will be on three thousand the protocol here will be tcp and the target port will similarly be 3000 because that's where our app is listening so this is going to be a clustered ip service which is only usable with inside of our cluster but it's going to be required so that our ingress can communicate with it so now we need to provide the selector which tells the service where to route the traffic to so in this case we know the app will be of app orders so let's go on off and we'll create a similar service here we'll create a service.yaml and auth as well and we can go ahead and copy this service over all we have to do is go ahead and change the name here to off so go ahead and change this to off and then we'll change the port here to 3001 so now we have two services that can be used for our ingress resource so let's go ahead and actually create a new ingress.yaml we'll call this ingress.yaml and this is going to be the ingress we described which will automatically provision the load balancer for our application let's go ahead and create this ingress resource here so the api version will be networking dot k8 dot io slash v1 the kind here will be kind ingress and we'll give it some metadata now so specify the name and we can call it borders ingress and we'll call it ordering ingress and call whatever you'd like but importantly now we need to provide some annotations and so these annotations are important for the aws load balancer controller to actually pick up on this ingress resource and create an associated load balancer for us so let's go ahead and provide these annotations these two annotations here firstly specifying this is an internet facing an external traffic based ingress so we want a load balancer created for it and then we also want the target type set to ip here and if you want to learn more about these annotations uh and and how all this works i'll include a link in the description to the docs for the aws load balancer controller but out of the box this is everything we'll need to set up the load balancer and so now we can provide the actual spec here so we'll have to give the spec and ingress class name here of alb for an application load balancer and then finally we'll provide the actual rules for our ingress so we have http based rules here and we're going to have paths set up here so we're going to have a set of paths that we want to route traffic for so our first path here will be for slash orders now any traffic that comes on slash orders will specify the path type will be prefixed so that we match it exactly and then we'll provide the back end we want to route this traffic to so in this case we have a service we just created and we know that the name will be orders and of course the port will be on port 3000 and so we can go ahead and copy this block here and fill in the same exact thing for our off route so we'll give it a path here of slash off this will be path type prefix with a backend service and we know we've created this cluster ip service name off and the port is on 3001 now so now we have our two paths here to route traffic to the appropriate services and we have a load balancer that will route all this traffic for us a couple mistakes we need to correct make sure we capitalize our ingress here and then secondly make sure we actually remove this dash here from our path section and make sure we keep our indentation so we should not have a dash for that path so after our eks cluster has been created you should see that we are able to run cube ctl get nodes and we can see we have two nodes provisioned for us by eks and we can run qctl get paused to see that we have no pods currently running so the great thing about our helm installation is that helm allows us to install the same project in any kubernetes cluster so we did it locally and now we can simply do it in eks with one command so before we can actually deploy our ingress we need to make sure we have the aws load balancer controller actually set up and installed so i'll include a link in the description for these installation instructions but we'll go ahead and walk through them as well the aws load balancer controller is what is actually responsible for creating the underlying aws resources or the load balancers when we want an ingress provisioned we can see that if we go to the home page here we can see that it satisfies the kubernetes ingress resources by provisioning albs which is what will will want and it also satisfies kubernetes service resources by providing nlbs if required so we'll go ahead and back the installation instructions here and we'll walk through the instructions that it specifies so let's scroll down the first instruction here and we'll copy this command where we create a im oidc provider let's go ahead and copy this command to our clipboard paste it in here and we just need to go and change our cluster name so in our case we'll change the cluster to ordering app and we'll go ahead and change our region to the region where we created our cluster so in this case for me this was us east one and we'll go ahead and create this provider so after that provider was created go to the second step and it says we need to download the i am policy for the controller so let's go ahead and download that policy and then we'll copy the third command here we create the i am policy let's go ahead and create that we have the name and the policy document file so we'll go ahead and run this command and you can see i have an error occurring because this policy already exists and that's because i've already done this step so that's okay just make sure you've run it and created this policy at least once and lastly we'll go ahead and create the i am role and service account for the load balancer controller so go ahead and copy this and we can go ahead and paste this command in so you'll have to include your region again so in my case this is us east1 i'll leave all the existing flags here and then you're going to have to provide your aws account id now this account id should be returned when you have created that previous step so go ahead and copy that id from here and paste it in now if you're missing this id you can simply get it by logging into your aws account so if you need to obtain your id you can log into the aws console and then click on your username here and your id will be populated in this drop down so go ahead and provide your aws account id here and then lastly you'll have to provide the cluster that we are applying this to so in this case this will be ordering app and with that go ahead and complete this command so after you've gone ahead and created that service account you should see a successful response and then we can go down to actually adding the controller to our cluster so these commands are quite simple we'll have to go ahead and add the repo here using helm so let's go ahead and add the repo you can see i already have it so it's going to skip it that's fine so go ahead and add that repo we can skip this step here because we're going to run helm install so we're going to go ahead and copy this third command here where we install the load balancer controller and so we'll go ahead and provide the name of the cluster that we want to apply this to and you can also see it's going to install it to the cube system namespace so we'll provide the name here to ordering app so after installing you should see that it installed successfully and then we can run cube ctl get pods under the cube system and we should see that we have an aws load balancer controller two of them running here in our cluster and so now we should be able to run helm install ordering app at the root directory and make sure we spell install correctly here so it might take a couple minutes for it to install properly but after it's deployed we should be able to run cube ctl get pods and we can see our application workload starting out and then if we run cube ctl get ingress we can see our ordering ingress here with a class of alb and we can see we have a kubernetes load balancer address that has automatically been created for us if we open up in postman we should be able to type in this address here so http colon slash and then we can run slash orders to start to see if we have any orders in our system now we have some issue connecting to this load balancer and that's because it can take a few minutes after our load balancer is created for the dns resolution to take place and for our requests to complete so let's wait a few minutes until this is finished populating okay so i've waited a few minutes for our load balancer dns resolution to occur and now we can send a request to get an empty array of orders because we have none in our app so let's go ahead and launch a request to slash off and if you remember the load balancer ingress will direct the traffic to the correct pod and we can create a new user here so let's go ahead and copy our post request from our localhost and provide it here so we'll send a user in and of course make sure we change our request here to post so we'll go ahead and post a new user and we get that new user created we can also go ahead and now launch a login request so we get that http cookie so we send a login request and we got that off cookie which is good and so now let's change the route here to slash orders we have slash orders here and we'll change the body now to a new order go ahead and provide a new order here and we'll go ahead and launch a few orders to be created now let's go ahead and query the orders in our system we can see we get back an array of orders this has been a quick example of how to deploy an sjs microservice application to amazon eks we can see all of our pods running successfully inside of our application here and we also should be able to see if we actually look at our logs for our application we get different billing requests coming in so we can see our application is correctly tied in together so if you'd like to see more videos in the future about eks deployment and sgs and microservices make sure you subscribe and stay tuned thanks for watching and i'll see you in the next one
Info
Channel: Michael Guay
Views: 8,867
Rating: undefined out of 5
Keywords:
Id: heQbbrSu8LM
Channel Id: undefined
Length: 40min 3sec (2403 seconds)
Published: Mon Jun 27 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.