cheslijones
cheslijones

Reputation: 9194

environment vs namespace in deployment.yaml

I'm looking at some older deployment.yaml files and I'm curious about the use of environment:.

This is the context:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: client-deployment-dev
  # namespace: development        # wouldn't this accomplish the same thing?
spec:
  replicas: 1
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      component: client
      environment: development       #here
  template:
    metadata:
      labels:
        component: client
        environment: development      #here
    spec:
      containers:
        - name: client
          image: client
          ports:
            - containerPort: 3000
          env:
          - name: DOMAIN
            valueFrom:
              secretKeyRef:
                name: app-dev-secrets
                key: DOMAIN 

The production and staging are similar: environment: staging and environment: production.

This apparently keeps the environments separated and prevents a kubectl apply -f ... from targeting the wrong environment (i.e. accidentally applying development configurations to production).

But wouldn't using namespace: development, namespace: staging, and namespace: production also accomplish the same thing? Is there a use case to use one over the other?

I guess one benefit of using environment is you can put everything in the default namespace while keeping Pods separated?

Upvotes: 2

Views: 1628

Answers (1)

PjoterS
PjoterS

Reputation: 14082

TL; DR;

You are referring to two totally different Kubernetes objects which are Namespace and Labels/Selectors

Namespaces

Kubernetes supports multiple virtual clusters backed by the same physical cluster. These virtual clusters are called namespaces.

Why use Kubernetes namespaces? Answer to this question is well described in What is a Kubernetes Namespace? article.

  • Allowing teams or projects to exist in their own virtual clusters without fear of impacting each other’s work.
  • Enhancing role-based access controls (RBAC) by limiting users and processes to certain namespaces.
  • Enabling the dividing of a cluster’s resources between multiple teams and users via resource quotas.
  • Providing an easy method of separating development, testing, and deployment of containerized applications enabling the entire lifecycle to take place on the same cluster.

In short namespace allows you to separate objects. Beside default you have a few namespaces like kube-system which was created by the Kubernetes system. In that namespace you have system pods like kube-dns or kube-proxy which are responsible for network configuration.

Another example is that many Helm Charts are configured to deploy objects in different namesapce than default.

Some resources are namespaced:

$ kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                        NAMESPACED   KIND
bindings                                       v1                                true         Binding
componentstatuses                 cs           v1                                false        ComponentStatus
configmaps                        cm           v1                                true         ConfigMap
endpoints                         ep           v1                                true         Endpoints
...

It means that they require defining namespace otherwise you will find error that resource was not found.

$ kubectl get po
No resources found in default namespace.
$ kubectl get pod --namespace kube-system
NAME                                                        READY   STATUS    RESTARTS   AGE
event-exporter-gke-666b7ffbf7-kjcn2                         2/2     Running   0          2m42s
fluentbit-gke-njk6d                                         2/2     Running   0          2m30s
fluentbit-gke-wlwsp                                         2/2     Running   0          2m29s
...

If you don't specify namespace, Kubernetes will use default namespace in all cases (create, remove, get, etc).

You can configure Quota in namespace to restrict numbers or pods, services, etc.

$ kubectl describe namespaces
Name:         default
Labels:       <none>
Annotations:  <none>
Status:       Active

Resource Quotas
 Name:                       gke-resource-quotas
 Resource                    Used  Hard
 --------                    ---   ---
 count/ingresses.extensions  0     100
 count/jobs.batch            0     5k
 pods                        0     1500
 services                    1     500

Use Case

  • When you will remove namespace, you will remove all objects which was in that particular namespace.
  • If you would have all your pods in one namespace, command like $ kubectl delete pod --all would remove all pods. If you will separate them by namespace, it will remove all pods from one specific namespace.

Labels / Selectors

Labels are key/value pairs that are attached to objects, such as pods. Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users, but do not directly imply semantics to the core system. Labels can be used to organize and to select subsets of objects.

Labels / Selectors are commonly used to connect Application with Services. Deployment and service have the same labels/selectors and this way they are connected.

Use Case

You have tested some specific software and you have used 2 pods with labels env: prod, app: nginx and 2 with labels env: dev and app: nginx. Now you can delete pods with specific label.

$ kubectl get po --show-labels
NAME     READY   STATUS    RESTARTS   AGE   LABELS
dev-1    1/1     Running   0          8s    app=nginx,env=dev
dev-2    1/1     Running   0          14s   app=nginx,env=dev
pord-1   1/1     Running   0          64s   app=nginx,env=prod
pord-2   1/1     Running   0          26s   app=nginx,env=prod
$ kubectl delete po -l env=prod
pod "pord-1" deleted
pod "pord-2" deleted
$ kubectl get po --show-labels
NAME    READY   STATUS    RESTARTS   AGE   LABELS
dev-1   1/1     Running   0          70s   app=nginx,env=dev
dev-2   1/1     Running   0          76s   app=nginx,env=dev

Conclusion

The production and staging are similar: environment: staging and environment: production.

Those are two different objects - Namespace which is some kind of virtual cluster which helps us to organise projects or environments. Labels are a key-value pair which is assigned to Kubernetes Resources like Pods, Deployments, etc.

I guess one benefit of using environment is you can put everything in the default namespace while keeping Pods separated?

In some cases yes, but for each command you will need to specify that label.

If you would list resource from all namespaces you can do it using --all-namespaces eg, $ kubectl get po --all-namespaces or flag -A like $ kubectl get po -A

Additional Links

Please let me know if you have further questions.

Upvotes: 2

Related Questions