Introduction

In this new article we discuss about Services.

What is a Service ?

Once you have deployed your pods or deployments, you may want to be abel to configure a frontend which will find out and keep track of which IP address to connect to, so that the frontend can use the backend part of the workload. In Kubernetes, a 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 selector.

For example, consider a stateless image-processing backend which is running with 3 replicas. Those replicas are fungible—frontends do not care which backend they use. While the actual Pods that compose the backend set may change, the frontend clients should not need to be aware of that, nor should they need to keep track of the set of backends themselves.

How to create a Service

Using a configuration YAML file

As usual, we create the following YAML File with the following mandatory parts :

apiVersion: 
kind: 
metadata:


spec:

In our example, we suppose we have a set of Pods that each listen on TCP port 9376 and carry a label app=MyApp.

So let’s begin with these 4 sections :

  • The api version in our case is “v1”. (You can see that’s different from our previous lecture with PODs)
  • The kind will be Service, for obvious reasons
  • Metadata will contain the name of our service. It can obviously contain the namespace or labels.
  • Finally, the “spec” is the most important part of our YAML file. It will contain the port, the target port and the protocol used by our service.

Here is our final YAML file called myservice-1.yaml :

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

We can now deploy our Service running the following command :

$ kubectl create -f myservice-1.yaml
service/my-service created

And that’s all !

You can get more information on your Servic erunning the following command :

master $ kubectl describe services my-service
Name:              my-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=MyApp
Type:              ClusterIP
IP:                10.111.70.159
Port:              <unset>  80/TCP
TargetPort:        9376/TCP
Endpoints:         <none>
Session Affinity:  None
Events:            <none>

How to update a Service ?

You can easily update a Service using the following command :

master $ kubectl edit services my-service
#make your changes, i.e ports and save it

service/my-service edited

Or by editing your YAML File and apply it with :

kubectl apply -f myservice-1.yaml

How to expose your application onto an external IP address ?

For some parts of your application (for example, frontends) you may want to expose a Service onto an external IP address, that’s outside of your cluster.

Kubernetes ServiceTypes allow you to specify what kind of Service you want. The default is ClusterIP.

Type values and their behaviors are:

  • ClusterIP: Exposes the Service on a cluster-internal IP. This is the default ServiceType.
  • NodePort: Exposes the Service on each Node’s IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You’ll be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>.
  • LoadBalancer: Exposes the Service externally using a cloud provider’s load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.
  • ExternalName: Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record

NodePort Type

One of the most used type is definitively the NodePort one. As explained previously, it will expose the service on each Node’s IP at a static port. Here is an example :

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: MyApp
  ports:
      
      # By default and for convenience, 
      # the `targetPort` is set to the same value as the `port` field.
    - port: 80
      targetPort: 80
      
      # Optional field
      # By default and for convenience, the Kubernetes control 
      # plane will allocate a port from a range (default: 30000-32767)
      nodePort: 30007

Sources

kubernetes.io

Leave a Comment

Your email address will not be published. Required fields are marked *