Hello and welcome to this lecture. In this lecture
we will discuss about service networking. In the previous lectures
we talked about POD networking. How bridge networks are created within each node and how PODs get a
namespace created for them and how interfaces are attached to those name spaces and how parts get an
IP address assigned to them within the subnet assigned for that note.
And we also saw through routes or other overlay techniques, we can get the PODs in different nodes to talk
to each other forming a large virtual network where all pods can reach each other.
Now you would rarely configure your pods to communicate directly with each other.
If you want a pod to access services hosted on another pod you would always use a service.
Let's quickly recap the different kinds of services. To make the orange pod accessible to the blue pod,
we create an orange service. The orange service gets an IP address and a name assigned to it.
The blue pod can now access the orange pod through the orange services IP or its name.
We'll talk about name resolution in the upcoming lectures.
For now let's just focus on IP addresses. The blue and orange pod around the same node.
What about access from the other PODs
on other nodes? when a service is created it is accessible from all parts of the cluster, irrespective
of what nodes the pods are on. While a pod is hosted on a node, a service is hosted across the cluster.
It is not bound to a specific node. But remember, the service is only accessible from within the cluster.
This type of service is known as ClusterIP.
If the orange POD was hosting a database application that is to be only accessed from within the cluster,
then this type of service works just fine.
Say for instance the purple pod was hosting a web application. To make the application on the pod accessible
outside the cluster.
we create another service of type NodePort.
This service also gets an IP address assigned to it and works just like ClusterIP. As in all the other
PODs can access this service using it’s IP.
But, in addition it also exposes the application on a port on all nodes in the cluster. That way external
users or applications have access to the service.
So that's the topic of our discussion for this lecture.
Our focus is more on services and less on PODs.
How are the services getting these IP addresses and how are they made available across all the nodes
in the cluster.
How is the service made available to external users through a port on each node.
Who is doing that and how and where do we see it.
So let's get started.
Let's start on a clean slate.
We have a three node cluster, no pods or services yet.
We know that every kubernetes node runs a kubelet process, which is responsible for creating PODs. Each
kubelet service on each node
watches the changes in the cluster through the kube-api server,
and every time a new POD is to be created, it creates the POD on the nodes.
It then invokes the CNI plugin to configure networking for that POD.
Similarly, each node runs another component known as kube-proxy. Kube
proxy watches the changes in the cluster through kube-api server, and every time a new service is to be created,
kube-proxy gets into action. Unlike PODs, services are not created on each node or assigned to each node.
Services are a cluster wide concept.
They exist across all the nodes in the cluster.
As a matter of fact they don't exist at all.
There is no server or service really listening on the IP of the service. We have seen that
PODs have containers and containers have namespaces with interfaces and Ips assigned to those interfaces.
With services
Nothing like that exists.
There are no processes or name spaces or interfaces for a service.
It's just a virtual object.
Then how do they get an IP address
and how were we able to access the application on the pod through service?
When we create a service object in kubernetes, it is assigned an IP address from a pre-defined range.
The kube-proxy components running on each node, get’s that IP address and creates forwarding rules on
each node in the cluster, saying any traffic coming to this IP, the IP of the service, should go to the
IP of the POD.
Once that is in place, whenever a POD tries to reach the IP of the service, it is forwarded to the PODs
IP address which is accessible from any node in the cluster.
Now remember it's not just the IP it's an IP and port combination.
Whenever services are created or deleted the kube-proxy component creates or deletes these rules.
So how are these rules created? kube-proxy supports different ways, such as userspace where kube-proxy
listens on a port for each service and proxies connections to the pods. By creating ipvs rules or
the third and the default option and the one familiar to us is using IP tables. The proxy mode can be
set using the proxy mode option while configuring the kube-proxy service
If this is not set, it defaults to iptables. So we’ll see how iptables are configured by kube-proxy and
how you can view them on the nodes.
We have a pod named db deployed on node-1.
it has IP address 10.244.1.2. We create a service of type ClusterIP to make this pod
available within the cluster.
When the service is created kubernetes assigns an IP address to it.
It is set to 10.103.132.104
This range is specified in the kube-apiservers
option called service-cluster-ip-range. Which is by default set to 10.0.0.0/24.
In my case, if I look at my kube-api-server option. I see it is set to 10.96.0.0/12.
That gives my services IP any where from 10.96.0.0 to 10.111.255.255. A relative
point to mention here.
when I setup my POD networking, I provided a POD network CIDR range of 10.244.0.0/16
which gives my pods IP addresses from 10.244.0.0 to 10.244.255.255.
The reason I brought this up here is because whatever range is specified for each of these networks
it shouldn't overlap which it doesn't
in this case. Both of these should have its own dedicated range of IPs to work with. There shouldn't
be a case where a POD and a service are assigned the same IP address.
So getting back to services.
that’s how my service got an IP address of 10.103.132.104.
You can see the rules created by kube-proxy in the iptables
nat table output.
Search for the name of the service as all rules created by kube-proxy
have a comment with the name of the service on it.
These rules mean, any traffic going to IP address 10.103.132.104 on port 3306
which is the IP of the service, should have its destination address changed to 10.244.1.2 and port 3306 which is the IP of the POD.
This is done by adding a DNAT rule to IP tables.
Similarly, when you create services of type NodePort, kube-proxy creates IPTable rules to forward all
traffic coming on a port on all nodes to the respective backend PODs.
You can also see kube-proxy create these entries in the kube-proxy logs itself. In the logs
you will find what proxier it uses, in this case its IP tables and the Add an entry when it added
a new service for the database.
Note that the location of this file might vary depending on your installation.
If you don't see these entries you must also check the verbosity level of the process as well.
Well that's it about service networking.
I will see you in the next lecture.