Kubernetes Controllers - ReplicaSet vs Replication Controllers etc - kubernetes

I'm trying to understand basic Kubernetes concepts but its documentation a bit confusing, as for me.
For example, the Replication Controller is mentioned in the kube-controller-manager.
At the same time, Kubernetes Concepts page says about ReplicaSet object.
And only after some googling I found this post on Medium:
Replication Controllers perform the same function as ReplicaSets, but Replication Controllers are old school. ReplicaSets are the smart way to manage replicated Pods in 2019.
And this is not mentioned anywhere in the official docs.
Can somebody please explain to me about Endpoints and Namespace Controllers?
Are they still "valid" Controllers - or they are also outdated/replaced by some other controller/s?

Replica Controller Vs Replica Set
The functionality of both Replica Controller and Replica Set are quite the same - they are responsible to make sure that X number of pods with label that is equal to there label selector will be scheduled to different nodes on the cluster.
(Where X is the value that is specified in the spec.replicas field in the Replica Controller / Replica Set yaml).
ReplicaSet is a replacement for the Replica controller and supports richer expressions for the label selector.
You can choose between 4 values of operators In, NotIn, Exists, DoesNotExist - see Set-based requirement.
A rule of thumb: When you see Replica Controller is mentioned in one the docs or other tutorials - refer to it as ReplicaSet AND consider using Deployment instead.
Regarding Endpoints and Namespace Controllers
The K8S control plane contains multiple controllers - each controller watches a desired state of the resource that it responsible for (Pods, Endpoints, Namespaces etc') via an infinite control loop - also called Reconciliation Loop.
When a change is made to the desired state (by external client like kubectl) the reconciliation loop detects this and attempts to mutate the existing state in order to match the desired state.
For example, if you increase the value of the replicas field from 3 to 4, the ReplicaSet controller would see that one new instance needs to be created and will make sure it is scheduled in one of the nodes on the cluster. This reconciliation process applies to any modified property of the pod template.
K8S supports the following controllers (at least those which I'm familiar with):
1 ) ReplicaSet controller.
2 ) DaemonSet controller.
4 ) Job controller.
5 ) Deployment controller.
6 ) StatefulSet controller.
7 ) Service controller.
8 ) Node controller.
9 ) Endpoints controller. # <---- Yes - its a valid controller.
10 ) Namespace controller. # <---- Yes - its a valid controller.
11 ) Serviceaccounts controller.
12 ) PersistentVolume controller.
13 ) More?
All resides in the control plane under a parent unit which is called the 'Controller Manager'.
Additional point
There is also a small difference in the syntax between Replica Controller:
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
And the ReplicaSet which contains matchLabels field under the selector:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels: #<-- This was added
tier: nginx

replication controllers are deprecated and is not recommended any more. Use ReplicaSets instead.
With ReplicaSet you define number of replicas you want to run for a specific application or a service. You would have those many replicas running at any point of time in the kubernetes cluster. It is taken care by ReplicaSet controller.

Related

If a Deployment in K8s creates replicas and a ReplicaSet, for you what is the point of creating a ReplicationController?

In the Kubernetes website it mentions
The following is an example of a Deployment. It 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
If it creates a ReplicaSet for you then for what reason would we create a new ReplicationController? Is that not duplicating something that exists?
I could just be confused as I'm still learning.
ReplicationController's updated version is ReplicaSet. ReplicaSet is considered as a replacement of replication controller. The key difference between the replica set and the replication controller is: replication controller only supports equality-based selector whereas the replica set supports set-based selector.
As far the k8s doc : ReplicaSet is the next-generation ReplicationController that supports the new set-based label selector. It's mainly used by Deployment as a mechanism to orchestrate pod creation, deletion and updates. Note that we recommend using Deployments instead of directly using Replica Sets, unless you require custom update orchestration or don't require updates at all.

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

kubernetes Service select multi labels

I have two StatefulSets named my-sts and my-sts-a, want to create a single service, that addresses same-indexed pods, from two different StatefulSets, like: my-sts-0 and my-sts-a-0. But found k8s doc says:
Labels selectors for both objects are defined in json or yaml files using maps, and only equality-based requirement selectors are supported
My idea is to create a label for the two sts pods like:
my-sts-0 has label abc:sts-0
my-sts-a-0 has label abc:sts-0
my-sts-1 has label abc:sts-1
my-sts-a-1 has label abc:sts-1
How to get the index of those pods so that I can create a label named abc=sts-<index> to approach it?
Is there any other way?
Kubernetes already gives you a DNS name to select individual StatefulSet pods. Say you have a Service my-sts that matches every pod in the StatefulSet, and the StatefulSet is set up with serviceName: my-sts; then you can access host names my-sts-0.my-sts.namespace.svc.cluster.local and so on.
If you specifically want a service to target a specific pod, there is also a statefulset.kubernetes.io/pod-name label that gets added automatically, so you can attach to that
apiVersion: v1
kind: Service
metadata:
name: my-sts-master
spec:
selector:
statefulset.kubernetes.io/pod-name: my-sts-0
ports: [...]

What is the behavior of Kubernetes if multiple ReplicaControllers have overlapping label selectors?

In Kubernetes, ReplicaController uses label selectors to specify which pod(s) it will operate on.
Now, my question is, if multiple ReplicaControllers have overlapping label selectors, what will be the behavior of the Kubernetes cluster? Or is it considered some kind of error and should be avoided?
For example, I have two ReplicationControllers described as below.
rc1.yaml:
apiVersion: v1
kind: ReplicationController
metadata:
name: frontend
spec:
replicas: 3
selector:
app: frontend
team: payment
rc2.yaml:
apiVersion: v1
kind: ReplicationController
metadata:
name: backend
spec:
replicas: 2
selector:
app: backend
team: payment
You can see that they both have the label selector team=payment, but one specifies a replica count of 3 while another of 2.
Any explanations or references will be appreciated. Thanks.
The Kubernetes docs state the following about overlapping selectors (either from other pods, replication controllers or jobs):
Also you should not normally create any pods whose labels match this selector, either directly, with another ReplicationController, or with another controller such as Job. If you do so, the ReplicationController thinks that it created the other pods. Kubernetes does not stop you from doing this.
If you do end up with multiple controllers that have overlapping selectors, you will have to manage the deletion yourself
In the docs about Deployments there is another statement that confirms the above:
If you have multiple controllers that have overlapping selectors, the controllers will fight with each other and won’t behave correctly.
So, in summary, you should try to avoid overlapping selectors for replication controllers, replica sets (the next-generation replication controller which I would advise you to use instead of replication controllers) and deployments because it might probably lead to severe problems as confirmed by this issue.

Kubernetes set deploment number of replicas based on namespace

I've split our Kubernetes cluster into two different namespaces; staging and production, aiming to have production deployments having two replicas (for rolling deployments, autoscaling comes later) and staging having one single replica.
Other than having one deployment configuration per namespace, I was wondering whether or not we could set the default number of replicas per deployment, per namespace?
When creating the deployment config, if you don't specify the number of replicas, it will default to one. Is there a way of defaulting it to two on the production namespace?
If not, is there a recommended approach for this which will prevent the need to have a deployment config per namespace?
One way of doing this would be to scale the deployment up to two replicas, manually, in the production namespace, once it has been created for the first time, but I would prefer to skip any manual steps.
It is not possible to set different number of replicas per namespace in one deployment.
But you can have 2 different deployment files 1 per each namespace, i.e. <your-app>-production.yaml and <your-app>-staging.yaml.
In these descriptions you can determine any custom values and settings that you need.
For an example:
<your-app>-production.yaml:
apiVersion: v1
kind: Deployment
metadata:
name: <your-app>
namespace: production #Here is namespace
...
spec:
replicas: 2 #Here is the count of replicas of your application
template:
spec:
containers:
- name: <your-app-pod-name>
image: <your-app-image>
...
<your-app>-staging.yaml:
apiVersion: v1
kind: Deployment
metadata:
name: <your-app>
namespace: staging #Here is namespace
...
spec:
replicas: 1 #Here is the count of replicas of your application
template:
spec:
containers:
- name: <your-app-pod-name>
image: <your-app-image>
...
I don't think you can avoid having two deployments, but you can get rid of the duplicated code by using helm templates (https://docs.helm.sh/chart_template_guide). Then you can define a single deployment yaml and substitute different values when you deploy with an if statement.
When creating the deployment config, if you don't specify the number of replicas, it will default to one. Is there a way of defaulting it to two on the production namespace?
Actually, there are two ways to do it, but both of them involved coding.
Admission Controllers:
This is the recommended way of assigning default values to fields.
While creating objects in Kubernetes, it passes through some admission controllers and one of them is MutatingWebhook.
MutatingWebhook has been upgraded to beta version since v1.9+. This admission controller modifies (mutates) the object before actully created (or modified/deleted), say, assigning default values of some fields and some similar task. You can change the minimum replicas number here.
User Have to implement a admission server to receive requests from kubernetes and give modified object as response accordingly.
Here is a sample admission server implemented by Openshift kubernetes-namespace-reservation.
Deployment Controller:
This is comparatively easier but kind of hacking the deployment procedure.
You can write a Deployment controller which will watch for deployment and if there is any deployment made, it will do some task. Here, you can update the deployment with some minimum values you wish.
You can see the official Sample Pod Controller.
If both of them seems lots to do, it is better to assign fields more carefully each time for each deployment.