Without a way to direct incoming web traffic to the correct application inside your cluster, every user would get lost and see error messages instead of your app. This chapter explains how Ingress solves that problem by acting like a smart front door for Kubernetes. For the CKAD exam, you must know how to write these rules and which controller you are using, because the exam will ask you to create and debug them under time pressure.
Jump to a section
A simple way to picture Ingress Controllers and Ingress Resources
A Hospital Admissions Coordinator is the person who stands at the main entrance of a large hospital. They do not treat any patients themselves, but they are responsible for looking at every person who walks in, checking what kind of problem they have (a broken leg, a fever, a heart attack), and then directing that person to the correct department: Orthopaedics, General Medicine, or Cardiology. Without the Coordinator, patients would wander into random wards, causing chaos and delays. The doctors and nurses in each ward are like the Kubernetes Services — they are ready to treat patients, but they cannot guide them in from the street.
The Coordinator works from a desk with a big map of the hospital and a phone list. That desk is the Ingress Controller. The map and phone list are the Ingress Resource rules that tell the Coordinator which patient goes where. If there is a rule that says chest pain goes to Cardiology, but the Cardiologist has left for the day, the Coordinator might send the patient to a first-aid room instead. This is like an Ingress Resource defining a default backend for when a specific service is unavailable.
In a real hospital, there might be multiple entrances. Each entrance needs its own Coordinator, but they all use the same master map. In Kubernetes, different Ingress Controllers (like Nginx or Traefik) can run at the same time, each responsible for different traffic, but they all read the same Ingress Resource rules. The Coordinator's job is simple but critical: get every patient to the right place without them having to know the hospital layout.
Kubernetes is like a small city of services. Each service runs its own application, but the outside world (the internet) does not know the internal addresses inside the cluster. To let users browse your app, you need a way to route external HTTP and HTTPS traffic to the correct internal service. That is what Ingress does.
An Ingress Resource is a Kubernetes object (a YAML file you write) that defines rules. Each rule says: if someone visits this web address (the hostname) and uses this path (like /shop or /login), send them to this Service. The Ingress Resource does not actually do the routing itself. It is just a set of instructions. The actual routing is done by the Ingress Controller, which is a separate piece of software that runs inside your cluster.
Think of the Ingress Resource as a set of written rules, and the Ingress Controller as the person who reads and executes those rules. You can have multiple Ingress Controllers in the same cluster (e.g., one for public traffic and one for internal traffic), but each Ingress Resource usually belongs to one Controller class.
Why did Kubernetes create Ingress instead of just using Services? Before Ingress existed, you had two choices to expose an app to the internet. You could use a Service of type NodePort, which opens a high-numbered port (like 30080) on every worker node. Or you could use a Service of type LoadBalancer, which asks a cloud provider to spin up a load balancer with its own public IP address. Both have problems. NodePort is messy because you must remember the port number, and the URL becomes http://node-ip:30080. LoadBalancer is expensive and wasteful if you have many apps, because each app gets its own cloud load balancer. Ingress solves this by giving you one public entry point (often a single IP or DNS name) that handles routing for many apps.
Here are the key parts of an Ingress Resource definition:
apiVersion: networking.k8s.io/v1 — this tells Kubernetes which version of the API to use. For CKAD, you must use the v1 version, not extensions/v1beta1 (which is deprecated).
spec.rules — a list of routing rules. Each rule can have a host (optional) and a list of paths. If you omit the host, the rule applies to all incoming traffic.
spec.rules[].http.paths[].path — the URL path to match, such as /api or /.
spec.rules[].http.paths[].pathType — there are three values: Prefix (matches everything starting with that path), Exact (must match exactly), and ImplementationSpecific (decided by the controller). Prefix is the most common for CKAD.
spec.rules[].http.paths[].backend — the destination, which includes a service name and a service port number.
Here is a minimal example. Imagine you have a Service called 'my-app' on port 80. An Ingress Resource that routes all traffic to that Service looks like this in YAML:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress spec: rules: - host: www.myapp.com http: paths: - path: / pathType: Prefix backend: service: name: my-app port: number: 80
Notice that we did not specify an Ingress Controller in the YAML. The Ingress Controller is not part of the resource definition. It is a separate Deployment (or DaemonSet) that watches for new Ingress Resources and updates its configuration accordingly. If you do not have an Ingress Controller installed, nothing happens when you apply your Ingress Resource. The CKAD exam usually expects you to use the default nginx-ingress controller, but you should understand the concept generically.
Ingress also supports TLS (HTTPS). You store your TLS certificate and private key in a Kubernetes Secret, and then reference that Secret in the Ingress spec. The structure is:
spec: tls: - hosts: - www.myapp.com secretName: myapp-tls-secret
That tells the controller to terminate TLS for that hostname using the certificate from the Secret. The traffic between the Ingress Controller and your Service is usually plain HTTP inside the cluster (called TLS offloading), but that is fine for most scenarios.
Why does this matter for CKAD? The exam will ask you to create an Ingress Resource from scratch based on a specification. You will need to know the exact YAML structure, the correct apiVersion, and how to set pathType. They might give you a scenario where the pathType is wrong, or the service name does not match. They might also ask you to update an existing Ingress to add a second route. You must be comfortable with kubectl apply -f your-ingress.yaml and kubectl get ingress.
Ingress Controllers come in many flavours. The most common for CKAD is nginx-ingress, but others like HAProxy, Traefik, or Kong are also used in the real world. The controller runs as a pod in your cluster and often exposes a LoadBalancer Service to get a public IP. When you create an Ingress Resource, the controller reads it and updates its own configuration (like an Nginx config file) to handle the new routing rules.
One important detail: if you do not specify a host in a rule, that rule becomes the default for all traffic that does not match other rules. If you have no default rule and no matching rule, the controller returns a default backend (often a 404 page). The CKAD exam might test your understanding of default backends by asking you to configure one explicitly.
In summary, Ingress gives you a single point of entry, clean URL routing, and TLS termination, all defined in a Kubernetes-native YAML file. It replaces the mess of NodePort ports and multiple LoadBalancers with one elegant object.
Verify the Ingress Controller is installed
Before doing anything else, check that an Ingress Controller is running in your cluster. Without it, your Ingress Resource will not process traffic. Use kubectl get pods -n ingress-nginx (if using NGINX) to see the controller pods. If no controller exists, you cannot proceed — the exam environment will have one pre-installed, but you should confirm it is running.
Create a TLS Secret (if required)
If the specification includes HTTPS, you need to create a Secret that holds the TLS certificate and private key. Use kubectl create secret tls <secret-name> --cert=<path-to-cert> --key=<path-to-key> -n <namespace>. The Secret must be in the same namespace as the Ingress Resource. Without this step, the Ingress will reject HTTPS connections.
Write the Ingress Resource YAML file
Use a text editor (vi or nano) to write your YAML. Start with apiVersion: networking.k8s.io/v1, kind: Ingress, and metadata. Then define spec.rules. Each rule must have a list of http.paths. For each path, specify path, pathType, and backend (service name and port number). If using TLS, add the spec.tls section with hosts list and secretName. Double-check the indentation — YAML is strict about spaces.
Apply the Ingress Resource to the cluster
Run kubectl apply -f your-ingress.yaml to submit the resource to the Kubernetes API server. The Ingress Controller watches the API and will detect this new resource. If you get validation errors, fix the YAML and reapply. Common mistakes: wrong apiVersion, missing http: stanza, or incorrect service name.
Verify the Ingress is working
Check the status of your Ingress with kubectl get ingress -n <namespace>. Look for the ADDRESS field — it should show the external IP or hostname of your Ingress Controller's LoadBalancer. If ADDRESS is empty, the controller may not be configured properly. Test the route by curling the hostname or the controller IP from outside the cluster.
Update DNS records (real-world only)
In a production scenario, you would create DNS A or CNAME records pointing your domain (e.g., shop.bee-hive.com) to the Ingress Controller's external address. This step is not tested in CKAD, but it is the final action to make the app publicly accessible. The exam focuses only on the YAML configuration.
Imagine you work as a junior platform engineer for a company called 'BeeHive', which runs a web application with three microservices: a customer-facing shop (bee-shop), an admin dashboard (bee-admin), and an API for mobile apps (bee-api). The company has one domain name, bee-hive.com, and wants to route traffic based on the subdomain or path.
Your boss gives you this requirement: traffic to shop.bee-hive.com goes to the bee-shop service. Traffic to admin.bee-hive.com goes to bee-admin. Traffic to api.bee-hive.com goes to bee-api. All these services run on port 80 inside the cluster. You also need HTTPS for the shop subdomain.
Step-by-step, here is what you do:
First, you make sure an Ingress Controller is running in your cluster. You check with kubectl get pods -n ingress-nginx. You see pods named nginx-ingress-controller-xyz. Good.
2. You create a Kubernetes Secret for the TLS certificate for shop.bee-hive.com. You have the certificate file (tls.crt) and private key (tls.key). You run: kubectl create secret tls shop-tls --cert=tls.crt --key=tls.key -n production
You write the Ingress Resource YAML file. It has one rule per subdomain. For the shop subdomain, you also add the tls section. The file looks something like this:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: bee-ingress namespace: production spec: tls: - hosts: - shop.bee-hive.com secretName: shop-tls rules: - host: shop.bee-hive.com http: paths: - path: / pathType: Prefix backend: service: name: bee-shop port: number: 80 - host: admin.bee-hive.com http: paths: - path: / pathType: Prefix backend: service: name: bee-admin port: number: 80 - host: api.bee-hive.com http: paths: - path: / pathType: Prefix backend: service: name: bee-api port: number: 80
You apply the file: kubectl apply -f bee-ingress.yaml. You check the status: kubectl get ingress -n production. You see the ADDRESS column shows an IP (the external IP of your Ingress Controller's LoadBalancer).
You update DNS records: you create CNAME records for each subdomain pointing to the Ingress Controller's external IP or DNS name.
A few days later, your boss says the mobile team wants a new path: api.bee-hive.com/v2 should go to a different service 'bee-api-v2'. You edit the same Ingress Resource, adding another path under the api.bee-hive.com rule. You use pathType Prefix and path /v2. You apply the updated YAML. The Ingress Controller detects the change immediately and starts routing /v2 traffic to the new service.
This real-world scenario shows the main advantages: one YAML file handles all routing, changes are instant, and HTTPS is configured centrally. If a developer later adds a new service, they just update the same Ingress Resource, and they do not need to ask you for a new load balancer or worry about port numbers.
The CKAD exam objective 6.2 focuses entirely on configuring Ingress to expose HTTP/HTTPS routes to applications. The exam is performance-based, meaning you actually type YAML into a terminal and apply it to a real cluster. You do not get multiple-choice questions on this topic — you must create or fix an Ingress Resource.
Here are the specific things CKAD tests:
You must write an Ingress YAML from scratch using the correct apiVersion: networking.k8s.io/v1. The older extensions/v1beta1 version is deprecated and will not work in the exam environment. This is a common trap — many beginners accidentally use the old syntax out of habit or outdated tutorials.
They expect you to use pathType correctly. The most common value is Prefix, which means the path you write is a prefix that matches everything starting with it. For example, path: /api with Prefix matches /api, /api/v1, /api/v2/orders. If you use Exact, it only matches /api exactly, so /api/v1 would not match. The exam scenario often asks for "all traffic under /app" which means Prefix.
You must know how to specify the backend service and port. The port must be a number, not a name, because the exam typically uses numbered ports. If you use a named port, it might fail if the service definition does not have that name.
They may ask you to configure TLS. You will need to reference an existing Secret. The exam will give you the Secret name (e.g., my-tls-secret). You must add the tls section correctly, with the hosts list matching the host in the rule.
They might test default backends. An Ingress can have a default backend defined at the spec level (spec.defaultBackend) that catches all requests that do not match any rule. This is a subtle concept — if you omit it and no rule matches, the controller returns its default (usually a 404). The exam could ask you to add a default backend for error handling.
They often ask you to modify an existing Ingress. For example, "add a new route /orders that points to the order-service on port 8080." You must find the existing Ingress YAML (maybe with kubectl get ingress my-ingress -o yaml), edit it, and apply the changes. This teaches you to work with what exists.
Traps to watch for: using the wrong apiVersion, misspelling the service name, forgetting the http: stanza under rules, putting the tls section at the wrong indentation level (it belongs under spec, not under rules), or using a port name instead of a number.
Key concepts to memorise:
apiVersion: networking.k8s.io/v1
spec.rules[].host is optional (if omitted, rule applies to all hosts)
spec.rules[].http.paths[].pathType: Prefix, Exact, or ImplementationSpecific
spec.tls[].hosts: list of hostnames to secure
spec.tls[].secretName: must match a Secret of type kubernetes.io/tls in the same namespace
If the Ingress Controller is not installed, your Ingress Resource does nothing. The exam cluster will have one pre-installed, typically nginx.
Remember: you cannot use kubectl create ingress to make a complex one from scratch. You must write the YAML file with a text editor (vi or nano) and apply it. Practise this repeatedly before the exam. The time limit is tight.
An Ingress Resource is a set of routing rules written in YAML, while an Ingress Controller is the software that reads those rules and routes traffic.
The correct apiVersion for Ingress in CKAD is networking.k8s.io/v1 — the old extensions/v1beta1 version is deprecated and will fail the exam.
pathType must be set to Prefix for most routing scenarios, meaning the path matches everything starting with that prefix (e.g., /api matches /api/v1).
TLS configuration in Ingress requires a Kubernetes Secret of type kubernetes.io/tls containing the certificate and key, referenced in the spec.tls section.
Without an installed Ingress Controller (like nginx-ingress), your Ingress Resource will not work — it is just a dead configuration file.
You can have multiple Ingress Resources in the same cluster, even in different namespaces, and they combine to form a single routing table managed by the controller.
A default backend can be specified at the spec level to handle all traffic that does not match any rule, returning a custom error page or redirecting to a catch-all service.
The exam expects you to edit an existing Ingress to add a path or host — not just create from scratch — so practise kubectl get ingress -o yaml and then apply changes.
These come up on the exam all the time. Here's how to tell them apart.
NodePort Service
Exposes a static high-numbered port (30000-32767) on each worker node
Traffic must hit that specific port; URL is http://node-ip:30080
No TLS termination built-in; must handle externally or with a separate proxy
LoadBalancer Service
Creates a cloud load balancer with a public IP or DNS name
Each LoadBalancer Service gets its own public IP, which costs money
Can often do TLS termination if paired with cloud provider certificates
Ingress Resource
A Kubernetes YAML object (resource) that defines routing rules
Passive: it does nothing on its own; it is just stored configuration
You create one per set of rules; multiple resources can coexist
Ingress Controller
A real software process (pod) that runs inside the cluster
Active: it watches for new or changed Ingress Resources and reconfigures its routing
Usually one controller handles all Ingress Resources in the cluster
pathType: Prefix
Matches any URL path that starts with the specified prefix
Example: path: /api matches /api, /api/v1, /api/v2/orders
Use this when you want to route all requests under a certain base path
pathType: Exact
Matches only the exact path specified, no more and no less
Example: path: /api matches only /api; /api/v1 does not match
Use this for single endpoints like /healthz or /login
Ingress with TLS
Requires a Kubernetes Secret with a TLS certificate and private key
Traffic between user and Ingress Controller is encrypted (HTTPS)
The controller terminates TLS and sends plain HTTP to the backend Service
Ingress without TLS
No Secret needed; all traffic is plain HTTP
Traffic between user and Ingress Controller is unencrypted (HTTP)
Simpler to set up, but not suitable for production with sensitive data
Mistake
An Ingress Resource is the same as an Ingress Controller, and you install them together with one YAML file.
Correct
An Ingress Resource is just rules (YAML). The Ingress Controller is a separate software component that reads those rules and does the actual routing. You install the controller once (often via a Helm chart or manifest), and then you create individual Ingress Resources for each set of rules.
People see the word 'Ingress' used for both and assume they are one unit. In reality, one is configuration, the other is a running program.
Mistake
If I create an Ingress Resource, the service it points to automatically becomes reachable from the internet with a public IP.
Correct
The Ingress Resource alone does nothing. The Ingress Controller must be running in the cluster and must have an external IP (usually from a LoadBalancer Service). The Ingress Resource only works if the controller exists and reads it.
Beginners think Kubernetes objects are self-sufficient. They do not realise that many objects (like Ingress, HPA, NetworkPolicy) depend on a separate controller to enforce them.
Mistake
You can only have one Ingress Resource per cluster because there is only one front door.
Correct
You can have many Ingress Resources in the same cluster. They can be in different namespaces, and they can all coexist as long as they do not have conflicting rules (e.g., same host and path). The Ingress Controller merges them.
The mental model of a single router makes people think one router = one config file. But Kubernetes treats each resource as a separate config unit.
Mistake
If you set pathType: Exact on /api, then /api/v1 will still match because it starts with /api.
Correct
Exact means an exact match. /api/v1 will not match /api with Exact. For /api/v1 to match, you need pathType: Prefix.
The word 'Exact' is intuitive, but in Kubernetes it is absolute. People assume 'Exact' means the path starts with that string. It does not.
Mistake
TLS in Ingress means the traffic is encrypted all the way from the user to the Pod.
Correct
TLS is typically terminated at the Ingress Controller. The traffic from the Controller to the Service Pod is usually plain HTTP (HTTP inside your cluster). End-to-end encryption requires additional configuration (like re-encrypting or using mTLS).
The word 'TLS' suggests total encryption. In practice, most setups terminate TLS at the edge for simplicity and performance, so internal traffic is plaintext.
Mistake
An Ingress Resource must always have a host field.
Correct
The host field is optional. If omitted, the rule applies to all incoming HTTP traffic that does not match a more specific host. This is useful for catch-all routing.
Many tutorials only show examples with host, so beginners think it is required. The YAML schema allows rules without hosts.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
An Ingress Resource is a YAML object that defines routing rules (like which domain goes to which Service). An Ingress Controller is a separate pod that runs inside your cluster and reads those rules to actually route traffic. You need both for Ingress to work.
No. If you apply an Ingress Resource without a running Ingress Controller, nothing happens. The resource is stored in the cluster, but no traffic will be routed. Always confirm the controller is installed first.
You must use networking.k8s.io/v1. The old apiVersion extensions/v1beta1 is deprecated and will not work in the exam environment. Always check that your YAML starts with apiVersion: networking.k8s.io/v1.
First, create a Kubernetes Secret of type kubernetes.io/tls with your certificate and private key (e.g., kubectl create secret tls my-tls --cert=tls.crt --key=tls.key). Then, in your Ingress Resource, add a spec.tls section listing the hostname and referencing that Secret name. The Ingress Controller will terminate the TLS connection.
Prefix means the path matches everything starting with that string. For example, path: /api with Prefix matches /api, /api/v1, /api/version. Exact means the path must match exactly, so /api only matches /api, not /api/v1. For most use cases, you use Prefix.
Yes, you can have multiple Ingress Resources in the same namespace. The Ingress Controller will merge them into a single routing table. However, be careful that no two rules define the same host and path combination, as that can cause conflicts.
You've finished Ingress Controllers and Ingress Resources. Continue through the CKAD study guide to build a complete picture of the exam.
Done with this chapter?