Once you have mastered deploying applications inside Kubernetes using Deployments and ReplicaSets, your next step is to learn how to interact with these applications, both from within and outside the Kubernetes cluster. This step involves making your application visible, which allows communication between other pods inside the cluster and users outside it. Kubernetes Services help you achieve this. In this topic, you will learn about the concept of Services, their importance, examine the different types of Services available, and learn about their specific uses.
Services
In Kubernetes, Services act as a crucial component that allows network access to the applications launched within the cluster. These accesses can come from both internal and external clients. Think of Services in Kubernetes as gateways that offer access to groups of Pods via a network. Each Service determines a set of endpoints, which often are Pods but can also include other Services. They also detail how to reach these Pods, hence making connecting internal/external clients to your application effortless.
When you fashion a Deployment for running your application, the Deployment forms Pods, and every Pod receives a unique IP address. It's vital to understand that because of the transitory nature of Pods, Pods processing your application at one instant may not be the same a bit later within the very Deployment. This makes it tough to monitor which IP address to link to. Services solve this issue by offering a constant IP address that clients can leverage to engage with the Pods. When a client submits a request to this IP address, the request is automatically forwarded to a Pod in the Service. It's key to remember that clients within the Kubernetes cluster don't need to employ the Service's IP address. They can simply send requests using the Service name, which automatically resolves to the Service's IP address. This convenient resolution eases interactions inside the cluster.
Kubernetes provides varied types of Services like ClusterIP, NodePort, LoadBalancer, and ExternalName, each designed for particular users. They simplify connecting services with each other and the external world; As a result, this enhances your application's reliability, security, and accessibility when deployed in Kubernetes. We'll evaluate each type in the subsequent sections.
Create a Service
A Service is a Kubernetes object that you can create, view, or modify its definitions using the kubectl command line tool.
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
# This tells the service to select only those pods whose labels exactly "match" to 'app: myApp'
selector:
app: myApp
ports:
- protocol: TCP
port: 80
targetPort: 6060
type: ClusterIPThe type field indicates the type of service you want to create. Kubernetes offers a variety of service types such as ClusterIP, NodePort, LoadBalancer, and ExternalName.
The selector field specifies which pods you want to select. In the above example, this service will select only those pods that have the label app: myApp. It's crucial to remember that the matchLabels sub-field within the selector field must perfectly match the labels attached to the pods; this is how a service identifies which pods to select.
To create a Service with the above manifest definition, start by creating a yaml file, let's call it svc.yaml, where you can copy the example manifest above. Once you have prepared your Service manifest, use the kubectl command to create it in your Kubernetes cluster. Open your terminal and navigate to the directory where you saved the svc.yaml file, then run the following command:
kubectl apply -f svc.yamlExecute the following kubectl command to note the IP address, which is automatically generated for this service:
kubectl get svc myapp-serviceRemember, Services provide a stable and unique IP address that you can use to interact with your application pods within the cluster. This IP address is exclusively for cluster use and cannot be accessed by clients outside the Kubernetes cluster. If you need an external IP address, use the LoadBalancer service type. In this instance, your IP is 10.43.206.130.
The definition of the ports sub-field within the spec field in the Service manifest varies depending on the type of service you're creating. Usually, it includes port and targetPort sub-fields. The port represents the port that the Service exposes within the cluster, enabling other pods in the Kubernetes cluster to interact with your application using the service IP (in this case, it's 10.43.206.130). In this example, that's port 80. The targetPort is the port your application listens on within the pod; essentially, it's the pod's internal port (in this example, our application is listening on port 6060 inside the pod).
You can also expose a Deployment imperatively using the following kubectl command:
kubectl expose deployment <deployment-name> --type=ClusterIP --name=<service-name> --target-port=6060 --port=80If you neglect to specify the --type flag, Kubernetes will create a service of type ClusterIP by default. If you do not provide a targetPort value, it defaults to the value specified in port.
The official documentation provides a comprehensive explanation of services, their various types, and their use cases. It goes into more detail than we've covered here.
ClusterIP
A ClusterIP Service in Kubernetes is a service type that gives internal network access to applications or services inside the cluster. It reveals a group of Pods as a single, stable IP address within the Kubernetes cluster.
In the image above, you see how other pods inside the cluster interact with the application we deployed using Deployment via a Service. When pod-A starts a request, it links to the Service through the Service's Cluster-IP and port. The Service then sends the request to our application pods at pod-IP:targetPort.
You typically use a Cluster-IP service in Kubernetes when you want to expose an application or service within your cluster to other applications operating in the same cluster, without requiring external access.
Imagine you have a backend application and a database running internally in your Kubernetes cluster. You prioritize security and want to stop external clients or apps from accessing the database to keep your data safe. However, your backend application needs to connect with the database to perform its intended function. In this case, you create a Cluster-IP service for the database. Cluster-IP services offer a consistent, stable internal IP address and DNS name within the cluster. Your backend application can use these DNS names or IP addresses to communicate smoothly with the database, without worrying about the underlying network configurations. This method not only assures secure data access but also simplifies inter-service communication, causing your application to be more robust and manageable.
Cluster-IP services are perfect for inter-service communication within the cluster, offering an internal network segregated from external traffic.
NodePort
When you're developing and testing, you might need to make a service accessible from outside the cluster. Let's say you've deployed a web application inside your Kubernetes cluster, and you need to access it from a web browser on your local machine. In this situation, you can use a NodePort service.
A NodePort Service in Kubernetes is a service type that makes an internally running application accessible to the external world, usually over a specific port, named nodePort. This service essentially takes the internal application and opens a particular port (nodePort) on all cluster nodes. When external clients make requests, they target the IP address of a node on the nodePort outlined by the Service. NodePort service builds on top of the ClusterIP service, so when you create a NodePort Service, Kubernetes also establishes a corresponding ClusterIP for the service. You can define the nodePort either in the ports section of the service manifest or by using the --nodePort flag if you prefer an imperative style of service creation. The default range for nodePort in Kubernetes is 30000-32767. If you don't specify a specific port for the nodePort value within this range when creating a NodePort service, Kubernetes will automatically assign a service port from this range.
In the image above, you can see how external clients (internet) direct their traffic to the nodes inside the Kubernetes cluster, specifying the nodePort. This traffic then goes to the ClusterIP Service on its set port, which guides it to a specific Pod or container listening on the targetPort.
LoadBalancer
A LoadBalancer Service in Kubernetes is a service type famously used for making applications visible online. It permits external access to your application and automatically balances the load of the traffic.
Once you create a LoadBalancer service, Kubernetes communicates with the cloud provider's API to supply a load balancer. This cloud-based load balancer features a steady external IP address and channels the external traffic to the proper Kubernetes nodes. Simultaneously, Kubernetes can also set up a NodePort service to work as a conduit, redirecting traffic from the LoadBalancer to the internal ClusterIP service, which guides the traffic to the Pods.
LoadBalancer Services in Kubernetes is your pick when you aim to make your applications open to the public without exposing the underlying Kubernetes nodes directly. They add a security layer by revealing a single IP address (the Load Balancer's IP) to external clients, therefore hiding the IP addresses of individual nodes within the Kubernetes cluster from external exposure.
In contrast, NodePort Services show a port on each node. External clients can reach the service using the IP address of any node combined with the specified NodePort. While NodePort services can facilitate external access, they might require exposing the IP addresses of individual nodes to external clients, making them less secure in preventing IP address exposure. That's why LoadBalancer Services are a good fit for production scenarios; in contrast, NodePort Services are commonly used during development and debugging stages.
ExternalName
ExternalName is a kind of Kubernetes Service that plays the role of a DNS alias. In other words, it offers a method to connect a Kubernetes service to an external DNS name. This comes in handy when you want to link to external services by name, without having to embed IP addresses or tamper with DNS settings inside your application pods. It doesn't balance the load of traffic or proxy requests to any pods or endpoints. Instead, it associates a Kubernetes Service with a DNS name.
Let's look at an example to comprehend the function of externalName services more effectively.
Imagine you're running a web application based on Kubernetes that needs to connect with an external OAuth2 identity provider like Google for user verification. This OAuth2 identity provider has fixed endpoints, including the authorization server, token endpoint, and user info endpoint. To streamline the setup and ensure secure integration, you can employ an ExternalName Service. You can create this service through the following definition; but note that this service manifest differs from other Kubernetes services.
apiVersion: v1
kind: Service
metadata:
name: oauth-identity-provider
spec:
type: ExternalName
# provide the address of any external api that you would like to use (like google api, dropbox api or any oauth service provider)
externalName: oauth2.provider.comYou can now tweak your web application settings to use the DNS name given by the ExternalName Service, which is oauth-identity-provider, for the OAuth2 identity provider's authorization server URL. The DNS name (oauth-identity-provider) will automatically resolve to the OAuth2 identity provider's authorization server URL.
This service is typically used when interfacing with external clients or services, including OAuth and external APIs. It diverges slightly from other Kubernetes services, offering a unique method to establish connections with external resources.
Conclusion
Services in Kubernetes are crucial for managing and exposing applications within a cluster. They offer a layer of abstraction that simplifies how you connect and access various parts of your application.
ClusterIP services facilitate communication among internal services, ensuring smooth interaction within the cluster.
NodePort services provide a temporary way for external access, perfect for testing and debugging.
LoadBalancer services are your primary choice for making applications reachable from the internet. They boost security by presenting a single IP address to external clients.
Finally, ExternalName services present a unique "inside-out" method, linking with external clients or services like OAuth and external APIs. Taken together, these service types bolster the resilience, security, and accessibility of Kubernetes applications.