Simplify Kubernetes YAML with Kustomize

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what is up youtube and welcome to another video if you're totally new to kubernetes or you've worked with kubernetes before you would have come across kubernetes yaml files now to interact with kubernetes we use yaml files there are multiple different ways with dealing with yaml files and complicated ways such as helm charts in this video we're going to be taking a look at a much simpler approach for bundling simple kubernetes yaml files with a tool called customize so without further ado let's go [Music] so kubernetes allows us to describe our infrastructure and our application as yaml files so if we take a look at the docker development youtube series i have a complete guide on kubernetes development if you're new to kubernetes please check the links down below to the kubernetes guide basically we cover everything in kubernetes such as deployments config maps ingresses secrets services stateful sets and even persistent volumes now if you're new to this channel everything i do is on github the source code is down below i've put a link in the description so you can follow along the first thing we're going to do is take a look at the readme file in the customize folder under the kubernetes folder this has all the steps that i'm about to showcase today so the first thing we're going to do is take a look at the traditional way of applying yaml objects to kubernetes and then we're going to take a look at what customize does to help us improve this process so if we take a look at the very basic way we normally use the cube ctrl apply command to deal with yaml files so in the basics here i have a couple of yaml files i want to deploy i have a namespace a config map a deployment and a service and if we take a look at the customize folder i created this basic application folder so this is the very basic traditional way of applying objects and deploying them to kubernetes so the first thing we're going to take a look at is the namespace namespaces are very simple they just have a name now namespaces allows us to group objects together it's a great way for your company to split out different applications between different departments as well as separating infrastructure such as monitoring components logging components or maybe even your ingress controllers so we take this command and we run that we say cube ctl apply that's going to go ahead and create the example namespace now our application is going to need some config in order to function so for that i have a config map if we take a look at that a config map is just a configuration file that your application might need so to deploy that i'm going to say cube ctl apply and i'm going to apply that config map to the cluster then we're also going to take a look at a deployment now deployment is a way for us to describe our application to kubernetes so kubernetes knows how to deploy and manage our application to keep it up and running so for that i have a deployment file we say created also in the example namespace we want to run two replicas we're running an example python application and we give it a port and we also mount in our config you can see here and to deploy that we're simply going to say cube ctl apply and we're going to apply that deployment file that's going to go ahead and deploy that guy into our example namespace which is going to give us two example app pods now to expose this application inside of kubernetes we're going to create a service a service is a way to expose applications in your cluster either privately or via a load balancer so if we take a look at the service.yaml we can see we're creating an example service in the example namespace and we're creating a type load balancer so that means because kubernetes is cloud native kubernetes knows how to provision load balances wherever it's running so i'm running docker for desktop here meaning that it's going to create a virtual load balancer so i can access my application over localhost so to deploy that we're going to take a look at the readme file and we're going to grab the yaml file and we're just going to go ahead and apply the service now there's another way we can apply this if we take a look at the cubect ctrl apply command it basically takes a file as we've noticed here but we can also apply an entire folder so sometimes this is good enough to say let's just apply the entire folder and that folder becomes our package or our chart or our template or whatever we want to call it for some people this is good enough if you don't need any kind of complicated um templating and parameter injection you can just happily take a file yaml file or a folder and just apply it to deploy your infrastructure so to check what we've deployed we can just say cubectl in the example namespace getpods we see we have two pods running and if i do cubectl getservice we can see we have our service running it's exposed over a load balancer and if we take a look at the browser we can see that we have our application now running in kubernetes now in all my videos where i deploy things like hashicorp vault argo cd and jenkins you see me just basically apply a yaml folder by saying cubect i'll apply f that is because it's easy to digest easy to read easy to follow and understand now many people ask me why don't you use helm charts and to be honest in all my experience with kubernetes you don't need complex abstractions complex template rendering complicated nested templates and all of that complexity it just makes it much harder for people to understand read and follow and digest it it also makes it much harder to upgrade and maintain your systems in many of my scenarios i would much rather copy paste yaml than trying to make a super generic template that's going to be hard to maintain hard to understand and hard to upgrade a lot of the times when i do ci cd pipelines you see me do something very basic where i say cat a deployment file pipe it into said i replace the image tag and then i pipe it into cube ctrl apply that is because simple applications like microservices don't need complicated template and rendering especially when you're only wanting to replace an image tag when you're doing deployments in a ci cd environment so i always recommend to try and stick to the very basics just use cube ctl where possible if you do need something more complicated then move on to something like customize and if all else fails then look at more complicated template rendering engines and try to keep your yaml files and folder structures flat and simple so customize introduces a template-free way to customize our application configuration file so we can take our deployment yaml that we have and we can keep it untouched and then what we can do is we can introduce little patches like patches for development staging and production and then apply that with a tool called customize and deploy that to our kubernetes environment so i'm going to show you how we can keep these yaml files intact and unchanged and just apply the necessary changes that we need for development staging and production environments so to start with customize we need a customization yaml file that describes what we want our bundle to look like so to do that in our customize folder we're going to create a customization.yaml file and it's very very straightforward to start we just say we want the resources and we list the resources we want to include in our bundle so i'm going to include all the yaml files that we have in this application folder over here now since a specific version of kubernetes the customized binary has been included in cubectl which makes it really easy to use so if we take a look and the way we can do it is we can say cube ctl customize and then pass in the name of the folder that we want to customize basically or we can say cubect i'll apply minus k that's basically going to run the customize build process on that folder produce the yaml and then apply it so we can say cube ctl apply dash k and pass in that folder and when i do that we can see we've created the namespace the config map the service and the deployment so we've done exactly the same thing as cube i'll apply but this time we've just used customize to do so now how do we do something a little bit more complicated like let's say we want to run two pods in development environment but we want maybe four or six pods running in production for that we use a thing called overlays so if we take a look at what overlays are we would basically take all those resources we have and that would become our base and then what we do is we introduce an overlay for dev and an overlay for production so when we apply our customized file we say we want to use development and then it will apply it to the development environment and if we use production overlay it will print it will patch in the production patches so to do that what we're going to do is move our customization yaml into the application folder i'm going to go ahead and do that and then obviously we have to change the paths so what i'm going to do is just remove the application folder from here and now we've basically turned this application folder into our base so it has a customization file and now what we need to do is introduce our overlays so what we can do now i'm just going to call it environments but you can call it anything you want since i'm going to be having two different environments in here i'd like to call it environment so it makes sense and then what i'm going to do is i'm going to create a folder i'm inside here called development and production so you can see now i have a development folder and a production folder and now we can put new customized templates inside these ones and define what we want to change on the base template so to define our overlays what i'm going to do is create a new file inside the development folder called customization.yaml and i'm going to do the same thing for the production folder so we create two customization overlays now inside the customization yaml for development i'm just going to specify what base i want to use so you can see here we're pointing to the folders up which are our application customize file and then same thing for the production i'm also going to take this base and i'm going to go ahead and paste that there so basically all we're doing now is we've specified a development and production overlay for our base customize so now to apply that all i need to do is say cube ctrl apply dash k and i can apply my development customized template and when i do so all that that's going to do is going to look at the base and it's going to apply it so how do we make changes to our development environment and production environment so let's say we want to run more pods in our development environment so if we take a look at the base application deployment yaml we can see that the replica specified here is two so let's say in development we want to run four pods what we will do then is we'll go to the customization yaml here and we're going to firstly add a new file called replicacount.yml and then what i can do inside that replica count file i can apply the patches that i want to apply so any kind of change i want to make i can apply it here so in this case we tell customize we want to make a change to the name example deploy so it will have to match the name in this deployment yaml and then we say we want reflectors for then we also need to go and tell customize about this replica account file and we do that by going into customization.yeah and we add a thing called patches so we have add a patch to point to the replica account.yaml so now customizable node to apply this patch to the original base template so now if i go ahead and apply that template we can see that our deployment has been configured and if i do cube ctl get pods i can see we're now running four replicas now let's say in production i want to run six pods so for that i go to the production folder i create a new file called replica count.yaml and then inside that replica account i just say i want six replicas for the production template and then what i do go to my customization.yaml and i'm gonna go ahead and add the replica account for that one and then if i go ahead and say cubect i'll apply and i apply the production customized build this time and we can see now we have applied it to the deployment yaml and if i do that we can see now we've got six replicas coming up the other thing i may want to do is say let's put some resource limits in production that's not in development so for that i might want to create a new file called resource limit and then in this file i can go ahead and say i want to apply resource limits to the specific container so i'm going to go ahead and save that and then i'm going to go to the customization yaml file and i'm just going to introduce this extra file that we've created in here and then what i'm going to do is say cube ct i'll apply minus k and go ahead and apply that limit restriction so you can see that overlays are a great way to patch existing yaml without having to change that base yaml now there is still one problem with our base template if we take a look at our application yaml and we take a look at the config map we can see that we still have a config json that's tied to our development environment so ideally we want every environment to have its own config now customize has the ability to generate configs and from files which is pretty pretty awesome so to do that what we're going to do is we're going to go to our production environment and we're going to add a new folder called config so we have a configs folder and then in here i'm going to create a config.json and in this config.json i'm going to say environment equals prod now how do we get customized to use this config that's very simple so we just go to our production customization.yaml file and then we add this thing called a config map generator so we tell customize to target the example config and then also in the namespace example and the behavior is to replace that config with config json file that we've defined in this folder so this is a great way for customize to be able to change configs for different environments so to apply that i just say cubect i'll apply dash k and i apply the file and now we can see that it's gone and configured our config map now if we want to take a look at that config map we can say cubectl getcm we can take the name and then we can specify the name and i can say output it as yaml and if we do that we can see it's taken effect so it's gone ahead and replaced that config map in our kubernetes environment now the customize tool has a lot more in-depth and advanced config generators and which applies to secrets as well so if you want to take a look at more advanced examples you can come over to this document over here where they take a look at a lot more advanced techniques and things you can do now what if we want to inject some environment variables to our pods in our deployment customize also has this capability to do strategic patch merging for that let's say i want to add some environment variables what i can do is i can go to my production customize base and i can say add a new environment.yeah and then in this yaml i can specify exactly what environment variables i want to add so in this case i want to untarget the container called exampleapp and i want to add an environment variable called production and you can do the same thing for referencing config maps and secrets as well then to make that take effect we're going to go to our customization.yaml file and we're going to go ahead and add that that's going to tell customize to do a strategic merge into the base deployment so if it's there it will update it and if the value is not there it'll go ahead and add it which is quite cool feature so that's a good way for patching and merging values into our base templates without having to change the original yaml file a lot of the times we we are not able to change the original yaml file because they might be coming from other vendors so to do this now to apply that patch i'm just going to say cube ctl apply dash k and i'm going to go ahead and apply that to the production and we can see now deployments has been taken effect so to take a look at that i can say cube ctrl git deploy and then i can go ahead and grab that deployment and say type output as yaml and if we scroll up we should be able to see that it's gone ahead and injected that environment variable into our deployment now another cool feature that customize allows us to do is let's say we have a deployment pipeline and all we want to do is change the tag of the image to our deployment yaml and we don't want to go and change the original deployment yaml so if we take a look at the base application deployment gamma we can see we're running python an application version 1.0.0 now we don't want to change this original yaml so that is where customize allows us to patch that using the images field so to do that all i need to do is go to my customization let's say we want to roll out a new version to production we go to our customization yaml file and we add the images field and now we can say we want to target the specific image in our deployment so if you have multiple deployments with multiple containers you can target specific ones using this and we say here that we want to apply a new tag with 1.0.1 so to apply that all i need to do is say cube ctl apply dash k and that'll go ahead and roll out the new deployment if we say cube ctl get deploy and we output that as yaml we can scroll up and we can see we've rolled out python 1.0.1 so this allows you to use customize in your ci cd pipeline and just change your tags to do rolling deployments now it's important to understand the default behavior when it comes to kubernetes and config maps when a deployment consumes a config map the pods that are associated with that deployment will only consume the config map at the time the pod is created that means if someone goes later down the track and changes the config map the pods that are still running will not pick up that new config map until the pods are deleted and recreated so the same thing happens to customize so if you take a look at our base template we have a config map.yaml and we're targeting an example config in our customization yaml for production we only override the config from a from basically from a config map generator here but because we're targeting an existing config in the base application that means customize is not going to manage that configuration so if we do cube ctl get pods we can see our pods were created four minutes ago and if i go to this config in production and i add let's say i add a new value called hello and and let's say i go and apply that we can see that the config map was configured but if we take a look at the pods the pods are still running the same pods are still running so they haven't been recreated automatically so how do we get customized to manage our config maps so if we want pods to consume new config every time we recreate the config map or change the config map we're going to need to use the auto rollout feature of the config map generator so to do that what we're going to need to do is we're firstly going to need to go to our base application config map and we're going to have to remove that config map altogether because we want customize to generate and manage our config map instead so we do that then we go to the production customize.yaml file and we remove the behavior of replacing configmap because we're not targeting an original config map anymore we want customize to generate a config map on the fly using our configmap generator that we've defined here so now if i say ctl apply and i go ahead and apply that look what happens customize will go and create a config map with a random hash behind it it'll also mount that config map into the deployment if i do cube ctrl get pod we can see that a new pod has just been created okay so if i go to my config now and i change this value to a new value and i go ahead and save that and i go ahead now and and apply that using customize apply we can now see that we've created a new config map so every time we make changes to the config map customize will regenerate a new config map and it will go ahead and volume mount that into our deployment so you can see a new config map was created and also a new deployment was configured so to double check that we can say cube ctl get deploy and we can output that as yaml and if we take a look at the config map mounts we can see that it's now mounting a volume to the auto config map so this is a great way for ci cd pipelines to automatically ingest configs every time they change the developer doesn't have to go and restart the pods manually so these are the most useful features i've found of the customized tool allowing you to keep your yaml files very simple and give you the flexibility of applying patches to different environments making your yaml files portable without the complexity now this will give you similar features to tools like helm without the unnecessary complexity remember that templating can often become really complex and is often not required so i hope this video was informative and useful and let me know down below in the comments about your yaml experience and also what sort of topics you'd like me to cover in a future video and as always like and subscribe and until next time [Music] peace you
Info
Channel: That DevOps Guy
Views: 67,046
Rating: undefined out of 5
Keywords: kubernetes, devops, kubectl, yaml, k8s, linux, docker, ci, cd, cicd, pipelines, deployments, kustomize, developer
Id: 5gsHYdiD6v8
Channel Id: undefined
Length: 20min 36sec (1236 seconds)
Published: Sun Jul 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.