Kubernetes - Getting IPs of pods of a proxy service - kubernetes

I have a proxy service that wraps 3 pods (say pod A, pod B, pod C). Some container inside pod A needs to get virtual IPs of other two pods. How can I do this?

Two options:
Talk to the Kubernetes API to get the endpoints for the service. (either with kubectl get endpoints SVCNAME or by GETing the /api/v1/namespaces/{namespace}/endpoints/{svcname} path on the apiserver)
Less likely to be of use, but if you create a service without a cluster IP, the DNS for that service will return a list of the IP addresses of the backing pods rather than a virtual IP address.
The IPs returned in either case are the IP addresses of all the pods backing the service.

Related

Pod with ClusterIP had a different IP than static IP of ingress

I'm managing a small Kubernetes cluster on Azure with Postgres. This cluster is accessible through an Nginx controller with a static IP.
The ingress routes to a ClusterIP to a pod which uses a Postgres instance. This Postgres instance has all IPs blocked, with a few exceptions for my own IP and the static IP of the ingress.
This worked well until I pushed an update this morning, where to my amazement I see in the logs an error that the pods IP address differs from the static ingress IP, and it has a permission error because of it.
My question: how is it possible that my pod, with ClusterIP, has a different outer IP address than the ingress static IP I assigned it?
Note that the pod is easily reached, through the Ingress.
Ingresses and Services handle only incoming pod traffic. Pod outgoing traffic IP depends on Kubernetes networking implementation you use. By default all outgoing connections from pods are source NAT-ed on node level which means pod will have an IP of node which it runs on. So you might want to allow worker node IP addresses in your Postgres.

Kubernetes: How to allow two pods running in same/different namespace communicate irrespective of the protocol using a servicename?

Allow two pods (say pod A and B) running in same/different namespace communicate irrespective of the protocol(say http,https,akka.tcp) along with a valid Network policy applied.
Solutions tried:
Tried applying network policy to both the pods and also used the service name: “my-svc.my-namespace.svc.cluster.local” to make pod B
communicate to pod A which is running the service “my-svc” but both
failed to communicate.
Also tried adding the IP address and host mapping of pod A in pod B while it’s deployment, then pod B was able to communicate to pod A
but inverse communication is failing.
Kindly suggest me a way to fix this.
By default, pods can communicate with each other by their IP address, regardless of the namespace they're in.
You can see the IP address of each pod with:
kubectl get pods -o wide --all-namespaces
However, the normal way to communicate within a cluster is through Service resources.
A Service also has an IP address and additionally a DNS name. A Service is backed by a set of pods. The Service forwards requests to itself to one of the backing pods.
The fully qualified DNS name of a Service is:
<service-name>.<service-namespace>.svc.cluster.local
This can be resolved to the IP address of the Service from anywhere in the cluster (regardless of namespace).
For example, if you have:
Namespace ns-a: Service svc-a → set of pods A
Namespace ns-b: Service svc-b → set of pods B
Then a pod of set A can reach a pod of set B by making a request to:
svc-b.ns-b.svc.cluster.local
You can put the Pods behind Services and use Service DNS for communication. Calls to service-name allow Pods in the same namespace to communicate. Calls to service-name.namespace allow Pods in different namespaces to communicate.

What is the use of Kubernetes cluster?

Every where its mentioned "cluster type of service makes pod accessible within a Kubernetes cluster"
Does it mean, after adding cluster service to a POD, then that POD can be connected only using cluster service IP of POD, we will not be able to connect POD using the IP of POD generated before adding cluster ?
Please help me understanding, am learning Kubernetes so.
When a service is created using the ClusterIP then that service is accessible only inside the cluster as service IP's are virtual IP.
Although if you want to access the pod from outside using the service IP then you can use the nodeport or loadbalancer type service which will allow you to access the pod using the Node's IP or the loadbalancer's IP.
Main reason behind using services to access pod is that it give a fixed location (ClusterIP or service name) to access. Pod's can come an go but service IP will remain same.

Do Cluster IP and Node Port IP addresses load balance between different nodes?

I have an app deployment called 'backend-app' running in pods that are on several different nodes. I also have a service that exposes the 'backend-app' to be accessed by other cluster internal pods as my 'frontend-app' pods.
If I use DNS to connect to the 'backend-app' from my different app deployment called 'frontend-app' will the requests be load balanced to each 'backend-app' pod on each node?
It sounds like a NodePort service will only connect to one node and not load balance my requests to others.
For each Service with type: NodePort a port is opened on all nodes (the same port on each). The port is open whether a pod of that service is running on a node or not. The load balancing is done among all pods of all nodes with no preference to a pod that happens to run on the same node to which you connected on the node port (if there is one there at all).
Services automatically load balance to the pods that are assigned to them. See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#creating-a-service.
The cluster IP address that is created with a service is the IP address that will automatically select an available pod on any node that is running the pod. You can find the service's cluster IP address by using a DNS lookup.
My confusion came because I didn't realise the cluster IP address was associated with a service, not with a specific Pod.
I'm currently not sure about how NodePort's work with this though.

How to discover headless service endpoints

Is there a way to discover all the endpoints of a headless service from outside the cluster?
Preferably using DNS or Static IPs
By watching changes to a list of Endpoints:
GET /api/v1/watch/namespaces/{namespace}/endpoints
Headless Services are a group of Pod IPs. Pod IPs are not (generally) available outside the cluster/cloud-provider.
Are you trying to get external IPs for a headless service or are you within the same network (e.g. in the GCE project) but not in the cluster?
The DNS addon is exactly what you're after. From the docs:
For example, if you have a Service called "my-service" in Kubernetes
Namespace "my-ns" a DNS record for "my-service.my-ns" is created. Pods
which exist in the "my-ns" Namespace should be able to find it by
simply doing a name lookup for "my-service". Pods which exist in other
Namespaces must qualify the name as "my-service.my-ns". The result of
these name lookups is the cluster IP.
And in the case of a headless service:
DNS is configured to return multiple A records (addresses) for the
Service name, which point directly to the Pods backing the Service.
However, this service is only available inside the cluster. But KubeDNS is just another pod:
kubectl get po --namespace=kube-system
kubectl describe po kube-dns-pod-name --namespace=kube-system
Which means you can create a service with an externally accessible address to expose this service. Just use a selector matching your kube-dns pod label.
http://kubernetes.io/v1.1/docs/user-guide/services.html#dns
https://github.com/kubernetes/kubernetes/blob/release-1.1/cluster/addons/dns/README.md