Kubernetes: Ingress to communicate with internal services using HTTPS - kubernetes

I have a service (Node REST app, let's call it ABC) within the cluster. This app listens to two ports, one runs on HTTP and the other on HTTPS.
I use Ingress. I can see Ingress only use HTTP port to communicate with ABC. I got confirmed this by stopping the HTTP and running ABC on HTTPS only.
Do I have to make any specific setup in Ingress so to use HTTPS instead of HTTP to communicate with ABC? Or is it a pattern to run services within a cluster on HTTP when use Ingress?
Ingress yaml :
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- host: abc.containers.myhost.net
http:
paths:
- backend:
serviceName: my-test-node
servicePort: 9080
path: my-test-node/xyz
tls:
- hosts:
- abc.containers.myhost.net
secretName: abc1

Related

How to ByPass Traffic directly to Backend from K8S NGINX Ingress Controller

OAUTH2 is used for authentication and the OAUTH2 proxy is deployed in Kubernetes. When a request is received by the NGINX Ingress controller, it always routes the traffic to OAUTH proxy. The requirement is when the request contains a specific header (For example: abc) then those requests should be routed directly to the backend. Those shouldn't be routed to OAUTH proxy. Can this be done using some sort of an annotation in NGINX Ingress controller? Can we by pass those traffic going to OAUTH2?
You may want to have a look at https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary
Let's say you have a normal Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-backend
spec:
ingressClassName: nginx
rules:
- host: XXX
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend
port:
number: 80
Set the header name and value for your desired backend on a second Ingress, with canary enabled.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-backend-header
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: sample-header
nginx.ingress.kubernetes.io/canary-by-header-value: abc
spec:
ingressClassName: nginx
rules:
- host: XXX
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-with-header
port:
number: 80
Now, every request with sample-header: abc routes to the second ingress/service. Any other value, e. g. sample-header: test, will route to the first ingress/service.

How do you specify a custom port for the ingress controller on Minikube?

It seems to listen on 80 by default - sensible - but if I wanted it to listen for requests on (for example) 8000, how would I specify this?
For clarity, this is via the nginx controller enabled via minikube addons enable ingress)
Ingress exposes HTTP and HTTPS routes from outside the cluster to
services
within the cluster.
It means that it'll use default ports for HTTP and HTTPS ports.
From the documentation we can read:
An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type Service.Type=NodePort or Service.Type=LoadBalancer.
While in general, Ingress does not allow you to expose random things on random ports, in case of nginx-ingress, you can do it. But you have to use additional annotation.
For instance, if your pod exposes 443, but you want it to be available on port 8081 you have to do following trick:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myservice
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: nginx
nginx.org/listen-ports-ssl: "8081"
spec:
tls:
- hosts:
- host.org
secretName: my-host-tls-cert
rules:
- host: host.org
http:
paths:
- path: /
backend:
serviceName: my-service
servicePort: 443
nginx-ingress controller actually allows changing http and https ports.
See the configuration parameters:
controller.service.ports.http
controller.service.ports.https

How to get two ingress ports accessible for single service using NGINX kubernetes controller

We have one service which has two exposed ports- one is for server and second is for management. Kubernetes cluster have NGINX controller running. Is there any way to expose both the ports of service in Ingress YAML file?
Details:
Service server Port : 8081
Service Management Port: 8082
We tried with two "backends" in Ingress YAML file but it works only for default port which is 80 and fail for any other port.
ingress.yml file is as below:
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: bw-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: my.host.net
http:
paths:
- path: "/controller/"
backend:
serviceName: bw-svc1
servicePort: 80
- path: "/actuator/"
backend:
serviceName: bw-svc2
servicePort: 5612
The indentation level of both paths is not equal in your config sample.
Other than that your config looks correct and should result in the following behavior:
All traffic coming to the cluster via my.host.net/controller will be sent to service bw-svc1:80
All traffic coming to the cluster via my.host.net/actuator will be sent to service bw-svc2:5612
If this is not what you'd like to achieve, could you please re-phrase your question?

Kubernetes - How ingress routing works

I saw some example where the Kubernetes cluster is installed with ingress controller and then the ingress class is added with annotations and host as below.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: testsvc.k8s.privatecloud.com
http:
I am not sure which service is installed and which IP is configured with the DNS "k8s.privatecloud.com" so as to route requests?
How the DNS routing "k8s.privatecloud.com" routes requests to Kubernetes cluster? How the ingress to kubernetes bridging works?
Also, There could be many services configured with the hosts rule like,
testsvc.k8s.privatecloud.com
testsvc1.k8s.privatecloud.com
testsvc2.k8s.privatecloud.com
How the subdomain routing works here when we hit the service testsvc.k8s.privatecloud.com or testsvc1.k8s.privatecloud.com ...
Thanks
The DNS for all the hostnames in your given example (e.g. testsvc.k8s.privatecloud.com) would point to the machine or load-balancer through which traffic will reach the Ingress controller's nginx, as is described in the kuberetes Ingress documentation
Subdomain routing is traditionally done via "virtual-hosting", sometimes called "v-host-ing", and the nginx ingress uses the HTTP Host: header to know which backend service should receive that traffic. Some Ingress controllers are able to use SNI for that same trick over https.
In addition to #Matthew L Daniel answer.
The kubernetes Ingress works as a proxy between external network and your cluster. The behavior of the ingress is explained in the object ingress. For example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: s1
servicePort: 80
- path: /bar
backend:
serviceName: s2
servicePort: 80
Above it`s explained how to route traffic between 2 backends s1 and s2. Ingress does not hold any information about services except its name and port, every time it needs more details it would need to be requested from the api-server.

How can I generate External IP when creating an ingress that uses nginx controller in kubernetes

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: helloworld-rules
spec:
rules:
- host: helloworld-v1.example.com
http:
paths:
- path: /
backend:
serviceName: helloworld-v1
servicePort: 80
- host: helloworld-v2.example.com
http:
paths:
- path: /
backend:
serviceName: helloworld-v2
servicePort: 80
I'm making kubernetes cluster and I will apply that cloudPlatform Isolated(not aws or google).
When creating an ingress for service I can choose host url but that is not exist anywhere(that address is not registrated something like DNS server) So I can't access that url. Visiting this IP just gives a 404.
how can I get or configure URL that can access external browser
:(...
It depends on how you configure your nginx controller.
You should have a Service configured which is the entry point when accessing from outside see the docs https://kubernetes.io/docs/concepts/services-networking/ingress/#what-is-ingress.
So basically you have a Service that points to the ingress controller and this will redirect the traffic to your pods based on Ingress Objects.
Ingress -> Services -> Pods
Since you don't run on aws or google You would have to use externalIp or NodePort and configure the service accordingly
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app: ingress-nginx
spec:
selector:
app: ingress-nginx
ports:
- name: http
port: 80
targetPort: http
- name: https
port: 443
targetPort: http
externalIPs:
- 80.11.12.10
And DNS needs to be managed with whatever you have for your domains in order to resolve, or for locally testing you can just edit your /etc/hostnames
Basically in AWS or Google you just create a service with type: LoadBalancer and point your dns records to the balancer address (CNAME for aws and the IP for google)