CARTER MORGAN: And now we put it all together.
If you missed the last four episodes, check them out.
Link below.
But for those of you who haven't, let's
check out how to get started with Kubernetes.
[VIDEO PLAYBACK]
- With a whole universe of things to learn,
it's important to start with the essentials.
Let's go over the concepts that make
Kubernetes usable, scalable, and just downright awesome.
Are you ready?
[PLAYBACK ENDS]
CARTER MORGAN: Hey, guys.
Thanks for joining me on this culminating video.
Before we talked about containers
and some other things, but it was mostly theoretical.
It would be great to see an example in action.
What do you think?
KASLIN FIELDS: Yeah, sounds good to me.
You remember in the last episodes
how we talked about containers and deploying those containers
onto Kubernetes?
CARTER MORGAN: Yeah, I went back,
I rewatched all the old episodes.
We talked about nodes.
We talked about containers, and we even
talked about the basic Kubernetes API objects.
But one thing was we deployed everything imperatively,
which you said wasn't going to scale well, right?
KASLIN FIELDS: Right.
So this time I'm going to show you how
to deploy an app declaratively.
CARTER MORGAN: Great.
I can't wait to see how it works.
KASLIN FIELDS: Now we're going to explore
how to deploy applications in containers declaratively using
Kubernetes.
If you remember in the last video,
we talked about deployments in Kubernetes
and how to create them.
But the command that we used in our last video
to create a deployment was imperative.
We told Kubernetes exactly what we wanted it to do
and it did it.
In the real world, we don't really
want to do things that way.
We want to do things declaratively
by having a file that describes or declares
what we want things to be like.
And then we have Kubernetes do the hard work of figuring out
how to make that happen.
Having our state defined declaratively in files
allows us to do some cool things, like make changes
to our deployments by just changing
the file describing it.
We can also track those changes through source control
and make use of great tools for deploying applications
at scale, like continuous integration
and continuous deployment tools.
So to start with, let's create a deployment
like we did in the last video, but this time we'll
do it declaratively.
So here you can see that I'm in Google Cloud platform,
and I'm using the Cloud Shell terminal
to interact with a Kubernetes cluster
that I have already created.
And if I run LS here, you'll see that I'm
in a directory that has some subdirectories and some files.
So the files for my microservice application
that I'm going to need to create that microservice application
in Kubernetes are all in these directories.
So the first one that I'm going to look at is
deployments/hello.yml.
So in this case, I have all of my files separated
by the type of Kubernetes resource that they define.
You could do this in all sorts of ways,
you don't have to do it with this structure or anything.
It's just the way that it is here.
So let's take a look at this.
If you remember the last video, we
had told Kubernetes what it was that we wanted it to create,
which is a deployment in this case.
So we're doing that again here.
We're giving that deployment a name.
We're telling Kubernetes a number of replicas
that we want of the pods that will be in this deployment.
You remember that we went over those as well.
And so here, we are defining the actual containers that we're
going to be running, the container image,
and a bit more information about that.
And you'll also see down here, we
have a liveness probe and a readiness probe,
which we didn't really go for last time.
But they are tools that Kubernetes provides
to help make sure that your application is up
and ready to receive traffic.
So there's a bit more that you can learn about deployments.
As you can see, this is a fairly--
it's not really that long, but there
are a few components in it that are worth learning a bit more
about.
So if you want to look into deployments a bit more,
I'd recommend it.
So this is what we mean by declaring our desired state.
All of the information about what
we want this deployment to look like is here in this file.
And if we wanted to make a change,
like changing the image that we're
going to be running in this deployment,
we could do that in this file and we could track that change
through source control.
So the next thing I'm going to do, actually,
I want to look at one more file before I create anything.
So let me look at, within services,
I have another file called Hello hello.yml.
So if you remember from the last video,
we created our deployment with our application
but then we needed some way to reach our application.
And we did that by creating a Kubernetes service.
So this is what this is going to do.
This is creating another Kubernetes service
that will allow artists to connect
to our Hello application, which will be
deployed in its own deployment.
So the service definition is pretty simple.
It just has a name for the service.
It has a selecter which tells the service how
to find the back ends that it is serving,
and then it has some port information
that will allow us to actually reach that application.
So if I want to create these and I
want to do it in a declarative way, what I'm going to do
is run kubectl apply dash f and give it the file name.
So let's say deployments/hello.yml.
And I can do more than one at a time.
I can just add another dash f here, and specify my service,
and create my service at the same time.
So that's pretty cool.
The kubectl apply command doesn't know which
API object you're creating.
So you can specify it in the file
and then just give it those files.
So it's pretty versatile.
So let's go ahead and create those.
So you can see that my deployment and my service
were created.
But it wouldn't be a microservice application
if it wasn't split up into multiple services.
So the next service that I'm going to deploy,
I'm going to deploy in exactly the same way.
I'm going to do kubectly apply dash f,
and then grab another deployment.
And this time I'm going to deploy my frontend.yml.
So for this application I've added in an Nginx server,
which will act as my front end.
And by the way, if you want to try this stuff out for yourself
and follow along, or just kind of play around with it,
check out the links below.
We'll have some information for you to get hands on with this.
So we're going to kubectl apply and we'll
give it a file for our front end deployment.
And once again, we're going to need a service for that.
So let's create our frontend.yml service as well.
Now, an interesting thing here is
I'm using the kubectl apply command
because, if that resource doesn't exist,
the apply command will go ahead and create the resource.
So I didn't have a front end deployment or a front end
service before.
So I went ahead and created those.
But if I were to run this command again,
you'll see that it says that the front end and the deployment
and its service were unchanged.
So if we were to make a change to our deployment,
like I said earlier, if we were to update the container image
or something like that in our deployment file,
where we have declared what we want our deployment
to look like, then we would be able to just apply that change.
And in the case of deployments, there
are settings within Kubernetes that you
can use to tell it how to roll out that change when
you apply a new change.
So in that way, this is a very declarative way
to create resources in Kubernetes.
But now that I have an Nginx component to my application,
there's some configuration information
that I want to pass into my Nginx server.
And it didn't really make sense to add that stuff
into the container definition.
And it didn't really make sense to add
that at any point along the way in creating the Kubernetes
deployment.
So how am I going to get that configuration information
into my Nginx server now?
Luckily, Kubernetes has a tool for that called ConfigMaps.
A config map lets you map your configuration information
to your application running in a Kubernetes deployment.
I already have a file here, which
has the configuration information that I
need for my Nginx front end.
And it's in nginx/frontedn.conf.
So you can see here that this is a bunch
of configuration information for my Nginx front end.
But you'll see that it's not in yml form.
So this is not actually declaratively declared.
So I'm going to have to create this just
using the configuration file as it is.
So what I'm going to do is run kubectl create.
Configmap is the type of Kubernetes
object that I want to create.
And I'm going to give that a name,
which I'm just going to call it Nginx front end conf,
and I'm going to tell it I want it to create that config map
from a file with information file,
which is nginx/frontend.conf.
Cool.
So this, we'll go ahead and create the config map
from that configuration information
that I showed you a minute ago.
But I have another problem.
I want to run this application a bit more securely
and I want to use TLS with it.
But for that, I'm going to need to pass it
some TLS certs, which I don't really
want to pass in a config map because that information is
just kind of plain text.
I want to make sure that that information is kept more, well,
secret.
So Kubernetes has a great tool for this called Secrets.
Now, there are a lot of different tools
for passing sensitive information in Kubernetes.
So Kubernetes Secrets might not be the best tool
for your use case.
You'll have to do a little bit of research to figure it out.
But in my case, Kubernetes Secrets
are going to be just fine.
They'll encrypt the information that I'm
passing into my application.
So let's go ahead and create a secret to pass my application,
the TLS certs that I have for it.
So kubectl create is what I'm going to use again.
Secrets are very similar to ConfigMaps,
except they're for secret information.
So create a secret.
And there are a few different types of secrets,
but for this one I'm just going to create a generic one.
And I'm going to give it a name, tls-certs.
And I'm going to create that, once again, from a file.
And that will be the TLS certs that I have in my directory.
So that secret was created.
And now there's one more piece of my microservice application.
And that is an authentication tool
that I've added into the microservice.
So what that's going to look like is, once again, coming
back to that trusty kubectl apply dash f,
and I'm going to grab a service for my auth.yml component
of my micra service.
And of course, I'm going to need something for that service
to serve, which will be a deployment one again.
And that's going to be auth.yml as well.
And I appear to have mistyped something.
Oh, I didn't put a dash f before my deployments file.
So you do have to put a dash f for each
file that you're passing it.
So there you go.
You can see that I've gone on ahead
and created the service in the deployment
for my authentication component of my microservice.
And that's it.
That's my whole microservice that I'm
going to be showing you today.
But how do I make sure that it's working properly?
Well, the best way is always to test, right?
So I'm going to run kubectl get services,
or just svc for short.
And I want to get the information for my front end.
So you'll see that my front end service
is of type load balancer.
In this case, that means that it created an actual load balancer
resource in Google Cloud, and that external load balancer
resource has created an external IP for us
that we will actually be able to use
to reach the application that I've created.
So I'm going to copy that IP and I'm going to export it
as a variable just to make my following commands
a little bit easier.
EXTERNAL_IP.
And give it that number.
OK.
So I've created my variable.
So now I can run a curl command to test
to make sure that my application is running correctly.
And if you'll remember earlier, we
incorporated some security capabilities
into this application.
But let's say that I just curled that IP.
What would happen?
Actually, I'm just going to post it in,
even though I just did that.
So if I curl that, nothing happens.
Why is that?
Of course, it's because we set up TLS
and we set up some security measures.
So now we're going to have to connect to this application
using HTTPS.
A bit more securely.
So I'm going to run curl dash k htttps:// and give it that IP.
And there you go.
So we've got our message output of hello.
And that's all I expected this application to do.
So I know the application is up and running properly.
But I also incorporated this authentication capability.
And so I can also connect to this application
as a specific user and make use of it that way.
So for that, I'm going to have to get a token to log in
as a specific user.
So what that's going to look like--
whoops.
I already did it.
So I'm going to go ahead and enter
the password for the user.
So what you can see here is I set up
a token, which equals a curl command, logging
in as a specific user.
I'm grabbing the token from that log in.
I had to enter the password for that user.
And so now I have this token that I can use
to access the website as well.
So now I'm going to go ahead and run a curl command where
I am passing in that token.
So I'm logging in as a specific user.
And if I run that, I get the same result.
So I know that I can reach my application
by using this authorization at capability that I edited.
So cool stuff.
I went through and I created deployments and config maps
and secrets.
And for the deployments and the services,
I did it in a declarative way, using these files
that I can then go in and make changes to, track
those changes, and do a lot of really cool stuff
with automation and running applications at scale.
So this is going to be really useful.
CARTER MORGAN: Great.
So that's how I can run my application declaratively.
KASLIN FIELDS: Right.
Running things declaratively is really
useful in the real world.
Running your deployments based on a file
makes it easy to set up CI/CD, source control,
and other processes that are useful for running applications
at scale.
CARTER MORGAN: Wow.
Thanks to Kaslin for taking the time
to show me how this all works.
This wraps up the most basic Kubernetes objects.
Next time we'll start looking into more advanced use cases
and features of Kubernetes.
Stay tuned.
Oh, and be sure to follow along in the Codelab link below
to walk through this code if you want to get hands-on.
And if you enjoyed this episode, subscribe for more.