OpenShift Ingress external service - kubernetes

tell me how to map an external resource as a service in openshift for use in ingress?
OKD 3.11.
I am creating a service type ExternalName
apiVersion: v1
kind: Service
metadata:
name: "sso"
namespace: "test"
spec:
type: ExternalName
externalName: sso.test.org
Then I create a ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example
namespace: test
spec:
rules:
- host: app.test.org
http:
paths:
- path: /
backend:
serviceName: ui
servicePort: 8080
- path: /auth
backend:
serviceName: sso
servicePort: 443
- path: /api
backend:
serviceName: api
servicePort: 8080
But I get the error "Application is not available" for /auth.
/api and / works fine.
What could be the mistake?
I have a problem when accessing external ports with ssl. When accessing ports without ssl, no problems. It seems that haroute does not add https at the beginning of the address, and the request goes through http:// sso:443

Related

Dynamic Routing by Hostname only - Kubernetes Ingress Rules

I have a K8s cluster with multiple different services deployed and would like to use a single Ingress to route each incoming request to the appropriate service via a unique hostname DNS.
Currently, I've only been able to resolve a request when using the root path i.e. service-123.app.com.
As soon as I try to make a request with a path it doesn't resolve. The paths are valid paths to each service. For example, service-123.app.com/page/12345 would be expected by the application.
I might not fully understand how K8s Ingress rules are expected to work, but I hoped that it would match based on hostname only and simply forward on the path to the appropriate service.
Am I missing something very simple here? Any help is much appreciated. Thanks!
Here are my config files.
Ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
......
name: app-name
namespace: default
spec:
rules:
- host: service-123.app.com
http:
- path: "/*"
backend:
serviceName: service-123
servicePort: 80
- host: service-456.app.com
http:
paths:
- path: "/*"
backend:
serviceName: service-456
servicePort: 80
service.yaml
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
app: service-123
name: service-123
namespace: default
spec:
ports:
- name: port8080
port: 80
targetPort: 8080
selector:
app: service-123
type: NodePort
Not sure which K8s and ingress controller you are using, but in the later K8s you can specify the pathType which takes care of path wildcards more nicely.
You would have something like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
......
name: app-name
namespace: default
spec:
rules:
- host: service-123.app.com
http:
- path: /
pathType: Prefix
backend:
serviceName: service-123
servicePort: 80
- host: service-456.app.com
http:
paths:
- path: /
pathType: Prefix
backend:
serviceName: service-456
servicePort: 80
If you are using an nginx ingress controller a good way to see the right nginx configuration is by looking at the actual nginx.conf generated by the ingress controller.
$ kubectl cp <nginx-ingress-controller-pod>:nginx.conf nginx.conf
$ cat nginx.conf

Kubernetes ingress - access to web service container subpaths

I have a web service (dashboard-service) running in a container. The service provides the required webpages at:
http://192.168.1.100:3000/page2/
http://192.168.1.100:3000/page3/
etc
I have the dashboard-service running in a kubernetes cluster, and want to use ingress to control access like this:
so that I can access at: http://192.168.1.100:3000/dashboard/1
http://192.168.1.100:3000/dashboard/2
etc
I've tried the following ingress setup, but am getting "404 Not Found"
Is there some way of adding routes to subpaths?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-service
namespace: db
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /dashboard/
pathType: Prefix
backend:
service:
name: dashboard-service
port:
number: 3000
First of all, there is no below configuration in ingress
backend:
service:
name: dashboard-service
port:
number: 3000
You should use next instead..
- backend:
serviceName: dashboard-service
servicePort: 3000
Next, I would propose you install, configure and use nginx ingress controller instead of regular kubernetes-ingress. Please note also, if you use nginx controller, your annotation should be nginx.ingress.kubernetes.io/rewrite-target: , not ingress.kubernetes.io/rewrite-target:
As per NGINX Ingress Controller rewrite documentation, your ingress should look like
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /page$2
name: dashboard-service
namespace: db
spec:
rules:
http:
paths:
- backend:
serviceName: dashboard-service
servicePort: 3000
path: /dashboard(/|$)(.*)
I tested regex and capture groups for you here: https://regex101.com/r/3zmz6J/1

Not able to access multiple services from ingress controller hosted on different ports

I have two services hosted on different ports and I have created a ingress resource which looks like this
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /svc1/
backend:
serviceName: app1-svc
servicePort: 3000
- path: /svc2/
backend:
serviceName: app2-svc
servicePort: 8080
on top of this I have created a NodePort type ingress controller.
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-ingress
name: controller-nginx-ingress-controller
spec:
clusterIP: 10.88.18.191
externalTrafficPolicy: Cluster
ports:
- name: http
nodePort: 30080
port: 80
protocol: TCP
targetPort: http
- name: https
nodePort: 31442
port: 443
protocol: TCP
targetPort: https
selector:
app: nginx-ingress
component: controller
release: controller
And finally, setup a cloud load balancer to access application running on my K8S cluster.
Problem:
I couldn't able to access any of my application using URL routing
http://load-balancer-ip/svc1/
http://load-balancer-ip/svc2/
Can anyone please let me know what incorrect I'm doing? And how to resolve this issue?
From what you mentioned in comments I am pretty sure the problem can be solved with path rewrites.
Now, when you are sending a request to /svc1/ with path: /svc1/ then the request is forwarded to app1-svc with path set to /svc1/ and you are receiving 404 errors as there is no such path in app1. From what you mentioned, you can most probably solve the issue using rewrite. You can achieve it using nginx.ingress.kubernetes.io/rewrite-target annotation, so your ingress would look like following:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress
namespace: mynamespace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /svc1(/|$)(.*)
backend:
serviceName: app1-svc
servicePort: 3000
- path: /svc2(/|$)(.*)
backend:
serviceName: app2-svc
servicePort: 8080
In this case when sending request with path set to /svc1/something the request will be forwarded to app1 with path rewritten to /something.
Also take a look in ingress docs for more explanation.
Let me know if it solved you issue.

SignalR Websocket via K8S ingress

I have an simple SignalR Client Server setup, where my Server consist of an Webapplication running in a kubernetes cluster, exposing a service via an ingress controller as such:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
# Enable PROXY protocol
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
name: coreapilocal-ingress
spec:
rules:
- host: coreapilocal.localhost
http:
paths:
- backend:
serviceName: coreapilocal-service
servicePort: 80
path: /
- backend:
serviceName: coreapilocal-service
servicePort: 80
path: /*
And a HTML Client that tries to invoke a SignalR Server method via the ingress?
But for some reason is this call being ignored for some reason?
I read somewhere that Http is being stripped by the ingress? and thereby can't recognize the call?
Is there someway to avoid this? or get around this?
I tried above given a different post I found here in SE, but this does not seem to work in my case..
For SignalR to work (and in general for WebSockets) you should enable Sticky Sessions
Add the annotation nginx.ingress.kubernetes.io/affinity: "cookie" to the ingress workload definition:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
# Enable PROXY protocol
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
nginx.ingress.kubernetes.io/affinity: "cookie"
name: coreapilocal-ingress
spec:
rules:
- host: coreapilocal.localhost
http:
paths:
- backend:
serviceName: coreapilocal-service
servicePort: 80
path: /
- backend:
serviceName: coreapilocal-service
servicePort: 80
path: /*

how to configure ingress to direct traffic to an https backend using https

I have a backend using https.
I want to separate load on that back-end based on URL/path.
I decided to use ingress to do this url/path based logic in order to move traffic to different back-ends ( same back-ends , just duplicated to different NodePorts )
my question is how I can configure the ingress to receive https requests and to forward those https requests to the https back-end?
thanks
edit:
I added the yaml file:
spec:
rules:
- http:
paths:
- backend:
serviceName: service
servicePort: 9443
path: /carbon
- backend:
serviceName: service2
servicePort: 9443
path: /oauth
for some reason I can;t change the rule form http to https
Attention: This answer applies to the ingress-nginx solution provided by the kubernetes organisation on github (https://github.com/kubernetes/ingress-nginx)
If you want to use load balancing mechanisms in k8s you should use services instead and start multiple instances behind that service that way k8s will do the load balancing. If you want to use different versions of your backend (e.g. prod and test) your way of separating them is fine
if your service is only reachable via https you need to add the following annotation to your ingress yaml: (documentation)
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
To secure ingress itself take a look at this: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls
But if you want that the backend services decrypt the TLS communication use the following annotation instead: (documentation)
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
Edit:
The Ingress YAML should look like this if you want to reach the backend via TLS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-name
namespace: namespace-name
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- http:
paths:
- backend:
serviceName: service
servicePort: 9443
path: /carbon
- backend:
serviceName: service2
servicePort: 9443
path: /oauth
The Ingress YAML should look like this if you want to reach the backend via TLS with TLS decryption in the ingress controller:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-name
namespace: namespace-name
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- app.myorg.com
secretName: tls-secret
rules:
- http:
paths:
- backend:
serviceName: service
servicePort: 9443
path: /carbon
- backend:
serviceName: service2
servicePort: 9443
path: /oauth
It's important to note that tls-secret is the name of a SecretConfig with a valid Certificate issued for the host (app.myorg.com)
The Ingress YAML should look like this if you want to reach the backend via TLS with TLS decryption in the backend:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-name
namespace: namespace-name
annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
rules:
- http:
paths:
- backend:
serviceName: service
servicePort: 9443
path: /carbon
- backend:
serviceName: service2
servicePort: 9443
path: /oauth
I never tested the last version myself so i don't know if that actually works but I'd strongly advise reading this passage for that variant.
If you are using the NGINX Ingress controller (https://docs.nginx.com/nginx-ingress-controller/), the nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" does not work. However, the nginx.org/ssl-services will let you pick the services that require TLS on the backend. The name is confusing, so it took me a while to realize the real purpose of it.
This does not work with the standard Kubernetes Ingress controller that uses NGINX under the hood; it only works with the NGINX-sourced controller.
Advanced annotation docs: https://docs.nginx.com/nginx-ingress-controller/configuration/ingress-resources/advanced-configuration-with-annotations/
In this example, NGINX will connect to the ssl-svc using TLS; it ignores any self-signed certificates. Example (https://github.com/nginxinc/kubernetes-ingress/tree/v1.12.0/examples/ssl-services):
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
nginx.org/ssl-services: "ssl-svc"
spec:
rules:
- host: cafe.example.com
http:
paths:
- path: /tea
backend:
serviceName: tea-svc
servicePort: 80
- path: /coffee
backend:
serviceName: coffee-svc
servicePort: 80
- path: /ssl
backend:
serviceName: ssl-svc
servicePort: 443