The meaning of the key field - kubernetes

I have a deployment, that looks as follows:
The question is, what is the difference between the red border label and the violet one?

blue border labels are applied to pod spec where as red border labels are part of deployment spec.
Notice that replicaSet selector uses same key:value pair to identify the related pods.
You can query deployment object using below command
kubectl get deploy -l app=nginx
same way, you can query pod using
kubectl get po -l app=nginx

You can add labels to any k8s object. Pod are one of the objects that take most advantage of it as services target them through labels, but again, any object can have labels.
About deployments, a deployment creates a replicaSet, that in turn creates the pods. The red square is the deployment labels, while the violet is the labels that will have the pods that the replicaSet will create. Note that it is under template section (Pod template).
Now, and this is the important thing with deployments, these two labels must match, in order for a deployment to recognize its "children", otherwise the pods will be orphan. So, if you would change any of these labels, the deployment will create new pods with its labels, and the pods that do not match will run without any controller to back them up.

These key fields are refereed as Labels on Kubernetes. These labels are used in Kubernetes in order to organize our cluster.
Labels are key/value pairs that are attached to objects that can be used to identify or group resources in Kubernetes. They can be used to select resources from a list.
Labels can be attached to objects at creation time and subsequently added and modified at any time. Each object can have a set of key/value labels defined. Each Key must be unique for a given object.
Going deeper on it, lets suppose you have this Pod in your cluster:
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
namespace: default
labels:
env: development
spec:
containers:
- name: busybox
image: busybox
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
restartPolicy: Always
As you can see we are setting one label: env: development
If you deploy this pod you can run the following command to list all lables set to this pod:
kubectl get pod sample-pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
sample-pod 1/1 Running 0 28s env=development
You can also list all pods with development label:
$ kubectl get pods -l env=development
NAME READY STATUS RESTARTS AGE
sample-pod 1/1 Running 0 106s
You can also delete a pod using the label selection:
pod "sample-pod" deleted
Matching objects must satisfy all of the specified label constraints, though they may have additional labels as well. Three kinds of operators are admitted =,==,!=. The first two represent equality (and are simply synonyms), while the latter represents inequality. For example:
environment = production
tier != frontend
You can read more about labels on Kubernetes Documentation.

Related

Couldn't understand availableReplicas, readyReplicas, unavailableReplicas in DeploymentStatus

I am creating deployments using Kubernetes API from my server. The deployment pod has two containers - one is the main and the other is a sidecar container that checks the health of the pod and calls the server when it becomes healthy.
I am using this endpoint to get the deployment. It has deployment status property with the following structure as mention here.
I couldn't understand the fields availableReplicas, readyReplicas, replicas, unavailableReplicas and updatedReplicas.
I checked docs of Kubernetes and these SO questions too - What is the difference between current and available pod replicas in kubernetes deployment? and Meaning of "available" and "unavailable" in kubectl describe deployment but could not infer the difference between of a pod being ready, running and available. Could somebody please explain the difference between these terms and states?
A different kinds of replicas in the Deployment's Status can be described as follows:
Replicas - describes how many pods this deployment should have. It is copied from the spec. This happens asynchronously, so in a very brief interval, you could read a Deployment where the spec.replicas is not equal to status.replicas.
availableReplicas - means how many pods are ready for at least some time (minReadySeconds). This prevents flapping of state.
unavailableReplicas - is the total number of pods that should be there, minus the number of pods that has to be created, or ones that are not available yet (e.g. are failing, or are not ready for minReadySeconds).
updatedReplicas - the number of pods reachable by deployment, that match the spec template.
readyReplicas - the number of pods that are reachable from deployment through all the replicas.
Let's use the official example of a Deployment that creates a ReplicaSet to bring up three nginx Pods:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
The Deployment creates three replicated Pods, indicated by the .spec.replicas field.
Create the Deployment by running the following command:
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
Run kubectl get deployments to check if the Deployment was created.
If the Deployment is still being created, the output is similar to the following:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 0 0 1s
When you inspect the Deployments in your cluster, the following fields are displayed:
NAME - lists the names of the Deployments in the namespace.
READY - displays how many replicas of the application are available to your users. It follows the pattern ready/desired.
UP-TO-DATE - displays the number of replicas that have been updated to achieve the desired state.
AVAILABLE - displays how many replicas of the application are available to your users.
AGE - displays the amount of time that the application has been running.
Run the kubectl get deployments again a few seconds later. The output is similar to this:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 18s
To see the ReplicaSet (rs) created by the Deployment, run kubectl get rs. The output is similar to this:
NAME DESIRED CURRENT READY AGE
nginx-deployment-75675f5897 3 3 3 18s
ReplicaSet output shows the following fields:
NAME - lists the names of the ReplicaSets in the namespace.
DESIRED - displays the desired number of replicas of the application, which you define when you create the Deployment. This is the desired state.
CURRENT - displays how many replicas are currently running.
READY displays how many replicas of the application are available to your users.
AGE - displays the amount of time that the application has been running.
As you can see there is no actual difference between availableReplicas and readyReplicas as both of those fields displays how many replicas of the application are available to your users.
And when it comes to the Pod Lifecycle it is important to see the difference between Pod phase, Container states and Pod conditions which all have different meanings. I strongly recommend going through the linked docs in order to get a solid understanding behind them.

Cannot update Kubernetes pod from yaml generated from kubectl get pod pod_name -o yaml

I have a pod in my kubernetes which needed an update to have securityContext. So generated a yaml file using -
kubectl get pod pod_name -o yaml > mypod.yaml
After updating the required securityContext and executing command -
kubectl apply -f mypod.yaml
no changes are observed in pod.
Where as a fresh newly created yaml file works perfectly fine.
new yaml file -
apiVersion: v1
kind: Pod
metadata:
name: mypod
namespace: default
spec:
securityContext:
runAsUser: 1010
containers:
- command:
- sleep
- "4800"
image: ubuntu
name: myubuntuimage
Immutable fields
In Kubernetes you can find information about Immutable fields.
A lot of fields in APIs tend to be immutable, they can't be changed after creation. This is true for example for many of the fields in pods. There is currently no way to declaratively specify that fields are immutable, and one has to rely on either built-in validation for core types, or have to build a validating webhooks for CRDs.
Why ?
There are resources in Kubernetes which have immutable fields by design, i.e. after creation of an object, those fields cannot be mutated anymore. E.g. a pod's specification is mostly unchangeable once it is created. To change the pod, it must be deleted, recreated and rescheduled.
Editing existing pod configuration
If you want to apply new config with security context using kubectl apply you will get error like below:
The Pod "mypod" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds` or `spec.tolerations` (only additions to existing tolerations)
Same output will be if you would use kubectl patch
kubectl patch pod mypod -p '{"spec":{"securityContext":{"runAsUser":1010}}}'
Also kubectl edit will not change this specific configuration
$ kubectl edit pod
Edit cancelled, no changes made.
Solution
If you need only one pod, you must delete it and create new one with requested configuration.
Better solution is to use resource which will make sure to fulfil some own requirements, like Deployment. After change of the current configuration, deployment will create new Replicaset which will create new pods with new configuration.
by updating the PodTemplateSpec of the Deployment. A new ReplicaSet is created and the Deployment manages moving the Pods from the old ReplicaSet to the new one at a controlled rate. Each new ReplicaSet updates the revision of the Deployment.

how to get all replicaset names inside a container

Consider the following example provided in this doc.
What I'm trying to achieve is to see the 3 replicas names from inside the container.
following this guide I was able to get the current pod name, but i need also the pod names from my replicas.
Ideally i would like to:
print(k8s.get_my_replicaset_names())
or
print(os.getenv("MY_REPLICASET"))
and have a result like:
[frontend-b2zdv,frontend-vcmts,frontend-wtsmm]
that is the pod names of all the container's replicas (also the current container of course) and eventually compare the current name in the name list to get my index in the list.
Is there any way to achieve this?
As you can read here, the Downward API is used to expose Pod and Container fields to a running Container:
There are two ways to expose Pod and Container fields to a running
Container:
Environment variables
Volume Files
Together, these two ways of exposing Pod and Container fields are
called the Downward API.
It is not meant to expose any information about other objects/resources such as ReplicaSet or Deployment, that manage such a Pod.
You can see exactly what fields contains the yaml manifest that describes a running Pod by executing:
kubectl get pods <pod_name> -o yaml
The example fragment of its output may look as follows:
apiVersion: v1
kind: Pod
metadata:
annotations:
<some annotations here>
...
creationTimestamp: "2020-10-08T22:18:03Z"
generateName: nginx-deployment-7bffc778db-
labels:
app: nginx
pod-template-hash: 7bffc778db
name: nginx-deployment-7bffc778db-8fzrz
namespace: default
ownerReferences: 👈
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet 👈
name: nginx-deployment-7bffc778db 👈
...
As you can see, in metadata section it contains ownerReferences which in the above example contains one reference to a ReplicaSet object by which this Pod is managed. So you can get this particular ReplicaSet name pretty easily as it is part of a Pod yaml manifest.
However, you cannot get this way information about other Pods managed by this ReplicaSet .
Such information only can be obtained from the api server e.g by using kubectl client or programmatically with direct calls to the API.

Kubectl get deployments, no resources

I've just started learning kubernetes, in every tutorial the writer generally uses "kubectl .... deploymenst" to control the newly created deploys. Now, with those commands (ex kubectl get deploymets) i always get the response No resources found in default namespace., and i have to use "pods" instead of "deployments" to make things work (which works fine).
Now my question is, what is causing this to happen, and what is the difference between using a deployment or a pod? ? i've set the docker driver in the first minikube, it has something to do with this?
First let's brush up some terminologies.
Pod - It's the basic building block for Kubernetes. It groups one or more containers (such as Docker containers), with shared storage/network, and a specification for how to run the containers.
Deployment - It is a controller which wraps Pod/s and manages its life cycle, which is to say actual state to desired state. There is one more layer in between Deployment and Pod which is ReplicaSet : A ReplicaSet’s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods.
Below is the visualization:
Source: I drew it!
In you case what might have happened :
Either you have created a Pod not a Deployment. Therefore, when you do kubectl get deployment you don't see any resources. Note when you create Deployments it in turn creates a ReplicaSet for you and also creates the defined pods.
Or may be you created your deployment in a different namespace, if that's the case, then type this command to find your deployments in that namespace kubectl get deploy NAME_OF_DEPLOYMENT -n NAME_OF_NAMESPACE
More information to clarify your concepts:
Source
Below the section inside spec.template is the section which is supposedly your POD manifest if you were to create it manually and not take the deployment route. Now like I said earlier in simple terms Deployments are a wrapper to your PODs, therefore anything which you see outside the path spec.template is the configuration which you will need to defined on how you want to manage (scaling,affinity, e.t.c) your POD
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Deployment is a controller providing higher level abstraction on top of pods and ReplicaSets. A Deployment provides declarative updates for Pods and ReplicaSets. Deployments internally creates ReplicaSets within which pods are created.
Use cases of deployment is documented here
One reason for No resources found in default namespace could be that you created the deployment in a specific namespace and not in default namespace.
You can see deployments in a specific namespace or in all namespaces via
kubectl get deploy -n namespacename
kubectl get deploy -A

What is the recommended way to get the pods of a Kubernetes deployment?

Especially considering all the asynchronous procedures involved with creating and updating a deployment, I find it difficult to reliably find the current pods associated with the current version of a given deployment.
Currently, I do:
Add unique labels to the deployment's template.
Get the revision number of the deployment.
Get all replica sets with the labels.
Filter them further to find the one with the correct revision number.
Extract the pod template hash from the replica set.
Get all pods with the labels plus the pod template hash.
This is awkward and complex. Besides, I am not sure that (4) and (6) are guaranteed to yield only the wanted objects. But I cannot filter by ownerReferences, can I?
Is there a more robust and simpler way?
When you create Deployment, it creates ReplicaSet, which creates Pods.
ReplicaSet contains "ownerReferences" path which includes the name and the UID of the parent deployment.
Pods contain the same path with the link to the parent ReplicaSet.
Here is an example of ReplicaSet info:
# kubectl get rs nginx-deployment-569477d6d8 -o yaml
apiVersion: extensions/v1beta1
kind: ReplicaSet
...
name: nginx-deployment-569477d6d8
namespace: default
ownerReferences:
- apiVersion: extensions/v1beta1
blockOwnerDeletion: true
controller: true
kind: Deployment
name: nginx-deployment
uid: acf5fe8a-5d0e-11e8-b14f-42010a8000fc
...