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
Related
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
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
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?
I have one master and two worker node kubernetes cluster on AWS. And I have two environments (qc and prod) in the cluster and I created two namespaces.
I have the same service running on qcand prod namespaces.
I have created ingress for both namespaces.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: prod
spec:
rules:
- host: "*.qc-k8s.example.com"
http:
paths:
- path: /app
backend:
serviceName: client-svc
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: qc
spec:
rules:
- host: "*.qc-k8s.example.com"
http:
paths:
- path: /app-qc
backend:
serviceName: client-svc
servicePort: 80
I have client-svc in both qc and prod namespaces and open the nodeport 80.
Then I created ELB service and daemonset as below.
kind: Service
apiVersion: v1
metadata:
name: ingress-svc
namespace: deafult
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:ca-central-1:492276880714:certificate/xxxxxxxxxxxxxx
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: http
- name: https
port: 443
targetPort: http
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: ingress-nginx
namespace: deafult
spec:
template:
metadata:
labels:
app: my-app
spec:
terminationGracePeriodSeconds: 60
containers:
- image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.6
name: ingress-nginx
imagePullPolicy: Always
ports:
- name: http
containerPort: 80
hostPort: 80
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/nginx-default-backend
When I tried to curl curl -iv https://gayan.qc-k8s.example.com/app/. Then Im getting an error.
2017/06/27 15:43:31 [error] 158#158: *981 connect() failed (111: Connection refused) while connecting to upstream, client: 209.128.50.138, server: gayan.qc-k8s.example.com, request: "GET /app/ HTTP/1.1", upstream: "http://100.82.2.47:80/app/", host: "gayan.qc-k8s.example.com"
209.128.50.138 - [209.128.50.138, 209.128.50.138] - - [27/Jun/2017:15:43:31 +0000] "GET /app/ HTTP/1.1" 500 193 "-" "curl/7.51.0" 198 0.014 100.82.2.47:80, 100.96.2.48:80 0, 193 0.001, 0.013 502, 500
If I curl curl -iv https://gayan.qc-k8s.example.com/app-qc, I'm getting the same issue.
Anyone has experienced this error previously ? any clue to resolve this issue?
Thank you
I solved this by https://github.com/kubernetes/kubernetes/issues/17088
An example, from a real document we use:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
namespace: dev-1
spec:
rules:
- host: api-gateway-dev-1.faceit.com
http:
paths:
- backend:
serviceName: api-gateway
servicePort: 80
path: /
- host: api-shop-dev-1.faceit.com
http:
paths:
- backend:
serviceName: api-shop
servicePort: 80
path: /
- host: api-search-dev-1.faceit.com
http:
paths:
- backend:
serviceName: api-search
servicePort: 8080
path: /
tls:
- hosts:
- api-gateway-dev-1.faceit.com
- api-search-dev-1.faceit.com
- api-shop-dev-1.faceit.com
secretName: faceitssl
We make one of these for each of our namespaces for each track.
Then, we have a single namespace with an Ingress Controller which runs automatically configured NGINX pods. Another AWS Load balancer points to these pods which run on a NodePort using a DaemonSet to run at most and at least one on every node in our cluster.
As such, the traffic is then routed:
Internet -> AWS ELB -> NGINX (on node) -> Pod
We keep the isolation between namespaces while using Ingresses as they were intended. It's not correct or even sensible to use one ingress to hit multiple namespaces. It just doesn't make sense, given how they are designed. The solution is to use one ingress per each namespace with a cluster-scope ingress controller which actually does the routing.
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).