Overview of Services
Pods, in fact, have a lifecycle. When a worker node dies, the Pods running on the Node are also lost. A ReplicaSet might then dynamically drive the cluster back to the desired state via the creation of new Pods to keep your application running.
The back-end system with some replicas. Those replicas are exchangeable; the front-end system should not care about backend replicas or even if a Pod is lost and recreated. That said, each Pod in a Kubernetes cluster has a unique IP address, even Pods on the same Node, so there needs to be a way of automatically reconciling changes among Pods so that your applications continue to function.
A Service in Kubernetes is an abstraction which defines a logical set of Pods and a policy by which to access them. Services enable a loose coupling between dependent Pods. A Service is defined using YAML or JSON. The set of Pods targeted by a Service is usually determined by a LabelSelector
Type of exposing Services
Although each Pod has a unique IP address, those IPs are not exposed outside the cluster without a Service. Services allow your applications to receive traffic. Services can be exposed in different ways by specifying a type
in the ServiceSpec:
- ClusterIP (default) – Exposes the Service on an internal IP in the cluster. This type makes the Service only reachable from within the cluster.
- NodePort – Exposes the Service on the same port of each selected Node in the cluster using NAT. Makes a Service accessible from outside the cluster using
<NodeIP>:<NodePort>
. Superset of ClusterIP. - LoadBalancer – Creates an external load balancer in the current cloud (if supported) and assigns a fixed, external IP to the Service. Superset of NodePort.
- ExternalName – Exposes the Service using an arbitrary name (specified by
externalName
in the spec) by returning a CNAME record with the name. No proxy is used. This type requires v1.7 or higher ofkube-dns
.
Services without Selector
Additionally, there are some use cases with Services that involve not defining selector
in the spec. A Service created without selector
will also not create the corresponding Endpoints object. This allows users to manually map a Service to specific endpoints. Another possibility why there may be no selector is you are strictly using type: ExternalName
.
Services and Labels
A Service routes traffic across a set of Pods. Services are the abstraction that allow pods to die and replicate in Kubernetes without impacting your application.
Services match a set of Pods using labels and selectors, a grouping primitive that allows logical operation on objects in Kubernetes. Labels are key/value pairs attached to objects and can be used in any number of ways:
- Designate objects for development, test, and production
- Embed version tags
- Classify an object using tags
Demo
Create New Services
Let’s list the current Services from our cluster:
kubectl get services
We have a Service called kubernetes that is created by default when minikube starts the cluster. To create a new service and expose it to external traffic we’ll use the expose command with NodePort as parameter
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
We have now a running Service called kubernetes-bootcamp. Here we see that the Service received a unique cluster-IP, an internal port and an external-IP (the IP of the Node).
To find out what port was opened externally (by the NodePort option) we’ll run the describe service
command:
kubectl describe services/kubernetes-bootcamp
Create an environment variable called NODE_PORT that has the value of the Node port assigned:
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}') echo NODE_PORT=$NODE_PORT
Now we can test that the app is exposed outside of the cluster using curl
curl $(minikube ip):$NODE_PORT
Step 2: Using labels
The Deployment created automatically a label for our Pod. With describe deployment
command you can see the name of the label:
kubectl describe deployment
Let’s use this label to query our list of Pods.
kubectl get pods -l run=kubernetes-bootcamp
You can do the same to list the existing services:
kubectl get services -l run=kubernetes-bootcamp
Get the name of the Pod and store it in the POD_NAME environment variable:
export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') echo Name of the Pod: $POD_NAME
To apply a new label we use the label command followed by the object type, object name and the new label:
kubectl label pod $POD_NAME app=v1
This will apply a new label to our Pod
kubectl describe pods $POD_NAME
We see here that the label is attached now to our Pod. And we can query now the list of pods using the new label:
kubectl get pods -l app=v1
Step 3 Deleting a service
o delete Services you can use the delete service
command. Labels can be used also here:
kubectl delete service -l run=kubernetes-bootcamp
Confirm that the service is gone:
kubectl get services
Then we try to check by these commands:
curl $(minikube
ip):$NODE_PORT
This proves that the app is not reachable anymore from outside of the cluster. You can confirm that the app is still running with a curl inside the pod:
kubectl exec -ti $POD_NAME
cur
l
localhost:8080