Service is an important and useful concept in Kubernetes. We can use Service to group pods and provide an extranet access endpoint. Kube-proxy also provides access to services in the process.

Connecting Users to Pods

If we want a user to be able to use the application, the user needs to be able to access the POD, but the POD is a transient thing, it can suddenly hang up and restart, and then the IP address changes, so the POD IP address is not static. Such as:

The user can’t access it because the user doesn’t know what the new IP address is.

To solve this problem, Kubernetes provides a high-level abstraction called Service. Service logically groups pods and sets access policies. Normally, we do grouping by label and selector.

Services

For example, we use app as key and DB and frontend as value to distinguish pod:

By using selector (app=frontend and app=db), we can divide these pods into two logical groups.

Frontend – SVC and db-svc = service; frontend- SVC = service;

Service Object Model

A service object model looks like this:

kind: Service
apiVersion: v1
metadata:
  name: frontend-svc
spec:
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
Copy the code

In this object model, we create a Service called frontend-svc that selects all the pods for app=frontend. By default, each service has a cluster-accessible IP address, also known as a ClusterIP:

Users can now access the POD using the IP address of the Service, which does the load balancing.

When forwarding requests, we can select the destination port on the POD. In our example, frontend- SVC accepts requests through port 80 and forwards them to port 5000 of the POD. If the destination port is not explicitly declared, it is forwarded by default to the port where the service receives the request (just like the service port).

A pod, IP address, and destination port tuple represent the endpoint of a service. In this example, frontend- SVC has three endpoints. They are 10.0.1.3:5000, 10.0.1.4:5000 and 10.0.1.5:5000 respectively.

kube-proxy

All worker nodes have a background task called kube-proxy. The Kube-proxy detects additions and removals of services and endpoints on the API Server. For each new service, on each node, Kube-Proxy sets the corresponding iptables rules to record the addresses that should be forwarded. When a service is deleted, Kube-proxy removes the iptables rules on all pods.

Service discovery

We already know that services are the main way to communicate with Kubernetes, so we need a way to discover existing services at runtime. Kubernetes offers two approaches:

The environment variable

When each pod starts on the worker node, Kubelet passes in information about all currently available services via environment variables. For example, if we have a service called Redis-Master that exposes port 6379 and the ClusterIP is 172.17.0.6, we can see the following environment variables on a newly created POD:

REDIS_MASTER_SERVICE_HOST=172.17. 06.
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp:/ / 172.17.0.6:6379
REDIS_MASTER_PORT_6379_TCP=tcp:/ / 172.17.0.6:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=172.17. 06.
Copy the code

If we use this solution, we have to be very careful about the order in which services are started, because the POD doesn’t get the ENV of the service it started.

DNS

Some DNS kubernetes addon, these addon automatically for all service to create a similar my – SVC. My – namespace. SVC. Cluster. The local DNS resolution, In addition, services in the same namespace can be directly accessed by the service name. This is the most recommended method.

The Service type

When we define a service, we can choose the accessible scope, for example:

  • Whether it can only be accessed within the cluster
  • Whether the cluster can be accessed both internally and externally
  • Whether the mapping is to an entity outside the cluster

The extent of access is determined by the type of service, which can be declared when the service is created.

ClusterIP and NodePort

ClusterIP is the default service type. A service obtains its own Virtual IP address through the ClusterIP address. This IP address is used to communicate with other services and can only be accessed within the cluster.

In addition to creating a ClusterIP, NodePort’s service type maps ports between 30000 and 32767 on all worker nodes to this service. For example, assuming that port 32233 is mapped to frontend SVC, we will be forwarded to the ClusterIP assigned by the service, 172.17.0.4, regardless of which worker node we are connected to.

By default, when Expose arrives with a Nodeport, kubernetes Master automatically randomly selects a port between 30,000 and 32767, although we can specify this port manually.

The service type of NodePort is useful when we want the external network to access our service. Users can access the service by accessing the specified port on the node. The administrator can set up a reverse proxy outside the Kubernetes cluster to facilitate access.

LoadBalancer

For the LoadBalancer Servicetype:

  • NodePort and ClusterIP will be automatically created and external Load Balancer will be automatically routed to them
  • The service is exposed on a static port
  • Exposed to the extranet through the load Balancer provided by the underlying Cloud provider

Kubernetes supports this service type only when the underlying infrastructure supports automatic load balancer, such as Google Cloud Platform and AWS.

ExternalIP

If a service can be routed to one or more worker nodes, it can be mapped to an ExternalIP address. Traffic that enters the cluster over this ExternalIP is routed to one of the endpoints.

Note that ExternalIP is not automatically managed by K8S. The administrator manually routes ExternalIP to one of the nodes.

ExternalName

ExternalName is a specific service type that does not have any selector or declared endpoint. When the service is accessed in the cluster, the CNAME of an external service is returned.

For example, if we have an external service called my-database.example.com, we can set the ExternalName service to be available within the cluster. Let other internal services access the service with a name like my-database.

Related articles

  • The Network of Kubernetes
  • Ingress of kubernetes
  • How do I use Helm for native development
  • Create a Kubernetes cluster using kubeadm
  • Service Mesh Istio