What value should I use for host in a kubernetes ingress manifest? - kubernetes

I have this yaml for an Ingress:
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: app
namespace: ingress-controller
... omitted for brevity ...
spec:
rules:
- host: ifs-alpha-kube-001.example.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
serviceName: service-nodeport
servicePort: 80
- path: /
pathType: ImplementationSpecific
backend:
serviceName: service-nodeport
servicePort: 443
status:
loadBalancer:
ingress:
- {}
In the above I set ...
- host: ifs-alpha-kube-001.example.com
That host just happens to be one of my nodes. I have three nodes. I am pretty certain that this incorrect. The ingress works but if I shutdown ifs-alpha-kube-001 the ingress stops working. What should I set host if I want a high availability cluster?
Thanks

What should I set host if I want a high availability cluster?
The idea behind the Ingress resource is using the brower's host: HTTP header (which is sent for every request HTTP/1.1 and newer) for virtual hosting, so you can create one load balancer, but point all of your DNS records at the one host -- versus having to create a new load balancer for every Service in your cluster
Thus, the host: header would be whatever DNS name you wished for the outside world to be able to reach your Service as; for example, if you have a website and a reporting web-app in your cluster, one host: might be www.example.com and the other host: might be reports.example.com but both would be CNAME records for my-k8s-lb.example.com

Related

Multiple FastAPI services on the same page

I am using FastAPI to create multiple services.
It works in a somewhat strange way, but basically I have a generic FastAPI service and a CI/CD that downloads multiple installable packages to create different services from it. It's all packaged neatly, I create multiple Docker images, then they are served by Kubernetes using deployments, services (separate pods, one container per pod) and ingress.
Now, I've configured ingress to serve those services from the same host. The only thing that is different for those services is the app root path. So for example I have:
foo.example.com/foo - 1st service
foo.example.com/bar - 2nd service
If I go to foo.example.com/foo/docs, I am greeted with Swagger documentation and I can select the app root path at the top of the page. Unfortunately, there's only one option: /foo. Same for the second service, but this time it's /bar.
Now I know that those services run in separate containers in separate pods in my k8s cluster, but I was wondering if there's a way to for example go to foo.example.com or to a particular service like foo.example.com/foo and have all the services listed in Swagger's drop-down menu, so I can select any of them and be redirected to it. It would be huge improvement from a user experience point of view.
#Edit, Ingress manifest file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$1
external-dns/manage-entries: "true"
spec:
rules:
- http:
paths:
- path: /foo/(.*)
pathType: Prefix
backend:
service:
name: foo-service
port:
number: 80
host: test.example.com
- http:
paths:
- path: /bar/(.*)
pathType: Prefix
backend:
service:
name: bar-service
port:
number: 80
host: test.example.com
- http:
paths:
- path: /baz/(.*)
pathType: Prefix
backend:
service:
name: baz-service
port:
number: 80
host: test.example.com

How to setup Ingress for AWS EKS Application Load Balancer(ALB) for multiple microservices?

I have 5 microservices which I wish to allow external traffic to. These microservices will be hosted on different subdomains. I am using K8s cluster on EKS and have the cluster and other services running.
There seems to be quite a lot of confusion when it comes to Ingress. I have configured the ALB ingress controller by following this tutorial on eksworkshop. This worked for me and I am able to deploy the 2048 game as the tutorial explains.
Now what I wish to develop is an Ingress resource as following:
# apiVersion: networking.k8s.io/v1beta1
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cluster-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- host: app.my-domain.com
http:
paths:
- path: /*
backend:
serviceName: app-cluster-ip-service
servicePort: 3000
- host: ms1.my-domain.com
http:
paths:
- path: /*
backend:
serviceName: ms1-cluster-ip-service
servicePort: 8000
- host: ms2.my-domain.com
http:
paths:
- path: /*
backend:
serviceName: ms2-cluster-ip-service
servicePort: 2000
- host: ms3.my-domain.com
http:
paths:
- path: /*
backend:
serviceName: ms3-cluster-ip-service
servicePort: 4000
- host: website.my-domain.com
http:
paths:
- path: /*
backend:
serviceName: website-cluster-ip-service
servicePort: 3333
So here are my doubts
How do I configure ingress to redirect to different ports based on the domain? (when I was using Nginx, there is a provision to set Upstream and then Nginx routes traffic accordingly)
What is the procedure to link it to my registered domain? (TLS certificates with Cert manager Lets Encrypt)
What should I put in my DNS records for all the subdomains? (A records/CNAME of ALB) And do all the 5 subdomains have the same record/config?
I use Cloudflare for DNS management if that helps.
Application load balancer uses the rules to conditional route the requests to different hosts/paths. So AWS load balancer controller supports that feature via annotations, see doc for detail.
You can cert manager to manage the certificates of your domain. Also AWS load balancer supports specifying the certificate stored in ACM if you use a wildcard cert.
Yes, you have to create multiple DNS records for your domains whatever the ingress controller you’re using. You can have a look at external-dns to make it automatically.

Ingress-controller redirect to serviceName according to ip addresses

I have an ingress controller and two nginx in one Kubernetes namespace. One service has the name nginx-1 and the second name nginx-2.
I need to create a situation where nginx-1 will be default backend, and nginx-2 will be a target for a few IP addresses.
I have tried to do this using a ConfigMap but without results.
Maybe someone had a problem like this?
Never saw on Kubernetes docs something like this, but I would like to purpose another approach. You can configure your ingress to use named based virtual hosting, so that few IP addresses would connect using a different domain.
Here and example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
Reference: https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting

Redirection from http to https not working for custom backend service in Kubernetes Nginx Ingress Controller

I have setup Custom Nginx ingress controller with Ingress resource in Kubernetes and instead of "default-http-backend service", I used custom application as the default backend service to be served for default requests. I have also used custom SSL which is set as kubernetes secret, for my service. The issue is that when I request the hostnames which are mentioned in the rules, the https redirection works. But when the requests other than the hosts mentioned in the rules are made, it serves the default app, but the https redirection does not work.
How can I redirect requests from http to https for all the requests including default requests. In other words, how to setup https redirection for wildcard domains in ingress resource.
Please find my yaml files for ingress resource.
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-resource
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
kubernetes.io/ingress.allow-http: "false"
ingress.kubernetes.io/rewrite-target: /
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/proxy-connect-timeout: "14400"
ingress.kubernetes.io/proxy-send-timeout: "14400"
ingress.kubernetes.io/proxy-read-timeout: "14400"
spec:
tls:
- secretName: tls-secret
rules:
- host: service1.example.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
- host: service2.example.com
http:
paths:
- path: /
backend:
serviceName: service2
servicePort: 80
---
I needed to configure custom service (not default-http-backend service) for default requests which does not have rules set and this custom service should use custom SSL. At present nginx-ingress-controller doesn't do anything if the domain names are omitted from the Ingress rules (with the intention of the "wildcard" TLS cert being used).
Therefore I have added the following code in the ingress yaml I used and this works perfectly. I have added the wildcard tls name in ingress rules at the bottom for the custom default service. Please find the code below:
rules:
- host: service1.example.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
- host: service2.example.com
http:
paths:
- path: /
backend:
serviceName: service2
servicePort: 80
- host: '*.example.com'
http:
paths:
- path: /
backend:
serviceName: custom-backend-service
servicePort: 80

kubernetes gke multiple ingresses single global ip

I have multiple MSA on k8s on GKE. Each is on separate subdomain like:
msa1.example.com
msa2.example.com
I have it in single ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: main-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: lalala-ip-1
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
- hosts:
- msa1.example.com
secretName: msa1-tls
backend:
serviceName: sink
servicePort: 80
rules:
- host: msa1.example.com
http:
paths:
- path: /.well-known/*
backend:
serviceName: letsencrypt
servicePort: 80
- path: /*
backend:
serviceName: lalala
servicePort: 80
- host: msa2.example.com
http:
paths:
- path: /*
backend:
serviceName: lalala2
servicePort: 80
... and all is nice.
The thing is, that I want to have each MSA in separate file.
Problem is this kubernetes.io/ingress.global-static-ip-name: lalala-ip-1 line. If I have it in two ingresses only first started is bounded to IP, but other ones no.
Is there a way, to share IP on GKE ingress controller between two ingresses?
A way around it could be to run your own nginx-ingress controller in your cluster and expose it via LoadBalancer service type. Then you would have 1 IP for your ingress and be able to serve all ingresses via nginx controller by adding annotation kubernetes.io/ingress.class: "nginx"
Reference: https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/
Confirmed my comment:
Only one resource at a time can use a static external IP address.
https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address
GKE has recently added support for the new Kubernetes Gateway API. Both the GKE Gateway implementation as well as the Kubernetes Gateway API specification are still in alpha at this point.
The Kubernetes Gateway-API, is intended to support use cases, where you have a central Gateway (with a single IP), but want different Routes (with different hostnames or paths), managed in separate objects or even namespaces.
References:
https://gateway-api.sigs.k8s.io/
https://cloud.google.com/kubernetes-engine/docs/concepts/gateway-api