Kubernetes Services
Last updated
Last updated
Being a resource will create a single, constant point of a group of Pods behind it. Each service will have a constant IP address and port, unless we delete it and create it again. The client will open a connection to the service, and that connection will be directed to one of the Pods in the background.
So what problems does service help us with? Each Pod also has its own IP address, so why don't we call it directly instead of going through the service without wasting time? To answer these questions, we will go over a few issues.
This means that a Pod is a very ephemeral resource, it will be created, deleted, and replaced with another at any time. Maybe when we want to change a different template for the Pod, the old Pod will be deleted. and the new Pod will be created. Or in case a woker node dies, the Pod on that worker node will also die, and a new Pod will be created on another woker node.
When creating a new pod, it will have a different IP from the old one. If we use the Pod's IP to create a connection to the client, then when the Pod is replaced with another IP, we must update the code.
This means we will have many pods running one of our applications to increase performance. For example, when we use ReplicaSet with replicas = 3, it will create 3 Pods. So how do we know which Pod to send requests to?
To solve the above problems, Kubernetes provides us with Services resource , the Service will create a constant endpoint for the Pods behind, the client only needs to interact with this endpoint.
How does the Service know which Pod it will choose to manage connections to those Pods, if you remember label selectors from previous articles and how ReplicaSet uses labels to manage Pods. Services will also use label selectors to select the Pod that manages the connection.
Sample config
Service will have 4 basic types:
ClusterIP
NodePort
ExternalName
LoadBalancer
This type of service will create an IP and local DNS that will be accessible inside the cluster, not accessible from the outside, used mainly for Pods inside the cluster to easily communicate with each other.
For example, we have an application that needs to use redis, we will deploy a redis Pod and our application needs to connect to that redis Pod. With redis, its connection string will look like this redis://<host-name>:<port>
, so how will our application connect to redis? Next we will make an example of creating Pod redis and Service for it.
Create a file named hello-service.yaml
kubectl apply -f hello-service.yaml
Now our redis will have the following access address redis://10.100.255.140:6379 . We can see that the hostname of our service here is 10.100.255.140 , we can use this address so that applications we deploy later can access the redis host.
So if we have applications already running, how can we connect to this host, or do we have to update the code? So to solve this problem, instead of accessing the redis host via IP, we can access it via DNS, kubernes provides us with a local DNS inside the cluster, helping us connect to our host. want to go through DNS. We can connect to redis with the following address redis://redis:6379 , with host name being the name of the Service we put in the metadata field .
Test the service. You can create a Pod to test using the config file
Or create using cli for quick
kubectl run hello-redis --image=080196/hello-redis
This is the application code in 080196/hello-redis image
Check the pod's log, if it prints Connect redis success , we have connected to the redis host using DNS
kubectl logs hello-redis
Clear resource
ClusterIP helps applications deployed in our cluster communicate with each other much easier. What if we want external clients to be able to access our application? There are 3 ways: using NodePort, LoadBalancer (supports cloud), Ingress.
This is the first way to expose the Pod so that external clients can access the Pod inside the cluster. Like ClusterIP, NodePort will also create an accessible endpoint inside the cluster by IP and DNS, and it will use a port of the entire worker node so that external clients can communicate with our Pod via through that port. NodePort will have a default range from 30000 - 32767. For example:
Clients can send requests to Pod using the address 130.211.97.55:30123 or 130.211.99.206:30123 . And the application inside the cluster can send requests to the Pod with the address http://hello-kube
Now let's create a NodePort service. Create a file named hello-nodeport.yaml
kubectl apply -f hello-nodeport.yaml
Test sends request to Pod with addresshttp://<your_worker_node_ip>:<node_port>
When you run kubernetes on the cloud, it will support LoadBalancer Service. If you run on an environment that does not support LoadBalancer, you cannot create this type of Service. When you create a LoadBalancer Service, it will create a public IP for us, so that clients can access the Pod inside the Cluster using this public IP address. For example
Ingress is a resource that allows us to expose HTTP and HTTPS routes from outside the cluster to services inside our cluster. Ingress will help us assign an actual domain to a service inside the cluster. For example:
We can also map multiple services to the same domain. For example:
Ingress is the most useful resource to expose Pod's HTTP and HTTPS to the outside. You can read more about Ingress here .