How to fix routes configuration for the gce ingress? - google-cloud-platform

The ingress calls random services on requests, and also it calls the root (/). I need ingress to call the specified in the configuration service and send the full path to the service (I use MVC pattern so I need to provide the application with the full path to resolve the correct controller)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: whatever
annotations:
ingress.kubernetes.io/add-base-url: "true"
ingress.kubernetes.io/rewrite-target: "/"
kubernetes.io/ingress.class: "gce"
kubernetes.io/ingress.global-static-ip-name: "my-static-ip-name"
spec:
tls:
- secretName: my-tls-secret
hosts:
- whatever.my-awesome-project.com
rules:
- host: whatever.my-awesome-project.com
http:
paths:
- path: /api/whatever
backend:
serviceName: whatever-service
servicePort: 80
- path: /api/not-whatever
backend:
serviceName: not-whatever-service
servicePort: 80
- path: /images/*
backend:
serviceName: not-whatever-service
servicePort: 80

From what I see in your question:
1) you are trying to use rewrite-target with gce ingress --> this wont work. rewrite-target is a nginx ingress controller feature. Btw starting from 0.22.0 version you should use nginx.ingress.kubernetes.io/rewrite-target: "/" instead of ingress.kubernetes.io/rewrite-target: "/"
2)The annotation add-base-url was removed in 0.22.0. And this is also was nginx annotation, not gce. More info here an here.
3)Also I believe you dont need rewrite-target annotation if you would like to have correct path
From my pow there should be something like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: whatever
annotations:
kubernetes.io/ingress.class: "nginx"
kubernetes.io/ingress.global-static-ip-name: "my-static-ip-name"
spec:
tls:
- secretName: my-tls-secret
hosts:
- whatever.my-awesome-project.com
rules:
- host: whatever.my-awesome-project.com
http:
paths:
- path: /api/whatever
backend:
serviceName: whatever-service
servicePort: 80
- path: /api/not-whatever
backend:
serviceName: not-whatever-service
servicePort: 80
- path: /images/*
backend:
serviceName: not-whatever-service
servicePort: 80
A lot of things depends on what ingress and version you use. Do you have a possibility to move to nginx?

Related

ingress always showing default backend - 404

I am trying to install the Cyclos Mobile app on GCP using the demo given on youtube on this URL: https://www.youtube.com/watch?v=LmfdhOXK_ik
Everything setup perfectly as per this video but when I am trying to access the setup on browser it always showing default backend - 404. I have tried everything as per stack overflow several previous questions but still same error.
Any I idea to fix this ?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencypt-staging
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{"cert-manager.io/cluster-issuer":"letsencypt-staging","kubernetes.io/ingress.class":"nginx","nginx.ingress.kubernetes.io/proxy-connect-timeout":"3600"},"name":"cyclos-ingress-nginx-https","namespace":"cyclos-name-space"},"spec":{"backend":{"serviceName":"default-http-backend","servicePort":80},"rules":[{"host":"ip-address.xip.io","http":{"paths":[{"backend":{"serviceName":"cyclos-app-stateful","servicePort":80},"path":"/*"}]}}],"tls":[{"hosts":["ip-address.xip.io"],"secretName":"ip-address.xip.io-tls-secret"}]}}
kubernetes.io/ingress.class: nginx
creationTimestamp: "2020-09-29T07:00:01Z"
generation: 11
name: cyclos-ingress-nginx-https
namespace: cyclos-name-space
resourceVersion: "643221534"
selfLink: /apis/extensions/v1beta1/namespaces/cyclos-name-space/ingresses/cyclos-ingress-nginx-https
uid: uid
spec:
backend:
serviceName: default-http-backend
servicePort: 80
rules:
- host: ip-address.xip.io
http:
paths:
- backend:
serviceName: cyclos-app-stateful
servicePort: 80
path: /*
tls:
- hosts:
- ip-address.xip.io
secretName: ip-address.xip.io-tls-secret
status:
loadBalancer:
ingress:
- ip: IP

Redirect non www to www using ALB Ingress Controller

I am trying to redirect a non www request to www. I checked the annotations here https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/ but could not find specific to non www to www redirect.
I already have a http to https redirect set and it's working.
below is my ingress resource manifest file.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: eks-learning-ingress
namespace: production
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/certificate-arn: ard878ef678df
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
labels:
app: eks-learning-ingress
spec:
rules:
- host: www.myhost.in
http:
paths:
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation
- path: /*
backend:
serviceName: eks-learning-service
servicePort: 80
Any help in this would be great. Thanks.
There are 2 ways of doing non-www to www redirections, 1. using alb.ingress.kubernetes.io/actions, 2. alb.ingress.kubernetes.io/conditions.
alb.ingress.kubernetes.io/actions
alb.ingress.kubernetes.io/actions.${action-name} Provides a method for
configuring custom actions on a listener, such as for Redirect
Actions.
The action-name in the annotation must match the serviceName in the
ingress rules, and servicePort must be use-annotation.
We need to have one more annotation, which tells ALB how to configure redirection:
alb.ingress.kubernetes.io/actions.redirect-to-www: >
{"Type":"redirect","RedirectConfig":{"Host":"www.myhost.in","Port":"443","Protocol":"HTTPS","StatusCode":"HTTP_302"}}
And one more host rule to catch your request domain myhost.in and redirect to www.myhost.in
- host: myhost.in
http:
paths:
- path: /*
backend:
serviceName: redirect-to-www
servicePort: use-annotation
alb.ingress.kubernetes.io/conditions
alb.ingress.kubernetes.io/conditions.${conditions-name} Provides a
method for specifying routing conditions in addition to original
host/path condition on Ingress spec.
The conditions-name in the annotation must match the serviceName in
the ingress rules. It can be a either real serviceName or an
annotation based action name when servicePort is "use-annotation".
In addition to the annotation we have added above, we continue to add conditions to annotations to filter the request but no need to have the host rule above.
alb.ingress.kubernetes.io/actions.redirect-to-www: >
{"Type":"redirect","RedirectConfig":{"Host":"www.myhost.in","Port":"443","Protocol":"HTTPS","StatusCode":"HTTP_302"}}
alb.ingress.kubernetes.io/conditions.redirect-to-www: >
[{"Field":"host-header","HostHeaderConfig":{"Values":["myhost.in"]}}]
We modify the existing host rule you currently have to achieve the redirection.
- host: www.myhost.in
http:
paths:
- path: /*
backend:
serviceName: redirect-to-www
servicePort: use-annotation
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation
- path: /*
backend:
serviceName: eks-learning-service
servicePort: 80
Update for networking.k8s.io/v1
- host: www.myhost.in
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: redirect-to-www
port:
name: use-annotation

Only the '/' works with NGINX ingress controller and ALB in AWS EKS

I created an EKS cluster and deployed an NGINX ingress controller with an Application load balancer. I deployed a sample app and tied it to my domain name.
Here is the ingress file -
kind: Ingress
metadata:
name: "2048-ingress"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
labels:
app: 2048-ingress
spec:
rules:
- host: test.abc.xyz
- http:
paths:
- path: /game
backend:
serviceName: "service-2048"
servicePort: 80
When I open test.abc.xyz/game in my browser it returns a 404 but test.abc.xyz works. Am I missing something here? I want test.abc.xyz/game to work and test.abc.xyz to return a 404.
Update -
I am following this tutorial to deploy the app -
https://aws.amazon.com/blogs/opensource/kubernetes-ingress-aws-alb-ingress-controller/
I want this app to be redirected to /game and not /
You have to define an wildcard in the path section like below:
spec:
rules:
- host: test.abc.xyz
- http:
paths:
- path: /*
backend:
serviceName: "service-2048"
servicePort: 80
- path: /game/*
backend:
serviceName: "service-2048"
servicePort: 80
Unfortunately is not well written in the documentation.

Variables in ingress host carried over to service name

My current ingress looks something like
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: web1.dev.cloud
http:
paths:
- path: /
backend:
serviceName: web1
servicePort: 8080
Meaning that the first part of the host will always match the serviceName.
So for every web pod I would need to repeat the above like:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: web1.dev.cloud
http:
paths:
- path: /
backend:
serviceName: web1
servicePort: 8080
- host: web2.dev.cloud
http:
paths:
- path: /
backend:
serviceName: web2
servicePort: 8080
I was just wondering if there is some support for doing the following:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: $1.dev.cloud
http:
paths:
- path: /
backend:
serviceName: $1
servicePort: 8080
This is not possible if you use kubectl to deploy your kubernetes manifests. However if you write a helm chart for your application it is possible. Helm uses a packaging format called charts. A chart is a collection of files that describe a related set of Kubernetes resources in the form for templates.
There in the inress.yaml template you can write such config using range block and putting the variable values in values.yaml
In your case it will look something like below
spec:
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .name }}.dev.cloud
http:
paths:
- path: {{ default "/" .path | quote }}
backend:
serviceName: {{ .name }}
servicePort: 8080
{{- end }}
and the values.yaml will have
ingress:
hosts:
- name: abc
- name: xyz
Thanks to RAMNEEK GUPTA post, you have solution how it can be automated.
According to the documentation:
Regular expressions and wild cards are not supported in the spec.rules.host field. Full hostnames must be used.
So please try as in your example:
1. Request based on the HTTP URI being requested "Simple fanout"
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: fanout
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: dev.com
http:
paths:
- path: /web1
backend:
serviceName: web1
servicePort: 8080
- path: /web2
backend:
serviceName: web2
servicePort: 8080
2. Requests based on the Host header "Named based virtual hosting"
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: Named
spec:
rules:
- host: web1.dev.com
http:
paths:
- backend:
serviceName: web1
servicePort: 8080
- host: web2.dev.com
http:
paths:
- backend:
serviceName: web2
servicePort: 8080

How do I set up a Kubernetes Ingress rule with a regex path?

I'd like to use regex in the path of an Ingress rule, but I haven't been able to get it to work. For example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cafe-ingress
spec:
tls:
- hosts:
- cafe.example.com
secretName: cafe-secret
rules:
- host: cafe.example.com
http:
paths:
- path: /tea
backend:
serviceName: tea-svc
servicePort: 80
- path: /coffee
backend:
serviceName: coffee-svc
servicePort: 80
I tried putting /t[a-z]a for the first path, but then any path I tried that should match that regex took me to the default backend instead of the service I expected.
Note: I'm using an nginx ingress controller, which should be able to support regex.
Apparently this question is still getting traffic, so I feel like I should update it. I'm no longer using the nginx ingress, so I can't verify this works. According to https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/:
The ingress controller supports case insensitive regular expressions in the spec.rules.http.paths.path field. This can be enabled by setting the nginx.ingress.kubernetes.io/use-regex annotation to true (the default is false).
The example they provide on the page would cover it:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress-3
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: test.com
http:
paths:
- path: /foo/bar/bar
backend:
serviceName: test
servicePort: 80
- path: /foo/bar/[A-Z0-9]{3}
backend:
serviceName: test
servicePort: 80
Original answer that no longer works.
It appears that the solution is ridiculously simple (at least with an nginx ingress controller) - you just need to prepend the path with "~ ":
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cafe-ingress
spec:
tls:
- hosts:
- cafe.example.com
secretName: cafe-secret
rules:
- host: cafe.example.com
http:
paths:
- path: ~ /t[a-z]a
backend:
serviceName: tea-svc
servicePort: 80
- path: /coffee
backend:
serviceName: coffee-svc
servicePort: 80
Now you just need enable regexp by annotation:
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
you can find full example here
I don't think there is an option to use regexp in Ingress objects. Ingress is designed to work with multiple IngressController implementations, both provided by cloud services or by self-hosted ingress like nginx one from kubernetes/contrib (which I use on my setup). Thus ingress should cover features that are commonly available on most common implementations, while specific, non-standard behaviours can be set using annotations (like ie. many nginx ingress features).