Files
container.training/slides/k8s/service-types.md
2023-01-13 17:50:22 +01:00

7.0 KiB

Service Types

  • There are different types of services:

    ClusterIP, NodePort, LoadBalancer, ExternalName

  • There are also headless services

  • Services can also have optional external IPs

  • There is also another resource type called Ingress

    (specifically for HTTP services)

  • Wow, that's a lot! Let's start with the basics ...


ClusterIP

  • It's the default service type

  • A virtual IP address is allocated for the service

    (in an internal, private range; e.g. 10.96.0.0/12)

  • This IP address is reachable only from within the cluster (nodes and pods)

  • Our code can connect to the service using the original port number

  • Perfect for internal communication, within the cluster


class: pic


class: pic


class: pic


class: pic


LoadBalancer

  • An external load balancer is allocated for the service

    (typically a cloud load balancer, e.g. ELB on AWS, GLB on GCE ...)

  • This is available only when the underlying infrastructure provides some kind of "load balancer as a service"

  • Each service of that type will typically cost a little bit of money

    (e.g. a few cents per hour on AWS or GCE)

  • Ideally, traffic would flow directly from the load balancer to the pods

  • In practice, it will often flow through a NodePort first


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


class: pic


NodePort

  • A port number is allocated for the service

    (by default, in the 30000-32767 range)

  • That port is made available on all our nodes and anybody can connect to it

    (we can connect to any node on that port to reach the service)

  • Our code needs to be changed to connect to that new port number

  • Under the hood: kube-proxy sets up a bunch of iptables rules on our nodes

  • Sometimes, it's the only available option for external traffic

    (e.g. most clusters deployed with kubeadm or on-premises)


class: extra-details

ExternalName

  • Services of type ExternalName are quite different

  • No load balancer (internal or external) is created

  • Only a DNS entry gets added to the DNS managed by Kubernetes

  • That DNS entry will just be a CNAME to a provided record

Example:

kubectl create service externalname k8s --external-name kubernetes.io

Creates a CNAME k8s pointing to kubernetes.io


class: extra-details

External IPs

  • We can add an External IP to a service, e.g.:

    kubectl expose deploy my-little-deploy --port=80 --external-ip=1.2.3.4
    
  • 1.2.3.4 should be the address of one of our nodes

    (it could also be a virtual address, service address, or VIP, shared by multiple nodes)

  • Connections to 1.2.3.4:80 will be sent to our service

  • External IPs will also show up on services of type LoadBalancer

    (they will be added automatically by the process provisioning the load balancer)


class: extra-details

Headless services

  • Sometimes, we want to access our scaled services directly:

    • if we want to save a tiny little bit of latency (typically less than 1ms)

    • if we need to connect over arbitrary ports (instead of a few fixed ones)

    • if we need to communicate over another protocol than UDP or TCP

    • if we want to decide how to balance the requests client-side

    • ...

  • In that case, we can use a "headless service"


class: extra-details

Creating a headless services

  • A headless service is obtained by setting the clusterIP field to None

    (Either with --cluster-ip=None, or by providing a custom YAML)

  • As a result, the service doesn't have a virtual IP address

  • Since there is no virtual IP address, there is no load balancer either

  • CoreDNS will return the pods' IP addresses as multiple A records

  • This gives us an easy way to discover all the replicas for a deployment


class: extra-details

Services and endpoints

  • A service has a number of "endpoints"

  • Each endpoint is a host + port where the service is available

  • The endpoints are maintained and updated automatically by Kubernetes

.lab[

  • Check the endpoints that Kubernetes has associated with our blue service:
    kubectl describe service blue
    

]

In the output, there will be a line starting with Endpoints:.

That line will list a bunch of addresses in host:port format.


class: extra-details

Viewing endpoint details

  • When we have many endpoints, our display commands truncate the list

    kubectl get endpoints
    
  • If we want to see the full list, we can use one of the following commands:

    kubectl describe endpoints blue
    kubectl get endpoints blue -o yaml
    
  • These commands will show us a list of IP addresses

  • These IP addresses should match the addresses of the corresponding pods:

    kubectl get pods -l app=blue -o wide
    

class: extra-details

endpoints not endpoint

  • endpoints is the only resource that cannot be singular
$ kubectl get endpoint
error: the server doesn't have a resource type "endpoint"
  • This is because the type itself is plural (unlike every other resource)

  • There is no endpoint object: type Endpoints struct

  • The type doesn't represent a single endpoint, but a list of endpoints


class: extra-details

Ingress

  • Ingresses are another type (kind) of resource

  • They are specifically for HTTP services

    (not TCP or UDP)

  • They can also handle TLS certificates, URL rewriting ...

  • They require an Ingress Controller to function


class: pic


class: pic


class: pic


class: pic

???

:EN:- Service types: ClusterIP, NodePort, LoadBalancer

:FR:- Différents types de services : ClusterIP, NodePort, LoadBalancer