Kubernetes - Services
Kubernetes Service
Service is an abstract way to expose an application running on a set of Pods as a network service.
Every pod has an IP address. A Pod’s IP address is ephemeral because the pods can failed and replaced in a different node. Service has a stable and reliable IP address that you can use to access the pods.
Service Types
There are three Service Typs to choose from.
- ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the clluster. 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 will be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>. The drawback of NodePort is you need to know the node’s ip address to access the service.
- LoadBalancer: Exposes the service externally using a cloud provider’s load balancer. If the cluster is not run on the cloud, then LoadBalancer type is probably not supported.
Service Commands
To get a list of services exposed
1 | kubectl get services |
To describe a service named nginx
1 | kubectl describe service nginx |
Delete a service
1 | kubectl delete service nginx |
Expose a resource( can be pod, replicaset, service, deployment) as a new Kubernetes service.
1 | # Create a service for an nginx deployment, which serves on port 80 and connects to the containers on port 8000. |
ClusterIP
You can only access this service while inside the cluster. ClusterIP is usually used by backend service and data store service.
Sample service with ClusterIP type
1 | apiVersion: v1 |
A service use selectors to select the pods with specific labels.
Here there are two ports defined
- targetPort - the port to access on the pods targeted by the service. This is the port which the application is configured to listen on.
- port - the port that wil be exposed by this service
Use kubectl get services
to list service info
1 | $ kubectl get services |
When inside the cluster, you can access this service suing the following
- clusterIP:port
Example to access the service inside the cluster
1 | curl 10.101.67.7:8080 |
One way to get into a cluster is to execute kubectl exec -it <pod-name> /bin/bash
command to get into a pod. You may need to install curl in the pod if it is not available. In addition, curl installation doesn’t always work.
Note that another way to access the application is port forwarding.
NodePort
NodePort exposes the service via the defined note port. The service can be reach on any node in the cluster via the nodePort.
myapp-service.yml
1 | apiVersion: v1 |
Here there are three ports defined
- targetPort - the port to access on the pods targeted by the service
- port - the port that wil be exposed by this service
- nodePort - The port on each node on which this service is exposed when type=NodePort or LoadBalancer. Usually assigned by the system.
Use kubectl get services
to list service info
1 | $ kubectl get services |
You can access this service using the following
- clusterIP:port
- nodeIP:nodePort
In addition to accessing the service using clusterIP, you can access the service outside of the cluster using node’s external IP. For minikube cluster, the node’s external IP can be retrieved using minikube ip
command.
1 | curl 172.17.0.44:30003 |
You can get a node’s ip using kubectl get nodes -o wide
command
LoadBalancer
Loadbalancer exposes the service to the outside world.
Sample LoadBalancer type service
1 | apiVersion: v1 |
Here there are three ports defined
- targetPort - the port to access on the pods targeted by the service
- port - the port that wil be exposed by this service
- nodePort - The port on each node on which this service is exposed when type=NodePort or LoadBalancer. Usually assigned by the system.
Use kubectl get services
to list service info
1 | $ kubectl get services |
You can access this service using the following
- clusterIP:port
- nodeIP:nodePort
- loadBalancerIp:port
Example to access the service using loadbalancerIP outside of the cluster. Kubernetes routes request to a nodePort, then routes to the clusterIP port.
1 | curl 172.17.0.22:8080 |
Service Discovery via DNS
As of Kubernetes v1.12, CoreDNS is the recommended DNS Server, replacing kube-dns. However, kube-dns may still be installed by default with certain Kubernetes installer tools. Both the CoreDNS and kube-dns Service are named kube-dns in the metadata.name field.
When inside a Kubernetes cluster, you can use ClusterIP or DNS to visit the service. DNS Service will resolve the DNS name.
Every Service defined in the cluster is assigned a DNS A Record. The record is of format <Service-name>.<Namespace>.svc.<Cluster-Domain>. You can often use <Service-name>.<Namespace> to refer to the service.
So in the application code, use url http://service-name.namespace/ to visit the service. Kubernetes will resolve the hostname using dns service.
servicediscovery.yml: A pod that uses DNS name to visit myapp service.
1 | apiVersion: v1 |
This pod refers to myapp service in default namespace using hostname myapp.default. The complete dns name for myapp service is myapp.default.svc.cluster.local. cluster.local is the default Namespace can be omitted if the service provider and consumer are in the same namespace.
Execute the following command to see how the pod visit the service using DNS name.
1 | $ kubectl apply -f servicediscovery.yml |
Port Forwarding
Service is not the only way to access an application. One way is to use port forwarding to access a pod.
port-forwarding allows you to forward a local port in the host to a port on the pod
1 | kubectl port-forward <pod-name> <local-port>:<port> |
You can use curl hostname:host-port
to access the pod locally. Default hostname is localhost if address option is not set.
kubctl port-forward
has an option --address
to specify the address to listen on. It accepts IP addresses or localhost as a value. Default is localhost.
For more details on port forwarding, use kubectl port-forward --help
command to see sample usage. See Port Forwarding documentation for more detail explaination.