Services: K8S

Saurabh Sharma

There are multiple Kubernetes objects we will be talking about in this blog. Mainly Services, Selectors and Labels.

  • Service is an abstraction which defines a logical set of Pods and a policy by which to access them.
  • A Service in Kubernetes is a REST object, similar to a Pod.
  • Service tags the pods, logically grouping them using selectors.
  • Pods have a lifecycle, they are born, they live, process and then they die. The pods (desired state) can be managed using deployment.
  • A label is an identifying attribute of an object, and can be defined at the creation time, and subsequently modified and added at any time.
  • Label selector is a grouping primitive in Kubernetes and allows client/user to identify a set of objects. There are two sets of selectors
    • equality-based and
    • set-based.

An abstract way to expose an application running on a set of Pods as a network service.

The set of Pods targeted by a Service is usually determined by a selector.

Labels are key/value pairs that are attached to objects, such as pods at the time of creation.

Labels allow for efficient queries and watches. Let’s learn by example. I will try and crate a NGINX pod and expose the port using a service. A simple exercise?

Step – 1: Define the Pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: my-pod
    author: saurabh
spec:
  containers:
  - name: nginx-pod-container
    image: nginx:latest

The above definition has labels applied to the pod, which will be used while creating a service and will be used in the selector.

k describe pod nginx-pod
Name:               nginx-pod
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               ip-10-0-1-103/10.0.1.103
Start Time:         Fri, 21 Aug 2020 16:49:20 +0000
Labels:             app=my-pod
                    author=saurabh
Annotations:        kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"my-pod","author":"saurabh"},"name":"nginx-pod","namespace":"...
Status:             Running
IP:                 10.244.2.3

You can use the labels for selectors as under

k get pods -lapp=my-pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          14m

you can combine labels as well

k get pods -lapp=my-pod,author=saurabh
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          15m
k get pods -l 'app in (my-pod,my-name)'
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          16m

Each object in your cluster has a Name that is unique for that type of resource. Every Kubernetes object also has a UID that is unique across your whole cluster.

Step – 2: Define the service

Let’s create the service to expose the pod.

apiVersion: v1
kind: Service
metadata:
  name: my-svc
spec:
  type: NodePort
  selector:
    app: my-pod
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80                 

A Service can map any incoming port to a targetPort. By default and for convenience, the targetPort is set to the same value as the port field.

k describe svc my-svc
Name:              my-svc
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"my-svc","namespace":"default"},"spec":{"ports":[{"port":8080,"tar...
Selector:          app=my-pod
Type:              ClusterIP
IP:                10.102.126.164
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.4:80
Session Affinity:  None
Events:            <none>

You can validate the service for endpoints

k get ep
NAME         ENDPOINTS                                 AGE
my-svc       10.244.2.4:80                             6m37s

I can also define the type of Service


apiVersion: v1
kind: Service
metadata:
  name: my-svc
spec:
  type: NodePort
  selector:
    app: my-pod
  ports:
    - port: 8080
      targetPort: 80

and recreate the service.

NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
my-svc       NodePort    10.110.6.32      <none>        8080:31676/TCP   2m50s

References

  • https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
  • https://kubernetes.io/docs/concepts/overview/components/#kube-apiserver
  • https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
  • https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types