<p>I'm looking at some older <code>deployment.yaml</code> files and I'm curious about the use of <code>environment:</code>.</p>
<p>This is the context:</p>
<pre><code>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 
</code></pre>
<p>The <code>production</code> and <code>staging</code> are similar: <code>environment: staging</code> and <code>environment: production</code>.</p>
<p>This apparently keeps the environments separated and prevents a <code>kubectl apply -f ...</code> from targeting the wrong environment (i.e. accidentally applying development configurations to production).</p>
<p>But wouldn't using <code>namespace: development</code>, <code>namespace: staging</code>, and <code>namespace: production</code> also accomplish the same thing? Is there a use case to use one over the other?</p>
<p>I guess one benefit of using <code>environment</code> is you can put everything in the <code>default</code> namespace while keeping Pods separated?</p>

cjones
<p><strong>TL; DR;</strong></p>
<p>You are referring to two totally different Kubernetes objects which are <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/" rel="nofollow noreferrer">Namespace</a> and <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/" rel="nofollow noreferrer">Labels/Selectors</a></p>
<h2>Namespaces</h2>
<blockquote>
<p>Kubernetes supports multiple virtual clusters backed by the same physical cluster. These virtual clusters are called namespaces.</p>
</blockquote>
<p>Why use Kubernetes namespaces? Answer to this question is well described in <a href="https://www.vmware.com/topics/glossary/content/kubernetes-namespace" rel="nofollow noreferrer">What is a Kubernetes Namespace?</a> article.</p>
<blockquote>
<ul>
<li>Allowing teams or projects to exist in their own virtual clusters without fear of impacting each other’s work.</li>
<li>Enhancing role-based access controls (RBAC) by limiting users and processes to certain namespaces.</li>
<li>Enabling the dividing of a cluster’s resources between multiple teams and users via resource quotas.</li>
<li>Providing an easy method of separating development, testing, and deployment of containerized applications enabling the entire lifecycle to take place on the same cluster.</li>
</ul>
</blockquote>
<p>In short namespace allows you to separate objects. Beside <code>default</code> you have a few <code>namespaces</code> like <code>kube-system</code> which was created by the Kubernetes system. In that <code>namespace</code> you have system pods like <code>kube-dns</code> or <code>kube-proxy</code> which are responsible for network configuration.</p>
<p>Another example is that many <code>Helm Charts</code> are configured to deploy objects in different <code>namesapce</code> than <code>default</code>.</p>
<p>Some resources are <code>namespaced</code>:</p>
<pre><code>$ 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
...
</code></pre>
<p>It means that they require defining namespace otherwise you will find error that resource was not found.</p>
<pre><code>$ 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
...
</code></pre>
<p>If you don't specify <code>namespace</code>, Kubernetes will use <code>default</code> namespace in all cases (create, remove, get, etc).</p>
<p>You can configure <code>Quota</code> in <code>namespace</code> to restrict numbers or pods, services, etc.</p>
<pre><code>$ kubectl describe namespaces
Name:         default
Labels:       &lt;none&gt;
Annotations:  &lt;none&gt;
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
</code></pre>
<p><strong>Use Case</strong></p>
<ul>
<li>When you will remove <code>namespace</code>, you will remove all objects which was in that particular <code>namespace</code>.</li>
<li>If you would have all your <code>pods</code> in one <code>namespace</code>, command like <code>$ kubectl delete pod --all</code> would remove all pods. If you will separate them by <code>namespace</code>, it will remove all <code>pods</code> from one specific <code>namespace</code>.</li>
</ul>
<h2>Labels / Selectors</h2>
<blockquote>
<p>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.</p>
</blockquote>
<p><code>Labels / Selectors</code> are commonly used to connect <a href="https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/" rel="nofollow noreferrer">Application with Services</a>. Deployment and service have the same <code>labels/selectors</code> and this way they are <code>connected</code>.</p>
<p><strong>Use Case</strong></p>
<p>You have tested some specific software and you have used 2 pods with labels <code>env: prod</code>, <code>app: nginx</code> and 2 with labels <code>env: dev</code> and <code>app: nginx</code>. Now you can delete pods with specific <code>label</code>.</p>
<pre><code>$ 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 &quot;pord-1&quot; deleted
pod &quot;pord-2&quot; 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
</code></pre>
<h2>Conclusion</h2>
<blockquote>
<p>The <code>production</code> and <code>staging</code> are similar: <code>environment: staging</code> and <code>environment: production</code>.</p>
</blockquote>
<p>Those are two different objects - <code>Namespace</code> which is some kind of virtual cluster which helps us to organise projects or environments. <code>Labels</code> are a key-value pair which is assigned to Kubernetes Resources like Pods, Deployments, etc.</p>
<blockquote>
<p>I guess one benefit of using environment is you can put everything in the default namespace while keeping Pods separated?</p>
</blockquote>
<p>In some cases yes, but for each command you will need to specify that <code>label</code>.</p>
<p>If you would list resource from all <code>namespaces</code> you can do it using <code>--all-namespaces</code> eg, <code>$ kubectl get po --all-namespaces</code> or flag <code>-A</code> like <code>$ kubectl get po -A</code></p>
<p><strong>Additional Links</strong></p>
<ul>
<li><a href="https://kubernetes.io/docs/tasks/administer-cluster/namespaces-walkthrough/" rel="nofollow noreferrer">Namespaces Walkthrough</a></li>
<li><a href="https://kubernetes.io/docs/tasks/administer-cluster/namespaces/" rel="nofollow noreferrer">Share a Cluster with Namespaces</a></li>
<li><a href="https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-organizing-with-namespaces" rel="nofollow noreferrer">Kubernetes best practices: Organizing with Namespaces</a></li>
<li><a href="https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/" rel="nofollow noreferrer">Managing Resources</a></li>
</ul>
<p>Please let me know if you have further questions.</p>
