Chapter 3
Section titled “Chapter 3”We now have a scalable, self-healing application running via a Deployment. But as we noted, it’s isolated inside the cluster’s private network. Let’s fix that.
Exposing Your Application: Services and Ingress
Section titled “Exposing Your Application: Services and Ingress”Your Pods are like houses in a gated community. They can talk to each other, but no one from the outside can get in. Pods are also constantly being created and destroyed by the Deployment, each time getting a new internal IP address. So, how can we reliably connect to them?
We need a stable address and a way to route traffic from the outside world to our application Pods. This is handled by two types of objects: Services and Ingress.
Part 1: The Service Object
Section titled “Part 1: The Service Object”A Service is a Kubernetes object that provides a stable network endpoint for a group of Pods. It acts as an internal load balancer. A Service gets a permanent IP address and a DNS name within the cluster, and it forwards any traffic it receives to one of its healthy backing Pods.
How does a Service know which Pods to send traffic to? It uses the exact same label and selector mechanism that a Deployment uses to identify its Pods.
There are three key types of Services you should know:
-
ClusterIP: (Default type) The Service gets a single, stable IP address that is only reachable from within the cluster. This is perfect for internal communication, for example, if your web application frontend needs to talk to a backend API or a database that is also running in the cluster.
-
NodePort: This type of Service exposes the application on a specific port on every Node in the cluster. You can then access your application by hitting
http://<Any-Node-IP>:<NodePort>. This is great for quick testing and development but isn’t ideal for production because you have to keep track of Node IPs and specific port numbers. -
LoadBalancer: This is the standard way to expose an application to the internet. When you create a Service of type LoadBalancer, Kubernetes works with your cloud provider (like GCP, AWS, or Azure) to provision a real, external load balancer. This load balancer gets a public IP address and automatically forwards all traffic to your Service, which in turn forwards it to your Pods.
-
Exposing with a
NodePortService” This is the simplest way to get external traffic to your Pods. Create a file namedservice-nodeport.yaml:service-nodeport.yaml apiVersion: v1kind: Servicemetadata:name: my-webapp-servicespec:# This selector must match the labels of the Pods in our Deploymentselector:app: my-webapp# This defines the service typetype: NodePortports:- protocol: TCP# Port on the Service itselfport: 80# The port on the Pods that the traffic should be sent totargetPort: 80# The static port on the Node. If not specified, Kubernetes picks one.# nodePort: 30007Apply it to your cluster:
Terminal window kubectl apply -f service-nodeport.yamlNow, Minikube gives us a handy shortcut to get the accessible URL:
Terminal window minikube service my-webapp-service --urlThis will output a URL like
http://192.168.49.2:31234. Open that URL in your browser or use curl, and you’ll see the “Welcome to nginx!” page, served from one of your Pods. -
Exposing with a
LoadBalancerService This simulates how you would expose an app in a real cloud environment.First, let’s delete the
NodePortservice:kubectl delete service my-webapp-service.Now, create a file named
service-loadbalancer.yaml:service-loadbalancer.yaml apiVersion: v1kind: Servicemetadata:name: my-webapp-servicespec:selector:app: my-webapp# This is the only line that changestype: LoadBalancerports:- protocol: TCPport: 80targetPort: 80Apply this new service:
Terminal window kubectl apply -f service-loadbalancer.yamlBecause Minikube doesn’t have a real cloud load balancer, it has a built-in tool that simulates one. Open a new, separate terminal and run:
Terminal window minikube tunnelLeave this command running. It will ask for your password to set up network routes. The tunnel will take over your machine’s network to route traffic to the
LoadBalancerIP.Now, in your original terminal, check the status of your service. After a few moments, you will see an
EXTERNAL-IPassigned.Terminal window # Watch for the EXTERNAL-IP to appearkubectl get service my-webapp-service --watchOnce you see an IP address in the EXTERNAL-IP column, you can curl that IP address directly, and it will hit your Nginx service.
Part 2: The Ingress Object
Section titled “Part 2: The Ingress Object”A LoadBalancer service is great, but it’s a one-to-one mapping. You get one public IP for one service.
What if you have 10 services (e.g., yoursite.com/api, yoursite.com/blog, admin.yoursite.com)?
Provisioning 10 load balancers would be slow and expensive.
An Ingress is a smarter solution. It’s a layer 7 (HTTP/S) router that can direct traffic to different services based on the requested hostname or URL path. It acts as a single entry point for your entire cluster.
To use an Ingress, you need two things:
- An Ingress object: A YAML file defining the routing rules.
- An Ingress Controller: A Pod running in your cluster that actually implements the rules (e.g., it’s a sophisticated Nginx or proxy server).
-
Enable the Ingress Controller Add-on Minikube comes with an Nginx Ingress Controller that you can easily enable:
Terminal window minikube addons enable ingressWait for it to complete. It will install the necessary controller into your cluster.
-
Create the Ingress Rule Create a file named
ingress.yaml. We will tell it to route all traffic for my-webapp.example.com to our existing service.ingress.yaml apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: my-webapp-ingressspec:rules:- host: "my-webapp.example.com"http:paths:- pathType: Prefixpath: "/"backend:service:name: my-webapp-serviceport:number: 80Apply the rule:
Terminal window kubectl apply -f ingress.yaml -
Map the Hostname to Minikube’s IP The world doesn’t know where
my-webapp.example.comis. We need to tell our local machine to direct requests for that domain to our Minikube cluster.First, get the IP address of your Minikube cluster:
Terminal window minikube ipLet’s say the IP is
192.168.49.2.Now, you must edit the
hostsfile on your computer to add this entry.- On macOS/Linux:
sudo nano /etc/hosts - On Windows: Open Notepad as an Administrator and open
C:\Windows\System32\drivers\etc\hosts
Add the following line to the end of the file, then save it:
192.168.49.2 my-webapp.example.com(Remember to use the actual IP from the
minikube ipcommand) - On macOS/Linux:
-
Test It! You can now access your application using the domain name. The Ingress Controller will see the request for
my-webapp.example.com, look up your Ingress rule, and forward the traffic tomy-webapp-service, which sends it to one of your Pods.Terminal window curl http://my-webapp.example.comYou should see the “Welcome to nginx!” page. Success!
Key Takeaways for Chapter 3:
Section titled “Key Takeaways for Chapter 3:”- Services give you a stable endpoint to access your ephemeral Pods.
NodePortis for quick access during development.LoadBalanceris the standard way to expose a single service to the internet.- Ingress is a powerful router that manages access to multiple services using hostnames and paths,
saving you from needing multiple
LoadBalancers.
When you are ready, we will proceed to Chapter 4, where we’ll learn how to manage application configuration and secrets without having to rebuild your container images.