When you have frontend Kubernetes Services, how do you manage them? How do you keep track of multiple paths to specific endpoints in the service? Are you using multiple on-prem load balancers or cloud load balancers?
A lot of thought goes into the quantity and overall need when it comes to Kubernetes frontend services.
In the second blog post for the “vs” series, you’re going to learn about using Standard Ingress without any overall management and Ingress managed in Portainer.
What is Ingress?
Before jumping into the hands-on piece of this content, let’s talk a bit about what Ingress is.
When an outside party, like a customer or a client, is accessing your frontend app, they need a way to reach out. Whether the app is a UI that they’re logging into, some type of POC for an app that you host for them, or any other use-case that comes to a specific type of frontend application. There must be some “path” or “endpoint” that a user is reaching to get to the frontend application.
That’s where Ingress Controllers come into play.
An Ingress Controller is essentially a specialized load balancer. It takes traffic from outside parties (clients, users, etc.) and sends the traffic to the backend Kubernetes service. It handles all of the routing to get from a user trying to reach the UI all the way to the Kubernetes Service. After it reaches the Kubernetes Service, it’s the job of the Kubernetes Service to route it to the backend Pods.
When you’re reading the above, it may sort of sound like that’s what the LoadBalancer type on a Kubernetes Service already does, so why would you use it? In the next section, you’re going to learn about use cases around an Ingress Controller.
Ingress Use Cases
From a frontend routing perspective, Kubernetes Services have two primary ways for a user to reach the service:
Load Balancer type
Node Port type
There are other Kubernetes Service types, but the above two are typically how end users reach a frontend application Here’s the problem when it comes to the above two ways.
First, if you’re thinking about node ports, that’s a lot of ports that you need to manage. A Node Port publicly exposes the port, which is fine in this case because that’s what you want, but you still have to keep track of all of those ports. Let’s say you have twenty frontend applications. Do you really want to have to keep track of all of the ports? The other major downside here is that although it’s fine for the port to be exposed, IP addresses need to be exposed. When accessing a node port, users will send requests to the IP of a worker node on node port values that are specified by the Service. Do you really want multiple IP addresses of nodes to be public?
If you don’t like the above way, which isn’t ideal, there’s the load balancer type. From a technical perspective, this is a great method. You expose a Kubernetes Service as a load balancer and users can access it just like any other loadbalanced app. Here’s the problem - well, two problems. First, if you’re in the cloud, cloud load balancers cost money. If you have twenty exposed frontend apps, that can get pretty costly. Not to mention you have to manage all of those load balancers. Second, if you’re on-prem, that means you need to create multiple virtualized on-prem load balancers using something like Metallb, which can begin to get cumbersome.
These two problems, amongst others, are why engineers go towards Ingress Controllers.
With an Ingress Controller, it’s one load balancer. However, the Ingress can point to multiple Kubernetes Services via paths. Therefore, you only have one load balancer to manage multiple Kubernetes Services.
Below is an example. See how there are two services? The two services are pointing to two different paths, which is how the Ingress Controller can point users to the right place.
Where Does Portainer Come Into Play
At this point, you may be wondering where Portainer comes in here for Ingress Controllers. There are three ways to think about what Portainer does for Ingress:
It gives you an easier installation method.
You’re able to manage Ingress properly.
You can get a visual of Ingress information and workloads.
In an upcoming section, you’re going to see the three bullet points above in action. Before that, let’s break them down.
First, there’s the installation piece of Ingress. Typically, engineers are installing Ingress via Helm Charts. You can go directly to the Kubernetes Manifests to do this, but it’s pretty cumbersome compared to running the Helm Chart. However, in Portainer, you can do both. You can install via the Helm Chart or run an application deployment to install the Ingress Controller directly from the Kubernetes Manifests. You could even open up the Kubernetes shell in Portainer and run the Helm Chart configuration as you see in the code below.
Outside of the installation, you’re able to manage Ingress Controllers from a visual perspective and see routes, ports open, and what Services are connected to the Ingress Controller. Overall, you have the ability to manage Ingress without having to rely on kubectl .
In an upcoming section, you’re going to see a full hands-on visual of how Portainer works with Ingress controllers. The purpose of this section is to give you the reasoning behind it from a theoretical perspective.
Now that you know some theory behind Ingress and where Portainer fits in, let’s learn about the two different methods of managing Ingress - with and without Portainer.
First, let’s start with installing Ingress on a standalone Kubernetes cluster.
To get started, you need to ensure that you’re on the proper Kubernetes cluster, your Kubeconfig has the proper Kubernetes context, and you have the proper permissions.
Run the following command to ensure you’re on the cluster you’re expecting.
Once you’ve confirmed the cluster, you can start the Ingress installation.
First, specify the Namespace that the Ingress Controller will be installed in.
Next, ensure that you have the Helm Chart available for the Ingress Controller and it’s up to date.
Finally, install the Ingress Controller. Depending on which cloud you’re in or if you’re on-prem, there are going to be a few different ways that you can install in terms of what addons (annotations) you want to utilize.
The example below is configuring an Azure Load Balancer for AKS, but you can take that out or add in other annotations based on the Kubernetes environment you’re deploying to.
Altogether, the process is pretty straightforward, right? Installing and configuring an Ingress Controller isn’t all that bad outside of Portainer using a standalone Kubernetes environment. However, there are a few nuances.
First, depending on how many Kubernetes environments you’re installing Ingress Controllers on, you have to constantly switch your Kubernetes context and ensure proper Kubeconfig permissions for each cluster. This is super manual.
Second, and again, from a manual perspective, you have to run the Helm Chart manually. Imagine having to do this for multiple clusters? It could end up being cumbersome. The next best solution here outside of Portainer would be to use GitOps to deploy, but no one is really doing that for Ingress Controllers and although it would work, it would feel like duct tape as an Ingress Controllers installation isn’t supposed to change.
In the GitOps world, there’s a funny, yet ironic saying - “if you’re using Kubectl, you’re doing it wrong”.
Let’s face it, using kubectl to deploy is fine if you’re in a dev environment and just messing around to test new features, but it’s not an ideal scenario for production-level workloads. You can’t scale one engineers laptop, and therefore, you can’t scale the deployment method of running kubectl apply -f .
With Portainer in general, but in this case, with Ingress, you don’t have to worry about using kubectl (although, you technically can be if you want to).
Let’s break down this section into two different subsections - installation, management and the new Ingress feature.
First, there’s the installation. In the previous standalone section, you saw the Helm Chart that you can run from the terminal. Technically, you can do that via the kubectl shell in Portainer, but it wouldn’t make much sense as Helm is supported in Portainer, which makes the installation and overall management of the Ingress Controller much easier.
First, click on the Helm option in your Kubernetes environment via Portainer.
Next, add the URL for the Ingress Controller Helm chart.
Once added, you’ll see that the Helm Chart for Nginx Ingress exists and you can click on it.
Once you click on the Ingress Controller, set what Kubernetes Namespace you want the Ingress Controller to be deployed to and the name of the Deployment.
Just like that, Nginx Ingress is installed! Extremely straightforward and the installation is a breeze when using Helm.
Once installed, go to your Kubernetes environment and click Cluster —> Setup.
Under Networking, you’ll now see the Nginx Ingress Controller added.
You’ll now be able to properly manage your Ingress Controller via Portainer, which you’ll learn about in the next section.
After the Ingress Controller is installed, you can go to the application list for your Kubernetes environment and see that it exists. You’ll be able to see information like the container image used for the Ingress Controller, the application type, the status, the published URL of where you can reach the Ingress Controller for your deployed applications, and a ton of other information.
Moving to port mappings, you can see the publishing mode showcasing that it’s a load balancer and the ports that applications will be available on via the Ingress Controller. In this case, it’s over port 80 and port 443.
Diving into the overall Ingress Controller itself, you can access some more information via the Namespace that the Ingress Controller resides in.
When you look at the details of the Ingress Controller via the Namespace, it’s more about the overall health of the
Ingress Controller and how it’s running vs in the application listing section, it’s more around the Dev information of the Ingress Controller (application access, ports, URL, etc.)
You can see how to access the Nginx Ingress Controller, along with port information, Cluster IP information, and the Type of Ingress Controller.
You’re also able to see a full list of events/logs that occur for the Ingress Controller, which gives you insight into how the Ingress Controller is performing, audit events that may occur, and how the development aspect of the Deployment (the Pods) are running and whether it’s successful or not.
Overall, you get way more options from an installation and management perspective if you decide to use Portainer to work with Ingress Controllers.
New Ingress Feature
When it comes to managing an Ingress Controller inside of Portainer, you can think of it like seeing the key visuals of how your Ingress Controller is running and the health of the Ingress Controller. Since Portainer v2.16, there’s a new menu feature called Ingresses.
Before jumping into the Ingress option, you’ll need a Kubernetes Deployment and Service to create the Ingress route. For the purposes of this blog post, let’s use a basic hello world app. The Manifest below is an “AKS hello world”, but it works perfectly fine if you’re not using AKS.
Deploy the below in your environment.
Once the app is deployed, in Portianer, click on the new Ingresses option.
As you can see on your screen and in the screenshot below, there are no current Ingress routes. Let’s create one.
There are two options to create an Ingress route:
Add with form: This option is new from Portainer and gives you an easier way to create an Ingress route other than using a Kubernetes Manifest.
Create from manifest: This option is the same as any other Ingress method. You can use a Kubernetes Manifest with the ingress Kind/resource to create a new Ingress route.
Let’s choose the Create from manifest method.
First, choose a Namespace that you want your Ingress route to go to and give your route a name.
Next, choose the Build method (which in this case is web editor) and the Deployment type, which is Kubernetes.
Copy the code below and paste it into the Web editor like in the screenshot below and click the blue Deploy button.
Once deployed, you’ll be redirected to the Application list page. click on the Nginx Ingress Controller.
Click on the External button so you can see the app.
Below is a screenshot of what you should see on your screen.
The truth is, installing one or even a few Ingress Controllers without Portainer isn’t all that bad. It’s very doable. The problem is, there’s no actual way to manage the Ingress Controllers aside from using kubectl and once you have to install Ingress Controllers on multiple Kubernetes clusters, it can get very cumbersome. It’s much easier to use an orchestration management tool like Portainer to be the Ingress Controller manager for you instead of having to switch between multiple Kubernetes contexts to check on each Ingress Controller via the command line.
The other aspect is that there are a lot of management features when it comes to Portianer. Before using Portainer, a lot of engineers are used to just checking if the Ingress Controller is running on the Kubernetes cluster via kubectl and combing through a bunch of unorganized logs. With Portainer, you get a full visual into the actual Ingress environment without having to hunt down information via kubectl .
If you'd like to give Portainer a try, you can get 3 nodes free here.