Reputation: 9194
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
Reputation: 14082
TL; DR;
You are referring to two totally different Kubernetes objects which are Namespace and Labels/Selectors
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
namespace
, you will remove all objects which was in that particular namespace
.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 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
The
production
andstaging
are similar:environment: staging
andenvironment: 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