Working with namespaces

The name of a resource is a unique identifier within a namespace in the Kubernetes cluster. Using a Kubernetes namespace could isolate namespaces for different environments in the same cluster. It gives you the flexibility of creating an isolated environment and partitioning resources to different projects and teams.

Pods, services, replication controllers are contained in a certain namespace. Some resources, such as nodes and PVs, do not belong to any namespace.

Getting ready

By default, Kubernetes has created a namespace named default. All the objects created without specifying namespaces will be put into default namespaces. You could use kubectl to list namespaces:

// check all namespaces
# kubectl get namespaces
NAME      LABELS    STATUS    AGE
default   <none>    Active    8d

Kubernetes will also create another initial namespace called kube-system for locating Kubernetes system objects, such as a Kubernetes UI pod.

The name of a namespace must be a DNS label and follow the following rules:

  • At most 63 characters
  • Matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])

How to do it…

  1. After selecting our desired name, let's create a namespace named new-namespace by using the configuration file:
    # cat newNamespace.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: new-namespace
    
    // create the resource by kubectl
    # kubectl create -f newNamespace.yaml
    
  2. After the namespace is created successfully, list the namespace again:
    // list namespaces
    # kubectl get namespaces
    NAME            LABELS    STATUS    AGE
    default         <none>    Active    8d
    new-namespace   <none>    Active    12m
    

    You can see now that we have two namespaces.

  3. Let's run the nginx replication controller described in Chapter 1, Building Your Own Kubernetes in a new namespace:
    // run a nginx RC in namespace=new-namespace
    # kubectl run nginx --image=nginx --namespace=new-namespace
    
  4. Then let's list the pods:
    # kubectl get pods
    NAME                                    READY     STATUS        RESTARTS   AGE
    
  5. There are no pods running! Let's run again with the --namespace parameter:
    // to list pods in all namespaces
    # kubectl get pods --all-namespaces
    NAMESPACE      NAME          READY     STATUS    RESTARTS   AGE
    new-namespace  nginx-ns0ig   1/1       Running   0          17m
    
    // to get pods from new-namespace
    # kubectl get pods --namespace=new-namespace
    NAME          READY     STATUS    RESTARTS   AGE
    nginx-ns0ig   1/1       Running   0          18m
    

    We can see our pods now.

  6. By default, if you don't specify any namespace in the command line, Kubernetes will create the resources in the default namespace. If you want to create resources by configuration file, just simply specify it when doing kubectl create:
    # kubectl create -f myResource.yaml --namespace=new-namespace
    

Changing the default namespace

It is possible to switch the default namespace in Kubernetes:

  1. Find your current context:
    # kubectl config view | grep current-context
    current-context: ""
    

    It reveals that we don't have any context setting now.

  2. No matter whether there is current context or not, using set-context could create a new one or overwrite the existing one:
    # kubectl config set-context <current context or new context name> --namespace=new-namespace
    
  3. After setting the context with a new namespace, we can check the current configuration:
    # kubectl config view
    apiVersion: v1
    clusters: []
    contexts:
    - context:
        cluster: ""
        namespace: new-namespace
        user: ""
      name: new-context
    current-context: ""
    kind: Config
    preferences: {}
    users: []
    

    We can see the namespace is set properly in the contexts section.

  4. Switch the context to the one we just created:
    # kubectl config use-context new-context
    
  5. Then check the current context again:
    # kubectl config view | grep current-context
    current-context: new-context
    

    We can see that current-context is new-context now.

  6. Let's list the current pods again. There's no need to specify the Namespace parameter, as we can list the pods in new-namespace:
    # kubectl get pods
    NAME          READY     STATUS    RESTARTS   AGE
    nginx-ns0ig   1/1       Running   0          54m
    
  7. Namespace is listed in the pod description as well:
    # kubectl describe pod nginx-ns0ig
    Name:        nginx-ns0ig
    Namespace:      new-namespace
    Image(s):      nginx
    Node:        ip-10-96-219-156/10.96.219.156
    Start Time:      Sun, 20 Dec 2015 15:03:40 +0000
    Labels:        run=nginx
    Status:        Running
    

Deleting a namespace

  1. Using kubectl delete could delete the resources including the namespace. Deleting a namespace will erase all the resources under that namespace:
    # kubectl delete namespaces new-namespace
    namespace "new-namespace" deleted
    
  2. After the namespace is deleted, our nginx pod is gone:
    # kubectl get pods
    NAME      READY     STATUS    RESTARTS   AGE
    
  3. However, the default namespace in the context is still set as new-namespace:
    # kubectl config view | grep current-context
    current-context: new-context
    

    Will it be a problem?

  4. Let's run an nginx replication controller again.
    # kubectl run nginx --image=nginx
    Error from server: namespaces "new-namespace" not found
    

    It will try to create an nginx replication controller and replica pod in the current namespace we just deleted. Kubernetes will throw out an error if the namespace is not found.

  5. Let's switch back to the default namespace.
    # kubectl config set-context new-context --namespace=""
    context "new-context" set.
    
  6. Let's run an nginx again.
    # kubectl run nginx --image=nginx
    replicationcontroller "nginx" created
    Does it real run in default namespace? Let's describe the pod.
    # kubectl describe pods nginx-ymqeh
    Name:        nginx-ymqeh
    Namespace:      default
    Image(s):      nginx
    Node:        ip-10-96-219-156/10.96.219.156
    Start Time:      Sun, 20 Dec 2015 16:13:33 +0000
    Labels:        run=nginx
    Status:        Running
    ...
    

    We can see the pod is currently running in Namespace: default. Everything looks fine.

There's more…

Sometimes you'll need to limit the resource quota for each team by distinguishing the namespace. After you create a new namespace, the details look like this:

$ kubectl describe namespaces new-namespace
Name:  new-namespace
Labels:  <none>
Status:  Active

No resource quota.

No resource limits.

Resource quota and limits are not set by default. Kubernetes supports constraint for a container or pod. LimitRanger in the Kubernetes API server has to be enabled before setting the constraint. You could either use a command line or configuration file to enable it:

// using command line-
# kube-apiserver --admission-control=LimitRanger

// using configuration file
# cat /etc/kubernetes/apiserver
...
# default admission control policies
KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
...

The following is a good example for creating a limit in a namespace.

We will then limit the resources in a pod with the values 2 as max and 200m as min for cpu, and 1Gi as max and 6Mi as min for memory. For the container, the cpu is limited between 100m - 2 and the memory is between 3Mi - 1Gi. If the max is set, then you have to specify the limit in the pod/container spec during the resource creation; if the min is set then the request has to be specified during the pod/container creation. The default and defaultRequest section in LimitRange is used to specify the default limit and request in the container spec:

# cat limits.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: limits
  namespace: new-namespace
spec:
  limits:
  - max:
      cpu: "2"
      memory: 1Gi
    min:
      cpu: 200m
      memory: 6Mi
    type: Pod
  - default:
      cpu: 300m
      memory: 200Mi
    defaultRequest:
      cpu: 200m
      memory: 100Mi
    max:
      cpu: "2"
      memory: 1Gi
    min:
      cpu: 100m
      memory: 3Mi
    type: Container

// create LimitRange
# kubectl create -f limits.yaml
limitrange "limits" created

After the LimitRange is created, we can list these down just like with any other resource:

// list LimitRange
# kubectl get LimitRange --namespace=new-namespace
NAME      AGE
limits    22m

When you describe the new namespace you will now be able to see the constraint:

# kubectl describe namespace new-namespace
Name:  new-namespace
Labels:  <none>
Status:  Active

No resource quota.

Resource Limits
 Type      Resource  Min   Max   Request  Limit   Limit/Request
 ----      --------  ---     ---    -------  -----   -------------
 Pod      memory    6Mi      1Gi  -         -      -
 Pod      cpu       200m   2     -         -      -
 Container  cpu       100m   2     200m      300m   -
 Container  memory    3Mi      1Gi  100Mi      200Mi   -

All the pods and containers created in this namespace have to follow the resource limits listed here. If the definitions violate the rule, a validation error will be thrown accordingly.

Deleting LimitRange

We could delete the LimitRange resource via:

# kubectl delete LimitRange <limit name> --namespace=<namespace>

Here, the limit name is limits and the namespace is new-namespace. After that when you describe the namespace, the constraint is gone:

# kubectl describe namespace <namespace>
Name:  new-namespace
Labels:  <none>
Status:  Active

No resource quota.

No resource limits.

See also

Many resources are running under a namespace, check out the following recipes:

  • Working with pods
  • Working with names
  • The Setting resource in nodes recipe in Chapter 7, Advanced Cluster Administration
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset