kubernetes services

What are kubernetes services used for?

  • kubernetes pods are ephemeral (can be deleted or moved)
  • kubernetes assigns an IP address on the fly, so it’s not possible to know in advance
  • application’s client should not know the kubernetes pods IP addresses
  • enter kubernetes services
  • each kubernetes service has an IP address (and an associated port) that does not change as long as the service exists

  • by default, the .spec.type is ClusterIP
  • a kubernetes service can expose multiple ports

Service discovery

  • each kubernetes service is available with FQDN: <service_name>.<namespace>.svc.cluster.local
  • inside the same namespace, each kubernetes service is available with only <service_name>

Endpoints

Example:

---
apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  ports:
    - port: 80
      targetPort: 8080
---
apiVersion: v1
kind: Endpoints
metadata:
  name: whoami
subsets:
  - addresses:
    - ip: 1.2.3.4
    - ip: 5.6.7.8
  ports:
    - port: 8080
$ kubectl get endpoints whoami
NAME     ENDPOINTS                  AGE
whoami   1.2.3.4:80,5.6.7.8:80      21s

External service

  • we can reference an external service (i.e. not hosted in k8s)
  • create an external service using spec.externalName if the external service has a DNS
  • if no DNS or a port redirection is needed, we can:

Expose a service to external clients

Hostport

apiVersion: v1
kind: Pod
metadata:
  name: nginx-squat
spec:
  containers:
    - name: port-squatter
      image: nginx:alpine
      ports:
        - name: exposed
          hostPort: 9080
          containerPort: 80
  • spec.containers.ports.hostPort will reserved on the cluster node where the pod will be run for the service

Nodeport

apiVersion: v1
kind: Service
metadata:
  name: whoami-nodeport
spec:
  type: NodePort
  selector:
    app: whoami
  ports:
    - nodePort: 30123
      port: 8080
      targetPort: 80
  • k8s will reserved a port on ALL nodes and redirect traffic on this port to the targeted service
  • ℹ️ a ClusterIP will also be created for internal communication
$ kubectl get svc whoami
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
whoami      NodePort    10.102.245.91   <none>        8080:30123/TCP   19m
  • NodePort range is defined at cluster level (by default, from 30000 - 32767)

Loadbalancer

  • k8s will interact with the APIs of the Cloud provider (AWS, Azure, GCP)
  • asynchronous configuration/provision
---
apiVersion: v1
kind: Service
metadata:
  name: whoami
  labels:
    app: whoami
    level: expert
spec:
  type: LoadBalancer
  selector:
    app: whoami
    level: expert
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 80

Headless services

Sometimes, a client needs the kubernetes pod ips (e.g. Netflix Ribbon). To mitigate this, k8s offers a Headless service.

  • no ClusterIP will be created
  • DNS resolution will return all the kubernetes pod IPs will be returned
---
apiVersion: v1
kind: Service
metadata:
  name: whoami-headless
  labels:
    app: whoami
    level: expert
spec:
  selector:
    app: whoami
    level: expert
  clusterIP: None
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 80

Port forward

It’s also possible to access to a kubernetes pod without passing into a kubernetes service, e.g. for debugging purpose, with kubectl port-forward:

$ kubectl port-forward whoami 8080:80
Forwarding from 127.0.01:8080 -> 80
Handling connection for 8080