# Journey into Kubernetes - Namespaces


Great, you have your cluster, you have your kubectl CLI installed... let's get creatin'!

> We're going to be using the YAML declarative language to create all our objects in our K8s cluter. It's also possible to do all this via the `kubectl` command, but quite frankly, that's silly. Just FYI though, you can create namespaces, deployments, pods, and other things via `kubectl`, you just shouldn't.

When we write a YAML file, we'll then *apply* it with this command:
```powershell
kubectl apply -f .\namespaces.yml
```
You'll be using the `apply` command a lot. Applying a YAML file tells the K8s cluster what you want some piece of it to look like. If you're confused, worry not, it will all become clear as we go along!

Go ahead and create a new folder where you'll be storing your YAML files. Inside that folder, create two new folders: Cluster, Services. We want to keep the cluster setup separate from the rest of your YAML files.

Inside the Cluster folder, create a file `namespaces.yml`. We're going to create two namespaces: Integration and Production. In a real-world scenario, you'd also want at least a Staging namespace in addition to the two aforementioned ones, but here we'll be fine with just two.

Inside the new `namespaces.yml` file, add the following code:
```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    name: prod

---

apiVersion: v1
kind: Namespace
metadata:
  name: integration
  labels:
    name: int
```

One thing to note, when writing YAML, you do __NOT__ want to use tabs. Always use spaces. The number of spaces is up to you, but no tabs! It will fail to parse when applying if you use tabs.

Let's check to make sure kubectl works and you see the nodes you created in the previous step.
```powershell
kubectl get nodes
```
You should see two nodes. If you don't, ensure you're targeting the right context (cluster). You can use the `az aks` commands to do this.

If you see two nodes, you're good to go. Let's apply this YAML file to the cluster, then discuss its contents.
```powershell
kubectl apply -f .\namespaces.yml
```
You'll see something like this:
```powershell
namespace/production created
namespace/integration created
```
Okay, let's look at the YAML real quick. The first key-value pair (KVP) is `apiVersion: v1`. Kubernetes is an evolving project and there have been lots of different versions of definition syntax. It's pretty confusing which version should be used and when even to a seasoned K8s navigator. In this case, we're using `v1`.

Next, the KVP `kind: Namespace` tells K8s that this definition is for a Namespace object. Pretty self-explanatory.

Then we have a metadata map. The first KVP is `name: production`. As you guessed, this sets the namespace's name.

Last, we have the labels map with a label KVP `name: prod`. Labels are used to organize and group things... as in any other service. For example, in Azure, you can add tags to any entities you create. Same concept. If you create additional objects, you can add the same label `name: prod`. Labels are *not unique*.

Okay! Now that you know what's what, let's see your namespaces.
```powershell
kubectl get namespaces
```
You'll get a list of namespaces, along with Status and Age properties. There's a `default` namespace, that's where all objects go if you don't specify a namespace for them. There are some `kube-*` namespaces which are system namespaces. Lastly, your two namespaces should be there as well.

> By default, all your kubectl commands go against the `default` namespace. To make things more convenient when applying all YAML configuration files later, we're going to set the integration namespace as our default instead. You can use the `kubectl config set-context --current --namespace=integration` command to do that. Alternatively, if you don't want to set your current context, you can add `-n integration` after every command you type. I think setting the context is more convenient, but it's your call.

Let's leave it here. In the next article, we'll talk about Resource Quotas and Limit Ranges. We don't want our microservices to go rogue and bring down our entire cluster...
