Transcript
This transcript was autogenerated. To make changes, submit a PR.
Jamaica real
time feedback into the behavior of your distributed systems
and observing changes, questions,
errors in real time allows you to not only experiment with
confidence, but respond instantly to get
things working again.
Code hi
everyone, my name is Robert. I'm a senior
solutions architect AWS, and today I
want to show you an alternative way to manage your Kubernetes
manifests. And that is, instead of being
a YAML engineer, you can be a software engineer
by writing real code with the help of the cloud
development kit for Kubernetes called cdks.
So what is the cdks? Let's jump
into it. The CDK for Kubernetes,
it's an open source software development framework
where you can use multiple general purpose languages
and the ones that are supported you can see at the bottom.
And with those you will model your Kubernetes
resources as reusable components with real code.
And for that you can use Python,
JavaScript, typeScript, Java and go
now the benefit you gain here is of course that
now that you're not writing YAmL or config files
anymore, but instead real code, you can use
familiar programming languages and techniques.
One of the things you gain, of course, is that you can
use software engineering best practices like do not repeat yourself
and you can refactor stuff. And it also makes it
easier for you to share things, because now your Kubernetes
manifests are actually a package of
your favorite language. It's not anymore just a bunch
of YAML files, but it could be a Python package or a typescript
module. Finally, you can use
cdks everywhere, so it's not something that
only works in the cloud. In the end, cdks is
a kind of config generator, so it will
put out some standard Kubernetes YAMl for
your deployments, but you don't have to write it yourself.
That's something that SDK does for you. And then
you can take those YAML files and insert
them into any existing process. You have to actually
deploy your Kubernetes manifests.
Now when talking about YAmL, you know it's a configuration
language. And I know some engineers
who swear that Yaml stands for yelling at my laptop.
And there are some good reasons now to use
something else instead of Yaml to configure or to define
your deployments. And we will look at some of
the reasons why it's hard to engineer in Yaml.
So let's have a look. Let's engineer some
yaml to get back into the
experience of how it feels to be in Yaml.
Engineer for this example, we're doing
something very simple, which is just an HTTP
echo server. So we want to go to our Kubernetes cluster
and deploy a simple container that just echoes
back what we sent to it. And we also want to
expose that container to the world through an ingress.
So just really standard stuff. So what do we
have to do here? Well, first of all, we have
to define a deployment, right? So that's the basic
object that we know from Kubernetes that helps us to create
something that is a highly available container
application. And with that we have to define
a lot of values, for example,
labels, ports and so on.
Now this only makes running the container on
Kubernetes possible, nothing else. So what we also
need is we need to define a service and the service makes
it so that these containers actually have a single common
ip address within the cluster where you can reach all of them.
And the service is already kind of load balancing between
those containers. So if one of them crashes, we can still reach the
service. If we deployed multiple
containers of that now it's still not available in
the world, we still have to create an ingress
for that. And the ingress in the end is pointing to the service saying
okay, now I actually want to expose that. And we
want to expose this under a HTTP path
called hello. And these are the three ingredients
we need for our little application.
Now if we look at the various things we did here,
we immediately spot that there's a lot of repetition going on,
right? So a lot of the time when you're working with
Kubernetes, you need to take care of labels and you
have to make sure that the labels are the same between different
objects because they reference each other through
those labels. So here we can see that we have quite a lot of repetition
with this app echo label because the deployment needs it to
actually find the containers and the service needs it as well to
find the containers. Besides that,
we also have some repetition of values like the
port. So we defined a port initially for the application
in the deployment, but then we also have to tell the
service that we need the same port so that
it is actually reaching the application that is running in the
container. And again we have another
mentioning of the same port or a similar port
where you need to tell the ingress that yes, this is the port number
where actually the service is listening so that it then can forward
the request to the container. So we already
see that we have a lot of repetition here, this is definitely not
dry. And the question is, is there a better way to
do it. Finally, we also
see that we have to do one of the hardest things in
software engineering or any kind of engineering, which is
naming things. So we have to think about the
name for the service here. And again, we have to repeat the same
name exactly for the ingress so that the ingress is actually pointing to
that specific service. In total,
we got 45 lines of Yaml here,
and this is something we had to write on our own.
So to sum it up, the downsides of Yaml
are, well, it's a static configuration language.
You don't have a lot of tools
to do things like conditionals, variables and tools.
It promotes a lot of copy paste. That's what we saw in our example.
So that makes it very error prone and difficult to
change. It's also hard to customize and share.
So there's no native method to actually put in variables
or inputs to change the template. And there's no
Yaml package manager. So you need to find your own way to actually
share those manifests, maybe in your company or publicly.
In addition, as we've seen, it's not just about Yaml,
it's also about Kubernetes having a lot of dials
and knobs. So these manifests actually carry a fairly
high cognitive load because you have to make
so many settings for the properties and make sure that they
match exactly, so that actually the whole thing
works. Now how can CDKs help
you there? The motivation of CDKs is
that as we just saw, authoring Kubernetes manifests can
be a rather complicated tasks. And CDKs
makes this easier. And this is
really what cdks wants to do at the core, making,
creating those manifests, authoring those manifests simpler
and more robust for you. And what does it
leverage to do that? Well, it leverages general purpose languages,
and by using general purpose languages you
can actually employ best practices of
software engineering. Now what are the benefits
of general purpose programming languages in comparison
to something like Yaml? Well, of course they're dynamic.
So you have multiple ways to do control flows.
You can iterate over stuff, you can apply things
like do not repeat yourself because you can pull but common
values that you reuse. You can refactor your
code to take, but repetitive
code that you use multiple times.
And typically you also have a standard package manager.
So you can have your Kubernetes manifests
distributed as a Python package or as a node
module. That's possible. And finally,
because now we're actually using programming languages, we can
build abstractions so we can remove some of that cognitive
load that we saw, some of that repetition which is needed
for kubernetes to work, but is actually not
really important for you in your day to day work because
they are just best practices and standard
ways of wiring things up that you do not want to
think about. Now let's jump into how
you can actually work with cdks.
First of all, you need the CDKs CLI,
and there are multiple ways to install that CLi, but one
of the easiest ones is just to do NPM install minus G
and referencing the CDK's minus CLI.
You also find other ways to do it, like with Brew,
and you can read all about it on the project website, which is Cdkates
IO. Now once you did that,
the next step is to actually initialize your project.
So there's a built in command that helps you to scaffold
an application skeleton in the language of your choice.
So if for example, you're like me,
you would go with cdks in a typescript app. And that would
give you the skeleton of a typescript app
where you can define your manifests in typescript.
And this is what you get when you execute
that command. After that you need
to import API objects.
So this is an important step because as
you know, Kubernetes has a lot of versions and each of
those versions has different API objects. Some of
them graduate between being beta to being
stable. And you need to let your project
know against which Kubernetes version you are actually working.
That's not something that is specific to cdks.
That's a challenge you basically have with any tool.
And with the fact that Kubernetes gets new updates like
every 3 hours, it feels like. So this
is something you have to deal with anyway. The way you do this
is you're using the import command so you can do CDK's
import and then reference the version of Kubernetes
that you want to work against. A very cool trick here is
as you see, that you can also reference
custom resource definitions. So another
way to use CDKs is to not only
work with the standard objects of kubernetes,
but also if you have any operators that expose any
custom resources to your cluster, which you
certainly have, you can give CDKs the
YAml file of those definitions and then CDKs
will create classes out of that, and those classes
will help you to actually instantiate those custom resources
as well in your code.
The next step you have to do after that is
actually coding what you want to deploy.
So this is where you're using the various classes
that ckates gives you to create
the manifests or the configurations you want to
have in your cluster. And in a minute we will jump into
how that feels like when you're actually using general purpose
programming languages to define your Kubernetes objects.
So getting started here,
for me it's visual studio code, but it would work in basically
any ide that you like.
When I start writing my deployment, I can see
that now for each of those Kubernetes
objects, like the deployment object, I also have a corresponding
class provided by cdks. And here it's the Kube
deployment. And this is a one to
one representation of the deployment
specification from the standard Kubernetes API.
But the benefit I get here already, as you can see, is as I'm
writing the configuration for that deployment, I get
a lot of autocompletion hints from my idE,
and that's possible out of the box obviously,
because now your Kubernetes API is just
a code library. So your ide will look at that library
and tell you what kind of properties are there. And if I
go further and start writing out those properties,
I can also see inline documentation here. So instead
of going to another website and reading on the properties,
I can read about what those properties are doing right
in my ide. So that is already a
pretty big boost to my productivity. Now let's
see how the echo server actually looks like with
cdks. And we're using typescript here because I'm a typescript guy.
So the first thing is that we are
writing that deployment class. We are configuring,
instantiating that deployment class. And you
see here, it looks rather similar to
what we did before with yaml, but now it's in code.
And again we need a deployment.
Of course we need the service. We have seen that
before as well because the service will then load balance between
the containers of my deployment. And finally we
need the ingress as well. So far no surprises,
but we already benefit because we have written code and
for writing all these properties we would have gotten
autocompletion and also inline documentation.
Now where we see some direct benefits is
with that point of being dry. So instead of
repeating the port number multiple times, we can
now pull it out into a variable and then basically reference
it anywhere in our application.
And also for the labels that we had to repeat before now
we can also just define them once and then basically
have them here defined
or repeated automatically differences anywhere
we need them. So that already makes it easier.
And we have removed a lot of repetition from before.
Another thing that's cool is that
there's already some built in convenience even into
those basic classes that we have here. So here
we can see that we actually don't have to think about the naming
like we had to think about before when we were defining YAml on
our own. So here we're just instantiating the service.
And to reference the service in the ingress,
we just have a handy property here service name
which we can use for that name. And we don't have to think about how
this is actually created. Cdks will
do that for me. It will make sure that it's a
unique name, so there's no collision. And I just have
one less thing to think about when I'm making that configuration.
Now that we've written our Kubernetes
manifest in a programming language, the next
thing we can do is actually synthesize it. And for that cdks
has a command called Synth. And what this command will do is
it will take that code, run it and create
standard vanilla Kubernetes manifests in Yaml out
of that. So the way this then looks like
is that in the disk folder of your
project you will find those manifests as YAML
files. And to make it super easy,
you can just take those YAMl files,
give them to Kubectl apply and it will deploy that stuff
in your cluster. At that point there's no dependency anymore
on cdks. You just have a vanilla YAMl file, you can take
it answers, you can check and lint it with standard
tools you have for Kubernetes manifest files.
There's nothing special about these files anymore. It doesn't matter that
CDK's created. And of course
if you have any other tools or processes where
you basically drop in your YAMl files, you can reuse
all those processes. So if you have some git ops process where the YAML
file is taken and applied to your Kubernetes cluster
with a kind of control loop to continuously make sure that
this is the Yaml file that is applied, you can do all of that
because CDK is not involved here anymore,
you just have a standard Kubernetes manifest.
Now once you did that, you might have the idea that
what you build is pretty cool and it's actually something that could be
reusable for the whole world or maybe just for your team
or for your company. So you could
publish this as a code package. And of
course that depends on which language you chose. So for example
for typescript you might have an internal or external
node package manager registry. And you could now
create a package out of what you just did, publish that
package and make it available for others to use. So that's
a great way to actually make
your work reusable and share it with others
so that they can benefit as well. And this is just
some pseudo code, fake code. But you could imagine
that you created a library called my team constructs
and you would share this for example internally through your package
registry. And then somebody else could use
your echo server deployment that you have just built and they could
just instantiate that and have this standard echo
server maybe for debugging. Now we saw
some benefits already by using a programming
language, but we can go even further. So let me
introduce you to Cdkates plus,
which is an extension to the basic cdkates library.
To explain what cdks does. We have to
talk about construct levels. So constructs
are what we are calling those classes. You have
seen that you instantiate and that represent
the real deployment objects or the real API objects.
And we think about levels when talking about
constructs. And the level defines the sophistication
of those constructs. So basically how much
they do for you or how smart they are.
At the lowest level, level zero,
we have the common functionality of the Kubernetes
API objects. So this is a very bare bones representation
of the normal API objects of Kubernetes.
If we go one level up, we have those classes
that we already use like Kube deployment, Kube service, Kube ingress.
Those are automatically generated. They already give you some
convenience, like the name generation I mentioned. But mostly
they are still representing the base API
from kubernetes. Now where it gets really
interesting, and this is where cdkates plus
comes into play, is with a level two.
So cdks
plus exposes a number of high level
handcrafted APIs that make it even easier
to create and wire up multiple
Kubernetes objects that you need to actually get can application
running. So to give you a real
example of how that looks like, let's take the same
Echo server we built with CDKs before and now
build it with CDKS plus.
What we can see here is that the whole example became
much more concise. We are still defining
the port. Of course we have to, that's up to our application.
We create a deployment again,
but this time it's a k plus.
So a cdks plus deployment. So it's a different class,
it's the high level variant of the deployment.
And here we can already see that we have to define
a lot less properties to make the deployment
work. So actually we mostly
just have to define the minimum needed
information about the container we want to run in our deployment,
which might be the image and the arguments,
and the port that is exposed and nothing
else. And then to actually expose it
via an ingress, there's a nice helper function called expose
via ingress. And there we just pass the path
we want to use for that, and the
type we want to use for that ingress, which is prefix in
that case, meaning everything after hello is basically passed to
the container. Now we see here that, for example,
we do not have to create a service object,
and we do not have to create the ingress object on our
own. This is basically all done by this smart
deployment object, by calling expose via ingress.
So this is why this code is much more
concise than what we did before. Actually, we have just
13 lines of code here. And before we had something like 45
lines of code. So already by a factor
of three, we reduced the amount of code we
had to write. And because we have less code
and questions that speak to us,
it's actually easier for us to declare our intent
and to write code for humans and not machines.
So if I look at that, it's much more clearer for me
what the person, and that might be me. If I look at
that maybe a year later,
it's much more clear for me as a person what
actually was the intent of that code and what that deployment should
do. And if we stick to that for just a
minute, I think this is a nice segue
to clean code, where you can say
that if you've read the book,
or if you know that there's this clean code book from Robert C.
Martin and other authors, where they basically say,
well, ideally we want to write clean code
and can important property of clean code is actually that
it can be easily understood by everyone on the team.
I find it's a really interesting aspect that
we can try to achieve here with CDKs or CDKs
plus. So by now having the ability
to change the way we write
our deployments, by using code, we can make the
code more readable and write it in a way that
it clarifies what we actually want to achieve,
so that it's easy to understand by other team members and
to really drive home. What I meant here is if we
again look at that example of CDKS plus and what
it does, we can see that now
it's much easier to tell a story, right, because we created a deployment,
and then we call deployment expose via ingress.
So the story is much clearer. I want to create a deployment
and I want to expose it via ingress.
Now, what's actually happening in the background? Let's look
a little bit at what cdkates is doing for us here.
So taking that code,
CDKates is creating the Kubernetes
Yaml manifest. And what it of course does,
it creates the deployment. In the deployment it has
to reference that port value that we set.
Then it also has to create labels
so that those labels point to the ports and the deployment
actually knows what ports belong
to that deployment. And cdks does
that for you. You don't see any labels here, right? This is happening
in the background. So it's taking all that cognitive load of thinking
about a label and making sure that you copy paste the right label
between multiple objects. And then we
have to create the ingress. Or we would have, but in this case cdks
is also doing that for us, right? We don't see that
here anywhere. And again this ingress
has to reference a port. Typically it can be
the same port and then
you also have to create that service. Except again
we don't have to do that. You don't see the service here anywhere.
This nice helper function is doing that for you in
the background. And here again you have
to think about naming the ingress must reference the name of the
service. This is all done for you behind the covers.
Again the service has to reference the same port or
another port potentially.
And again the service needs labels because
also the service uses labels to actually figure out which
ports shall being to the service and shall get requests
that are coming in. And there you
see that this whole graph is already getting
a little bit complicated for such a simple application.
But you don't have to think about that. You wrote your story
in CDK's plus and under the hood.
CDK's created and wired all those resources
for you and took care of boring technical
details that you just have to get right, but actually do
not really give you something new or cool. It just has
to be done and you can stick to your much more
concise story of what you wanted to achieve.
Summing up here are some reasons why
I think you should code your infrastructure.
So what are you gaining by using cdks or similar frameworks?
Well, instead of using YamL or some other configuration language,
you are using a familiar programming language of your choice. And that
could be Javascript, typescript, Python,
Java or even Golang. That's up to you.
With that you get great ide and tool support, because now your
deployments are just code, there's nothing special about them.
And all the cool features that you have in your ide for
refactoring, autocompletion,
inline documentation just work out of the box.
Going further, we just saw that with cdks plus you
also get powerful abstractions to have a more concise
configuration and also have the ability
to tell a story that's much clearer to your teammates.
And of course all of that is wrapped in the opportunity to
use software engineering best practices
and exercising clean code.
Now, are there reasons to not code your infrastructure
to not use cdks? Well, yes, of course. So if
you are feeling very comfortable with your current tools and your workflows,
of course you don't have to change. The cool thing about cdks
is that of course you can mix and match. You saw that cdks
in the end just creates vanilla Kubernetes manifests.
So you could have mixed workflows
where you actually can use,
for example, your existing tools, but also create part of the
application with cdks and then just merge
those YAML files together, deploy them together.
If you don't like coding, that might also be
a reason, and I think it's a fair reason because
code means abstraction, and abstractions are nice when they work
and you really hate them when they do not work. But that's
kind of part of the course for using
programming languages. So either
you like it and you know how to deal with it,
or you don't like it, and then of course you can stick to writing YamL
or some other configuration language.
Finally, if you are an author of an helm chart and you're wondering, can I
use this to actually author the helm chart? So create the guts,
the internals of the helm chart. This is not supported.
You can deploy Helm charts, so you can interact with helm
charts as an end user in your cluster, but you cannot
author the helm charts. Finally, I want to
leave you here with some resources on how you can get started
with cdks if you want to. So for
example, a good place to start is of course the project website
cdks IO. There you find the documentation
and also some instructions on how to install the stuff.
A very cool resource is also the constructs
hub that you can find under constructs dev.
And this is basically a place where you can search for community
created constructs. So basically libraries
from other people where they already packaged up
some cool constructs and
classes that do certain things for you.
So for example, you could find maybe something like the
Echo server we just built there as a premade
package and then you could import it to your own project and
use it. And do not repeat the same work that other people
did. Also, there are multiple
ways to interact with the community. So CDks
is a CNCF sandbox project and you can read
all about that on the CNCF website.
We also have a slack under CDK dev.
And finally, there's also the CDK day,
which is a community event. So that's not basically
managed by AWS, but really from the open source community
where you can learn all about the whole CDKs
ecosystem. So CDks is not the only tool
in the CDK ecosystem. There are cloud
development kits for AWS and for terraform
and some other cool tools that help you to actually build
cloud infrastructure with real code. And on
the CDK day the community is celebrating these advancements
and you can learn about all the cool stuff you can do in that space.
So with that, I hope you really liked the
idea of using programming languages to
define your Kubernetes deployments.
Let me know if this is something that's interesting for you.
Let me know what experience you
had with that when you tried it out. You can reach me on Twitter and
you can find me on LinkedIn and I would be super thrilled
to learn about your experience there. Thanks a lot and
have a great day.