Internal working and connection of Kubernetes Ingress Object and Ingress Controller - kubernetes

I was trying to understand the relation between Kubernetes Ingress Resource and Ingress Controller.
I read that Ingress resource is mainly the rules and controller Pods route the traffic actually for Ingress rules.
I'm confused, like other Objects why Ingress resource can not spin up PODs on its own by specifying the image.
Secondly, how Ingress Object connects to actual Ingress Controller Pods to get its work done ( or say other way round). I don't see specifying any selector in the Ingress Object.
Thirdly, if the Ingress Resource gets its own IP address ( internal or external) then why Ingress Controller needs external IP address.
thanks
PS: I do not have a great knowledge of Kubernetes, please pardon if the questions sound silly.

Details with diagram are posted in GKE tutorial
Ingress with NGINX controller on Google Kubernetes Engine

Related

K8s - Unable to reach application from outside the cluster

I am learning to deploy applications on private clusters. The application is up and running in a pod and is reachable from the node itself. I have created an ingress controller service as well, but I am not sure what's going wrong. The external IP of the nginx-ingress service always returns 404. Any ideas on the fix ?
Services running :
Application service :
Nginx service :
Application ingress :
Ingress yaml :
Looks like the Ingress is not being served by your Nginx Ingress controller at the moment. If the Ingress is served by a controller, it should have at least one IP Address under its status.loadBalancer (which should be the external IP used by the Ingress Controller which is serving it), while in your case, looks empty like this:
status:
loadBalancer: {}
The most common problem on this regard is that the Ingress does not define an Ingress Class or there is no default Ingress Class in the cluster.
First of all, do a k get IngressClass and see if there's any Ingress Class defined. in your cluster. Depending on the Kubernetes version and Ingress Controller version, it could make use of IngressClass objects or simply use annotations (or both).
I would try simply adding the annotation kubernetes.io/ingress.class: nginx under the Ingress metadata as the nginx class is usually the one defined by the Nginx Ingress Controller. Or, if your Ingress Controller is using a different Ingress Class, I'd try specify that in the annotation, then your setup should work.
If you are curious on what is the purpose of an Ingress Class, it can mostly be used to associate an Ingress resource definition, with an ingress controller. On a Kubernetes cluster, there may be more than one Ingress Controller, each one with its own ingress class and Ingress resources are associated to one of them by matching the requested ingress class.
If an ingress class is not specified, the Ingress uses the default one, which means that the IngressClass annotated to be the default one of the cluster is automatically used.
For more info, check the documentation here ( https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class )

How to access kubernetes application through ingress only

I have a kubernetes objects as below:
a deployment
a service to use with that deployment in step 1
an ingress with backend paths to the service in step 2
I am using Kubernetes Engine in GCP. Once I created an ingress object, it created a load balancer as usual.
So I have my dns, and I added a A record with a domain name test1.<my-domain>.co pointing to the IP of the LoadBalancer created from the ingress
But this is not working. It doesn't load the page.
Then I tried installing ningx ingress controller, and once that is being deployed, it created another load balancer in the gcp. So, I got the IP of that newly created load balancer and switched/changed replace the DNS record IP with newly created Load Balancer's IP. And voila, it started working. So does that mean, an ingress always need an ingress controller to work?
Yes, in order for the Ingress resource to work, the cluster must have an ingress controller running. Only creating an Ingress resource has no effect.
An Ingress controller is responsible for fulfilling the Ingress, usually with a load balancer, which is what you see.
A request from the client lands up on the Ingress managed Load Balancer which is forwarded to the respective Ingress based on the host and path in the original request. Following the routing rules defined in the ingress, request is forwarded to the service from where it lands up on the backend pods.
Ingress resource creating its own Load Balancer seems to be a behaviour followed in GKE. From the GCP docs
When you specify kind:Ingress in the resource manifest, you instruct
GKE to create an Ingress resource. By including annotations and
supporting workloads and Services, you can create a custom Ingress
controller. Otherwise, GKE makes appropriate Google Cloud API calls to
create an external HTTP(S) load balancer.
You can read more about this here.
yes ingress controller is needed to serve user request comes outside the cluster.
when user sends request on load balancer IP of ingress controller ingress controller reads route from ingress resource and forward user request accordingly.
ingress resource is a part of service. means for every service you need to have ingress resource where as a ingress controller can serve multiple ingress resource.
There are mainly two ingress controller used.
nginx
contour.
you can read about them in details.

Is it possible to have multiple ingress resources with a single GKE ingress controller

In GKE Ingress documentation
it states that:
When you create an Ingress object, the GKE Ingress controller creates a Google Cloud HTTP(S) Load Balancer and configures it according to the information in the Ingress and its associated Services.
To me it seems that I can not have multiple ingress resources with single GCP ingress controller. Instead, GKE creates a new ingress controller for every ingress resource.
Is this really so, or is it possible to have multiple ingress resources with a single ingress controller in GKE?
I would like to have one GCP LoadBalancer as ingress controller with static IP and DNS configured, and then have multiple applications running in cluster, each application registering its own ingress resource with application specific host and/or path specifications.
Please note that I'm very new to GKE, GCP and Kubernetes in general, so it might be that I have misunderstood something.
I think the question you're actually asking is slightly different than what you have written. You want to know if multiple Ingress resources can be linked to a single GCP Load Balancer, not GKE Ingress controller. Based on the concept of a controller, there is only one GKE Ingress controller in a cluster, which is responsible for fulfilling multiple resources and provisioning multiple load balancers.
So, to answer the question directly (because I've been searching for a straight answer for a long time!):
Combining multiple Ingress resources into a single Google Cloud load
balancer is not supported.
Source: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress
Sad.
However, using the nginx-ingress controller is one way to at least minimize the number of external (GCP) load balancers provisioned (it only provisions a single TCP load balancer), but since the load balancer is for TCP traffic, it cannot terminate SSL, or apply Firewall rules for you (Cloud Armor cannot be used, for instance).
The only way I know of to have a single HTTPS load-balancer in GCP terminate SSL and route traffic to multiple services in GKE is to combine the ingresses into a single resource with all paths and certificates defined in one place.
(If anybody figures out a way to do it with multiple separate ingress resources, I'd love to hear it!)
Yes it is possible to have the single ingress controller for multiple ingress resources.
You can create multiple ingress resources as per path requirement and all will be managed by single ingress controller.
There are multiple ingress controller options also available you can use Nginx also that will create one LB and manage the paths.
Inside Kubernetes if you are creating a service with type LoadBalancer it will create the new LB resource in GCP so make sure your microservice type is ClusterIP and your all traffic goes inside K8s cluster via ingress path.
When you setup the ingress controller it will create one service with type LoadBalancer you can can use that IP in DNS servers to forward the subdomain and path to K8s cluster.

List all available ingress controllers on Kubernetes

I have a GKE cluster with Traefik being used as an ingress controller.
I want to create a GKE ingress, but I can't find anywhere which kubernetes.io/ingress.class to use.
I tried to use kubernetes.io/ingress.class: gce, but nothing happened... it's almost like the ingress was completely ignored.
Is there a way to list all available ingress controllers/classes? Or, at least, which kubernetes.io/ingress.class should I use to create a GKE Ingress? (I'll still use traefik for other ingresses).
Run describe on the Ingress. If you see create/add events, you have an Ingress controller running in the cluster, otherwise, you probably have the HttpLoadBalancing(GKE Ingress Controller) add-on disabled on your GKE cluster.
On GKE, The kubernetes.io/ingress.class: gce is the default ingress class, if there is no an annotation defined under the metadata section, the Ingress Resource uses the GCP GCLB L7 load balancer to serve traffic. So have you tried setting the annotation to an empty string?
Being said that, answering the following questions it will help me to understand the contest:
Could you please define you use case? Are you trying to define two
ingress for the same service or convert to curren Traefik to a GCE
ingress?
Could you please attach your GKE ingress definition to see
if there is a sintaxis error ?

what is an ingress controller and how do I create it?

Good morning guys, so I took down a staging environment for a product on GCP and ran the deployment scripts again, the backend and frontend service have been setup. I have an ingress resource and a load balancer up, however, the service is not running. A look at the production app revealed there was something like an nginx-ingress-controller. I really don't understand all these and how it was created. Can someone help me understand because I have not seen anything online that makes it clear for me. Am I missing something?
loadBalancer: https://gist.github.com/davidshare/5a571e56febe7dacd580282b373f3095
Ingress Resource: https://gist.github.com/davidshare/d0f53912bc7da8310ec3d64f1c8a44f1
Ingress allows access to your Kubernetes services from outside the Kubernetes cluster. There are different kubernetes aka K8 resources alternatively you can use like (Node Port / Loadbalancer) which you can use to expose.
Ingress is independent resource to your service , you can specify routing rules declaratively, so each url with some context can be mapped to different services.
This makes it decoupled and isolated from the services you want to expose.
So to work ingress it needs an Ingress Controller for your cluster.
Like deployment resource in K8, ingress can be created simply by
kubectl create -f ingress.yaml
First, you have to implement Ingress Controller in order to apply Ingress resource, as described in #Shubhu answer. Ingress controller, as an edge router, applies specific logical structure with aim to route external traffic to your Kubernetes cluster underlying services via basic pattern routing rules defined in Ingress resource.
If you select Nginx Ingress Controller then it might be useful to proceed with installation guide approaching some specific prerequisites based on cloud provider environment. In order to simplify Nginx Ingress controller installation procedure it is also possible to use Helm package manager and install appropriate stable/nginx-ingress Helm chart.