Can I have multiple headless services for StatefulSet? - kubernetes

In kubernetes, is it somehow possible to "assign" multiple headless services to single statefulset, or achieve behaviour describe below some other way?
Use-case:
We've got statefulset, let's call it: set. It has 3 pod, and headless service called set-headless.
It is possible to access pods, using following dns names:
set-0.set-headless.namespace.svc.cluster.local
set-1.set-headless.namespace.svc.cluster.local
set-2.set-headless.namespace.svc.cluster.local
For some reasons, we would like to change this endpoints, to i.e. contain some more information in headless service name - set-uswest1-headles.
To accomplish this change without downtime, it would be perfect, to have two headless services running at the same time, so pods could be accessible by following dns names:
set-0.set-headless.namespace.svc.cluster.local
set-1.set-headless.namespace.svc.cluster.local
set-2.set-headless.namespace.svc.cluster.local
set-0.set-uswest1-headless.namespace.svc.cluster.local
set-1.set-uswest1-headless.namespace.svc.cluster.local
set-2.set-uswest1-headless.namespace.svc.cluster.local
Is it possible at all? Can this be achieved some other way (not using headless servic

Yes, it all depends on the labels applied to each statefulSet/Pod that will add that pod to the headless service endpoints.
You can have one headless service to route to all the pods, and 1 for each set of different set of pods
EDIT: For your use case, in order to not have downtime, its important that both of the headless services has the same labels.
Also, its important to remember that headless services are for pods in the same statefulset to communicate with each other and services are used for pods to be reached from other services. So in case you need the pods to be reached by other services/ingress you need the same labels applied to both services and satefulsets for no downtime.
Or you could explain what kind of service is this and i can help you with specific actions for that kind of service

Related

Why headless services are not recommended in stateless applications?

I'm a kubernetes beginner and I found that headless service is generally recommended for stateful applications, so I'm wondering why it can't be used in stateless again? Is it bad that requests should be faster if they go directly to the Pod and not through the Service?
A regular Service provides you with a single, stable, IP address to access any of the replicas associated to the Service.
Given that the application is really stateless, it does not matter which replica you talk to, so the "hiding" behind a single IP.
This relieves you of the responsibility of load balancing: You can just use the very same IP every time and don't have to handle added replicas, removed replicas or repeated DNS lookups.
If you would use a headless service for a stateless application, which is of course possible, you would have to handle all that or risk that the replicas do not deliver scaling and/or high-availability as intended.
In fact a headless service shuffles the order of returned records when performing a DNS looup to help clients with the load balancing, if they can't handle it themself. But you have to perform regular DNS lookups for headless services to learn about added and/or removed instances, which is not the case for a regular service with a service IP.
First of all Headless services are vaguely used to access all the
pod replicas directly instead of using the Services.
In the case of deployment(Stateless services) the pods are
interchangeable because if the pod needs to reschedule it wont
maintain the same id as the previous pod.
Whereas the Statefulsets maintain a unique ID for each pod.
Statefulsets provide 2 unique identities for each pod. First Network
Identity which helps us to give the same DNS name to the pod
regardless of numerous restarts and second is the Storage Identity,
it will also remain the same regardless of the restarts. So,
statefulset won’t use the shared volume.
An IP address is not assigned to a headless service. Internally, it
builds the required endpoints for DNS-named pod exposure.
Conclusion: Pods having a distinct identity are required for stateful applications (hostname). To communicate one pod with other pods a StatefulSet requires a Headless Service. A service with a service IP is a headless service. As a result, it immediately returns the IPs of our related pods. This enables us to communicate with the pods directly instead of using a proxy. Whereas in stateless applications a Service is required to interact with other pods.
For more detailed information refer to this article

Headless service for blue green or A/B deployment

How can we make headless service work in case of blue-green or A/B deployment?
The service id moves across when we do the switch but how can we make application aware of it?
Unfortunately, it is not possible to create blue/green deployment using the headless service. This is, beacuse:
Sometimes you don't need load-balancing and a single Service IP. In this case, you can create what are termed "headless" Services, by explicitly specifying "None" for the cluster IP (.spec.clusterIP).
However, if you want to create a blue/green deployment, you need a network traffic control tool to switch between pods. You can also read more here:
If working with headless services, traffic splits cannot be retrieved. Linkerd reads service discovery information based off the target IP address, and if that happens to be a pod IP address then it cannot tell which service the pod belongs to.

What exactly Kubernetes Services are and how they are different from Deployments

After reading thru Kubernetes documents like this, deployment , service and this I still do not have a clear idea what the purpose of service is.
It seems that the service is used for 2 purposes:
expose the deployment to the outside world (e.g using LoadBalancer),
expose one deployment to another deployment (e.g. using ClusterIP services).
Is this the case? And what about the Ingress?
------ update ------
Connect a Front End to a Back End Using a Service is a good example of the service working with the deployment.
Service
A deployment consists of one or more pods and replicas of pods. Let's say, we have 3 replicas of pods running in a deployment. Now let's assume there is no service. How does other pods in the cluster access these pods? Through IP addresses of these pods. What happens if we say one of the pods goes down. Kunernetes bring up another pod. Now the IP address list of these pods changes and all the other pods need to keep track of the same. The same is the case when there is auto scaling enabled. The number of the pods increases or decreases based on demand. To avoid this problem services come into play. Thus services are basically programs that manages the list of the pods ip for a deployment.
And yes, also regarding the uses that you posted in the question.
Ingress
Ingress is something that is used for providing a single point of entry for the various services in your cluster. Let's take a simple scenario. In your cluster there are two services. One for the web app and another for documentation service. If you are using services alone and not ingress, you need to maintain two load balancers. This might cost more as well. To avoid this, ingress when defined, sits on top of services and routes to services based on the rules and path defined in the ingress.

How DNS service works in the Kubernetes?

I am new to the Kubernetes, and I'm trying to understand that how can I apply it for my use-case scenario.
I managed to install a 3-node cluster on VMs within the same network. Searching about K8S's concepts and reading related articles, still I couldn't find answer for my below question. Please let me know if you have knowledge on this:
I've noticed that internal DNS service of K8S applies on the pods and this way services can find each other with hostnames instead of IPs.
Is this applicable for communication between pods of different nodes or this is only within the services inside a single node? (In other words, do we have a dns service on the node level in the K8S, or its only about pods?)
The reason for this question is the scenario that I have in mind:
I need to deploy a micro-service application (written in Java) with K8S. I made docker images from each service in my application and its working locally. Currently, these services are connected via pre-defined IP addresses.
Is there a way to run each of these services within a separate K8S node and use from its DNS service to connect the nodes without pre-defining IPs?
A service serves as an internal endpoint and (depending on the configuration) load balancer to one or several pods behind it. All communication typically is done between services, not between pods. Pods run on nodes, services don't really run anything, they are just routing traffic to the appropriate pods.
A service is a cluster-wide configuration that does not depend on a node, thus you can use a service name in the whole cluster, completely independent from where a pod is located.
So yes, your use case of running pods on different nodes and communicate between service names is a typical setup.

Why don't Kubernetes deployments support services?

I'm new to K8s, so still trying to get my head around things. I've been looking at deployments and can appreciate how useful they will be. However, I don't understand why they don't support services (only replica sets and pods).
Why is this? Does this mean that services would typically be deployed outside of a deployment?
To answer your question, Kubernetes deployments are used for managing stateless services running in the cluster instead of StatefulSets which are built for the stateful application run-time. Actually, with deployments you can describe the update strategy and road map for all underlying objects that have to be created during implementation.Therefore, we can distinguish separate specification fields for some objects determination, like needful replica number of Pods, template for Pod by describing a list of containers that should be in the Pod, etc.
However, as #P Ekambaram already mention in his answer, Services represent abstraction layer of network communication model inside Kubernetes cluster, and they declare a way to access Pods within a cluster via corresponded Endpoints. Services are separated from deployment object manifest specification, because of their mission to dynamically provide specific network behavior for the nested Pods without affecting or restarting them in case of any communication modification via appropriate Service Types.
Yes, services should be deployed as separate objects. Note that deployment is used to upgrade or rollback the image and works above ReplicaSet
Kubernetes Pods are mortal. They are born and when they die, they are not resurrected. ReplicaSets in particular create and destroy Pods dynamically (e.g. when scaling out or in). While each Pod gets its own IP address, even those IP addresses cannot be relied upon to be stable over time. This leads to a problem: if some set of Pods (let’s call them backends) provides functionality to other Pods (let’s call them frontends) inside the Kubernetes cluster, how do those frontends find out and keep track of which backends are in that set?
Services.come to the rescue.
A Kubernetes Service is an abstraction which defines a logical set of Pods and a policy by which to access them. The set of Pods targeted by a Service is (usually) determined by a Label Selector
Something I've just learnt that is somewhat related to my question: multiple K8s objects can be included in the same yaml file, separate by ---. Something like:
apiVersion: v1
kind: Deployment
# other stuff here
---
apiVersion: v1
kind: Service
# other stuff here
i think it intends to decoupled and fine-grained.