SANDEEP DINESH: As you start to build more and more services
on top of Kubernetes, simple tasks
start to get more complicated.
For example, teams can't create services or deployments
with the same name.
If you have thousands of pod, just
listing them all would take some time,
let alone actually administering them.
And these are just the tip of the iceberg.
In this episode of "Kubernetes Best Practices,"
let's take a look at how namespaces can make managing
Kubernetes resources easier.
So what exactly is a namespace?
You can think of a namespace as a virtual cluster
inside your Kubernetes cluster.
You can have multiple namespaces inside a single Kubernetes
cluster.
And they're all isolated from each other.
They can help you and your teams with organization, security,
and even performance.
In most Kubernetes distributions,
the cluster comes out of the box with the namespace called,
default. In fact, there are actually three namespaces that
Kubernetes ships with, default, kube system, and kube public.
Kube public really isn't used for much right now.
And it's usually a good idea to leave kube system alone,
especially in a managed system like Google Kubernetes Engine.
This leaves the default namespace
as the place where your services and apps are created.
There's absolutely nothing special about this namespace,
except that the Kubernetes tooling is set up
out of the box to use this namespace
and you can't delete it.
While it's great for getting started
and smaller production systems, I
would recommend against using it in large production systems.
This is because it's very easy for a team
to accidentally overwrite, or disrupt another team
without even realizing it.
Instead, you should create multiple namespaces
and use them to segment your services
into manageable chunks.
Creating a namespace can be done with a single command.
If you want to create a namespace called test,
you would run kubectl create namespace test.
Or you could create a YAML file and apply it just
like any other Kubernetes resource.
You can see all the namespaces with the following command,
kubectl get namespace.
You can see the three built-in namespaces spaces, as well as
the new namespace called test.
Let's take a look at a simple YAML to create a pod.
You may notice that there is no mention of a namespace
anywhere.
If you kubectl apply on this file,
it'll create a pod in the current active namespace.
This will be the default namespace unless you change it.
Now, there's two ways to explicitly tell
Kubernetes which namespace you want your resource created in.
The first way, is using the namespace flag
when creating the resource.
The second way is to specify a namespace in the YAML
declaration.
Now, if you specify a namespace in the YAML,
the resource will always be created in that namespace.
If you try to use another namespace
by using the namespace flag, the command will fail.
Now, if you try to find your pod,
you may have noticed you can't find it.
This is because all commands are run
against a current active namespace.
To find your pod, you need to use the namespace flag.
Now, this can get annoying quickly,
especially if you're a developer working
on a team that uses its own namespace for everything
and don't want to use the namespace flag
for every single command.
Let's see how we can fix that.
Out of the box, your active namespace
is the default namespace.
Like we saw before, unless you specify
a namespace in the resource's YAML,
all Kubernetes commands will use the active namespace.
Now unfortunately, trying to manage an active namespace
with kubectl can be a pain.
Fortunately, there's a really good tool called
Kubens that makes it a breeze.
When you run the kubens command, you
should see all the namespaces with the active namespace
highlighted.
To switch your active namespace to the test namespace
you can just run kubens test.
Now you can see the test namespace is active.
If you run kubectl commands, the namespace
will now be test instead of default.
This means you don't need the namespace flag to see
the pod in the test namespace.
So namespaces are hidden from each other,
but they're not isolated.
A service in one namespace can talk
to a service in another namespace pretty easily.
This can often be very useful.
For example, having your service for your team
talk to another namespace with another team's service.
Normally, when your app wants to access a Kubernetes service,
you can just use the built-in DNS service discovery
and just point your app at the services name.
However, you can create a service
for the same name in multiple namespaces.
Thankfully, it's easy to get around this
by using the expanded form of the DNS address.
Services in Kubernetes expose their endpoint point
using a common DNS pattern.
It looks like this.
Normally, you just need the service's name
and DNS will automatically resolve to the full address.
However, if you need to access a service in another namespace,
just use the service name plus the namespace name.
For example, if you want to connect to the database
service in the test namespace, you
can use the following address database.test.
And if you want to connect to the database
service in the prod namespace, you
can use the following address database.prod.
Of course, sometimes you do want to isolate and limit access
to a namespace.
Kubernetes lets you do this with network policies.
Stay tuned for a future episode, where
we'll deep dive into these.
A common question I get is, how many namespaces to create?
And for what purpose?
What exactly is a manageable chunk?
If you make too many namespaces, they'll just get in your way.
But if you make too few, you'll lose the benefits.
I think there are four major stages that each company goes
through and they have their own organizational structure.
Depending on the stage that your project or company is in,
you can adopt the relevant namespace strategy.
So imagine you're part of a small team that's working on
maybe 5 to 10 microservices and you can easily bring everyone
into the same room.
In this situation, it makes sense
to launch all production services into the default
namespace.
You might want to have a production and development
namespace, if you want to get fancy.
But you know, you're probably testing your development
environment on your local machine using something
like Minikube.
Now, the scenario changes.
You have a rapidly growing team that's
working a 10 or more microservices.
It's necessary at this point to use
multiple clusters, or namespaces,
for production and development.
You may start to split the team into multiple sub-teams
that each have their own microservices.
And then each of these teams might
choose their own namespace for easier manageability.
While everyone might know how the complete system works,
it's getting harder and harder to coordinate every change
with everyone else.
Trying to spin up the full stack on your local machine
is just getting more complicated every day.
Now, at large companies everyone doesn't know everyone else.
Teams are working on features that other teams might not even
know about.
Now, teams are communicating using service contracts
and maybe they're using service meshes like Istio
to coordinate communication.
Trying to run the whole stack locally is just impossible.
Using a Kubernetes aware CD system like Spinnaker
is highly recommended.
And at this point, each team definitely
needs their own namespace.
Each team might even opt for multiple namespaces
to run their development and production environments.
Setting up [? R-back ?] and resource quotas is a good idea
as well.
And we'll cover those in future episodes.
Multiple clusters start to make sense at this point,
but they really might not be necessary.
And finally, there are large enterprise companies.
There are groups that don't even know about the existence
of other groups.
Groups might as well be external companies and services are
consumed through well-documented APIs.
Each group has multiple teams and have
multiple microservices.
Using all the tools I previously mentioned are necessary.
And people should not be deploying services by hand.
And in fact, they should be locked out
of namespaces they don't own.
At this point, it probably makes sense
to have multiple clusters to reduce the blast
radius of poorly configured applications
and to make billing and resource management easier.
As the number of microservices and teams
using Kubernetes in your organization increases,
namespaces can really make Kubernetes
a lot more manageable and give you increased control,
security, and flexibility.
I'll see you on the next episode of "Kubernetes Best Practices."