Headless service for blue green or A/B deployment - kubernetes

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.

Related

Can I have multiple headless services for StatefulSet?

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

My understanding of headless service in k8s and two questions to verify

I am learning the headless service of kubernetes.
I understand the following without question (please correct me if I am wrong):
A headless service doesn't have a cluster IP,
It is used for communicating with stateful app
When client app container/pod communicates with a database pod via headless service the pod IP address is returned instead of the service's.
What I don't quite sure:
Many articles on internet explaining headless service is vague in my opinion. Because all I found only directly state something like :
If you don't need load balancing but want to directly connect to the
pod (e.g. database) you can use headless service
But what does it mean exactly?
So, following are my thoughts of headless service in k8s & two questions with an example
Let's say I have 3 replicas of PostgreSQL database instance behind a service, if it is a regular service I know by default request to database would be routed in a round-robin fasion to one of the three database pod. That's indeed a load balancing.
Question 1:
If using headless service instead, does the above quoted statement mean the headless service will stick with one of the three database pod, never change until the pod dies? I ask this because otherwise it would still be doing load balancing if not stick with one of the three pod. Could some one please clarify it?
Question 2:
I feel no matter it is regular service or headless service, client application just need to know the DNS name of the service to communicate with database in k8s cluster. Isn't it so? I mean what's the point of using the headless service then? To me the headless service only makes sense if client application code really needs to know the IP address of the pod it connects to. So, as long as client application doesn't need to know the IP address it can always communicate with database either with regular service or with headless service via the service DNS name in cluster, Am I right here?
A normal Service comes with a load balancer (even if it's a ClusterIP-type Service). That load balancer has an IP address. The in-cluster DNS name of the Service resolves to the load balancer's IP address, which then forwards to the selected Pods.
A headless Service doesn't have a load balancer. The DNS name of the Service resolves to the IP addresses of the Pods themselves.
This means that, with a headless Service, basically everything is up to the caller. If the caller does a DNS lookup, picks the first address it's given, and uses that address for the lifetime of the process, then it won't round-robin requests between backing Pods, and it will not notice if that Pod disappears. With a normal Service, so long as the caller gets the Service's (cluster-internal load balancer's) IP address, these concerns are handled automatically.
A headless Service isn't specifically tied to stateful workloads, except that StatefulSets require a headless Service as part of their configuration. An individual StatefulSet Pod will actually be given a unique hostname connected to that headless Service. You can have both normal and headless Services pointing at the same Pods, though, and it might make sense to use a normal Service for cases where you don't care which replica is (initially) contacted.
A headless service will return all Pod IPs that are associated through the selector. The order is not stable, so if a client is making repeated DNS queries and uses only the first returned IP, this will result in some kind of load balancing as well.
Regarding your second question: That is correct. In general, if a client does not need to know all instances - and handle the unstable IPs - a regular service provides more benefits.

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.

how to use consul as a default dns or service discovery in kubernetes

make Consul as default Service Discovery with Glider labs
registrator.
registrator is for registering all services in k8s cluster
First thing that comes to mind is : WHY?!?
Regardless, there is no "default service discovery" in kubernetes. Kubernetes has API where everything is created/registered/updated. That you can not take away unless you simply stop using Kubertnetes. You can run sidecar container for every pod though and use it to register to Consul service additionally. No idea why you would, but you can. Some software can follow similar pattern for it's own clustering coordination via separate instance where all it's instances register to.
If you rely on service IPs and DNS, and want to switch that to different service discovery, you can obviously select different DNS service IP then (Kube/Core)DNS and use ie. Consuls, but again, I see no reasonable use case for that.