How to manage Ingress which routes to different helm subcharts? - kubernetes

I have the following applications (deployed with k8s) as helm subcharts:
Prometheus
Grafana
airflow-webserver
custom-application
custom-api
custom-webapp
This is nested under an umbrella chart.
The custom-webapp is the main application and should be routed to at mywebsite.com
I'm wondering how do I set up my ingress so that:
mywebsite.com routes to custom-webapp:5000
mywebsite.com/services/app routes to custom-application:5000
mywebsite.com/api/ routes to custom-api:5000
mywebsite.com/services/airflow routes to airflow:8080
mywebsite.com/services/prometheus routes to prometheus:9090
mywebsite.com/services/grafana routes to grafana:3000
Do I have 1 main ingress at the umbrella chart which routes to services exposed through subcharts? (the one i'm leaning most towards)
OR
Do I have multiple ingresses for each application ? In this case how do I tie them together?
This is hosted on GKE, and I'd kinda prefer to not pay for 1 ingress per application.

You need to configure a collection of rules that will define which connections reach which services.
You can aggregate several Ingress rules into a single Ingress definition.
If you are using Kubernetes 1.6+ you can check out this documentation regarding an nginx-ingress deployment on a Kubernetes cluster using the Helm package manager.

Related

Migrate deployments and services from stable/nginx-ingress to kubernetes/ingress-nginx

I'm trying to migrate our ingress controllers from the old stable/nginx-ingress to the newer kubernetes/ingress-nginx
I have followed their instructions for zero downtime deployments.
Create a second nginx-controller with the kubernetes/ingress-nginx helm chart.
The instanceClassName has to be different than the original.
original instanceClassName: nginx
new instanceClassName: nginx2
Update dns to point to the new nginx 2 ELB.
Get rid of the old nginx-controller
This is all great, but all of our services/deployments are attached to instanceClassName: nginx. We can update the DNS, but then the services attached to it won't receive traffic. We can update the services at the same time, but they update at different times. This will cause an outage of some type while updating.
All of the research I have done seems to stop at that controller level. It doesn't go deeper and explain how to keep all the services connected during the switch.
How can I get both nginx controllers to route traffic to the application at the same time? I have not been able to get that to happen at the service or nginx controller level.
Or maybe I'm thinking about incorrectly, and it can work in a different way.
thanks.
There are multiple methods and I have given below with Istio and providing alternate method documentations for your reference.
You can avoid down time while migrating via splitting the traffic. There are few traffic splitting tools. Kubernetes has traffic splitting in-built feature with Istio and it will help you to direct a percentage of traffic to the new ingress controller while keeping the rest of the traffic on the old ingress controller.
Install Istio in your cluster and configure your ingress resources to use Istio gateway instead of the ingress controllers directly.
Install Istio in your cluster.
Configure your ingress resources to use the Istio gateway.
Create virtual service for your ingress resources and gradually increase the traffic to the new ingress controller and also make sure to update your DNS records to point to the new ingress controllers IP.
Reference and for further information please check the official Istio page and Istio Service Mesh Workshop.
For alternative methods please refer below options:
Canary Deployments and Type Loadbalancer

Kubernetes with route fanout - Basic understanding of Service setup

I have questions about my basic understanding about the setup of my k8s cluster.
I have a K8s running on Hetzner-cloud and allocated a "physical" Loadbalancer (which can be controlled via annotations on a Service.)
I use a nginx (or traefik) as my ingress-controller.
Please correct me if I am wrong:
I create the service Loadbalancer with the annotations in the same namespace of my ingress-controller right?
Then I create an ingress with label kubernetes.io/ingress-controller=nginx in my default namespace with the settings to point to my services in the default namespace (one for frontend, one for backend)
Is this the correct way to set this up?
1.- No. Ingress Controller and your workload doesn't have to be in the same namespace. In fact, you will have the Ingress Controller running in a separate namespace than your workload.
2.-Yes. Generally speaking your Ingress rules, meaning your Ingress object, meaning your Ingress yaml and your Service must be in the same namespace. So Ingress can't transpass a namespace.
Note: There is a way to have an Ingress object to send trafffic to a Service in a different namespace.
I create the service Loadbalancer with the annotations in the same
namespace of my ingress-controller right?
No ideally your ingress controller will be running in different namespace in which your workload must not be running.
You should be keeping only the Nginx service with type : Loadbalancer other services of your workload should be ClusterIP.
So all your traffic comes inside the cluster from one point. Your flow will be something like
DNS > LB > Ingress > Service > Pods > Container
Then I create an ingress with label
kubernetes.io/ingress-controller=nginx in my default namespace with
the settings to point to my services in the default namespace (one for
frontend, one for backend)
You mentioned label ideally, it should be an annotation kubernetes.io/ingress-controller=nginx.
Yes, it's perfect. You can create different ingress with different annotation rules as per requirements for different services that you want to expose publicly.
Keep your workload in default namespace for the controller you can use different namespaces like ingress-controller in future also if you have any requirement of setting up the Monitoring tools also you can create namespace and use it for monitoring only.

Ingress resource deployment

What is the best approach to create the ingress resource that interact with ELB into target deployment environment that runs on Kubernetes?
As we all know there are different cloud provider and many types of settings that are related to the deployment of your ingress resource which depends on your target environments: AWS, OpenShift, plain vanilla K8S, google cloud, Azure.
On cloud deployments like Amazon, Google, etc., ingresses need also special annotations, most of which are common to all micro services in need of an ingress.
If we deploy also a mesh like Istio on top of k8s then we need to use an Istio gateway with ingress. if we use OCP then it has special kind called “routes”.
I'm looking for the best solution that targets to use more standard options, decreasing the differences between platforms to deploy ingress resource.
So maybe the best approach is to create an operator to deploy the Ingress resource because of the many different setups here?
Is it important to create some generic component to deploy the Ingress while keeping cloud agnostic?
How do other companies deploy their ingress resources to the k8s cluster?
What is the best approach to create the ingress resource that interact with ELB into target deployment environment that runs on Kubernetes?
On AWS the common approach is to use ALB, and the AWS ALB Ingress Controller, but it has its own drawbacks in that it create one ALB per Ingress resource.
Is we deploy also a mesh like Istio then we need to use Istio gateway with ingress.
Yes, then the situation is different, since you will use VirtualService from Istio or use AWS App Mesh - that approach looks better, and you will not have an Ingress resource for your apps.
I'm looking for the best solution that targets to use more standard options, decreasing the differences between platforms to deploy ingress resource.
Yes, this is in the intersection between the cloud provider infrastructure and your cluster, so there are unfortunately many different setups here. It also depends on if your ingress gateway is within the cluster or outside of the cluster.
In addition, the Ingress resource, just become GA (stable) in the most recent Kubernetes, 1.19.

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.

Ingress resource having backend kubernetes services in multiple namespace

I have two applications deployed in different namespace in Google Kontainer engine(GKE). I want to use a single ingress resource (Google Load Balancer) to point to both the application using path based routing. Is it possible to have backend kubernetes services in multiple namespace behind a single ingress resource. If possible, how?
You'll have to setup an nginx ingress controller and deploy ingress resources per each namespace: https://github.com/kubernetes/kubernetes/issues/17088#issuecomment-221393102