Kubernetes ingress edit: HTTP 400 Bad request - The plain HTTP request was sent to HTTPS - kubernetes

Could there be any reason why a webapp which perfectly loads up fine gives a *HTTP 400 Bad request - The plain HTTP request was sent to HTTPS* port after the webapp's ingress has been edited manually or edited through an automated job which updates the ingress modifying the Whitelisted IPs
Apparently, this issue gets fixed when we redeploy the webapp after purging the webapp deployment...
Any pointers to this would be great as this happens on our PROD env and not reproducible on any lower envs.
Points to note:-
- Nginx Ingress controller setup is the same across lower envs and Prod env.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/force-ssl-redirect: "true"
ingress.kubernetes.io/ingress.allow-http: "false"
ingress.kubernetes.io/proxy-body-size: 20M
ingress.kubernetes.io/secure-backends: "true"
ingress.kubernetes.io/whitelist-source-range: xxx.yy.zz.pp/32, yyy.ss.dd.kkl/32
ingress.kubernetes.io/whitelist-source-range-status: unlocked
creationTimestamp: 2018-11-29T15:34:05Z
generation: 5
labels:
app: xyz-abc-pqr
name: xxxx-webapp-yyyy-zzzz
namespace: nspsace-name
resourceVersion: "158237270"
selfLink: /apis/extensions/v1beta1/namespaces/nspsace-name/ingresses/xxxx-webapp-yyyy-zzzz
uid: 348f892e-f3ec-11e8-aa6f-0a0340041348
spec:
rules:
- host: ssssssss.wwwwweewwerwerw.co.uk
http:
paths:
- backend:
serviceName: xxxx-webapp-yyyy-zzzz
servicePort: 443
path: /
- host: xxxx-webapp-yyyy-zzzz.bbbbv.lasdfkla.ajksdfh.ioohhsaf.pp
http:
paths:
- backend:
serviceName: xxxx-webapp-yyyy-zzzz
servicePort: 443
path: /
tls:
- hosts:
- ssssssss.wwwwweewwerwerw.co.uk
- xxxx-webapp-yyyy-zzzz.bbbbv.lasdfkla.ajksdfh.ioohhsaf.pp
secretName: xxxx-webapp-yyyy-zzzz-server-tls
status:
loadBalancer:
ingress:
- {}

There may be something wrong with the ingress controller and how it updates its configuration. I'm assuming you are using a nginx ingress controller so you can inspect the configs before an after:
$ kubectl cp <nginx-ingress-controller-pod>:nginx.conf nginx.conf.before
$ kubectl edit ingress <your-ingress>
$ kubectl cp <nginx-ingress-controller-pod>:nginx.conf nginx.conf.after
$ diff nginx.conf.before nginx.conf.after
You can see the this may happen with nginx because of something like this: Dealing with nginx 400 "The plain HTTP request was sent to HTTPS port" error.

Related

K8S traffic to one service via two separate ingress (http + https)

So I have a bunch of services running in a cluster, all exposed via HTTP only ingress object, example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: some-ingress
spec:
ingressClassName: nginx
rules:
- http:
paths:
- backend:
service:
name: some-svc
port:
number: 80
path: /some-svc(/|$)(.*)
pathType: Prefix
They are accessed by http://<CLUSTER_EXTERNAL_IP>/some-svc, and it works ofc.
Now I want to create an additional ingress object for every service which will force SSL connections and allow the use of a domain instead of an IP address.
The problem is that the newer SSL ingresses always return 404 while testing the connection.
The manifests are as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "some-ingress-ssl"
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/app-root: "/some-svc"
spec:
tls:
- hosts:
- foobar.com
secretName: foobar-tls
rules:
- host: foobar.com
http:
paths:
- path: /some-svc(/|$)(.*)
pathType: Prefix
backend:
service:
name: some-svc
port:
number: 80
tests (foobar.com point to CLUSTER_EXTERNAL_IP):
> curl -I http://<CLUSTER_EXTERNAL_IP>/some-svc
HTTP/1.1 200 OK
> curl -I https://foobar.com/some-svc
HTTP/2 404
Is it possible to have both ingresses simultaneously? (one enforcing SSL, the other not)
If so what am I doing wrong here?
Figured out I was missing this annotation:
nginx.ingress.kubernetes.io/rewrite-target: /$2
in SSL ingress...
works like a charm now, maybe someone will find this usefull

Ingress hostname wont change

I have an Ingress setup and initially I used a placeholder name, "thesis.info". Now I would like change this hostname but whenever I to change it I just end up getting 404 errors.
Change the spec.tls.rules.host value in the yaml to the new hostname
Change CN value which openssl uses for the crt and key that are generated for TLS
Edit the value /etc/hosts value on my local machine
Is there a step I am missing that could be causing a problem. I am baffled by why it works with one value but not the other.
Below is the ingress yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-ingress
namespace: thesis
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/add-base-url: "true"
nginx.ingress.kubernetes.io/service-upstream: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
tls:
- hosts:
- thesis
secretName: ingress-tls
rules:
- host: pod1out.ie
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 3000
---
Most likely, you can find a hint on what is going on in the nginx logs. If you have access, you can access the logs using something like this:
kubectl -n <ingress-namespace> get pods
# should be one or more nginx pods
kubectl -n <ingress-namespace> logs <nginx-pod>
Not sure if this is the only issue, but according to the documentation, the host in 'tls' has to match explicitly the host in the rules:
spec:
tls:
- hosts:
- pod1out.ie
secretName: ingress-tls
rules:
- host: pod1out.ie
Before struggling with tls, I would recommend making the http route itself work (eg. by creating another ingress resource), and if this works with the host you want, go for tls.

Website responding with "default backend - 404" on GKE - Kubernetes

On one of our domains https://www.secretwish.in - all the 404 traffic is going to the default GKE Ingress whereas it has to route to my application.
All other pages on my application are working fine, the problem is just with 404 page, all traffic is going on gke default ingress. Sample URL - https://www.secretwish.in/hshshs
Need to find a solution for this so that all traffic starts routing to my app
Cluster Version - 1.14.10-gke.27
The ingress file looks like:-
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ans-commerce-ingress
annotations:
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/tls-minimum-version: "1.0"
spec:
tls:
- hosts:
- www.secretwish.in
secretName: www-secretwish-in-tls
- host: www.secretwish.in
http:
paths:
- path: /
backend:
serviceName: ans-commerce
servicePort: 80
In GKE docs you can find information regarding GKE Ingress, that for specific path you should specify backend, otherwise you will received issue 404 default backend.
You can specify a default backend by providing a backend field in your
Ingress manifest. Any requests that don't match the paths in the rules
field are sent to the Service and port specified in the backend field.
... If you don't specify a default backend, GKE provides a default
backend that returns 404.
Default backend will redirect all request which could not be found
in any spec.rules.http.paths.path
For little test I've used 2 deployments and 2 services form this gke example.
Option 1 without configured default end
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- path: /world
backend:
serviceName: hello-world
servicePort: 60000
- path: /kube
backend:
serviceName: hello-kubernetes
servicePort: 80
user#cloudshell:~ (prjoect-name)$ curl 35.244.197.176
default backend - 404
user#cloudshell:~ (prjoect-name)$ curl 35.244.197.176/kube
Hello Kubernetes!
user#cloudshell:~ (prjoect-name)$ curl 35.244.197.176/world
Hello, world!
Version: 2.0.0
Hostname: hello-world-deployment-7f67f479f5-vqzxg
user#cloudshell:~ (prjoect-name)$ curl 35.244.197.176/yvgbhuij
default backend - 404
Option 2 With defailt backend
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend:
serviceName: hello-world
servicePort: 60000
rules:
- http:
paths:
- path: /world
backend:
serviceName: hello-world
servicePort: 60000
- path: /kube
backend:
serviceName: hello-kubernetes
servicePort: 80
user#cloudshell:~ (prjoect-name)$ curl 35.244.186.95
Hello, world!
Version: 2.0.0
Hostname: hello-world-deployment-7f67f479f5-vqzxg
user#cloudshell:~ (prjoect-name)$ curl 35.244.186.95/hello
Hello, world!
Version: 2.0.0
Hostname: hello-world-deployment-7f67f479f5-kd6fg
user#cloudshell:~ (prjoect-name)$ curl 35.244.186.95/kube
Hello Kubernetes!
user#cloudshell:~ (prjoect-name)$ curl 35.244.186.95/fyvgbhujnkl
Hello, world!
Version: 2.0.0
Hostname: hello-world-deployment-7f67f479f5-vqzxg
Please keep in mind that Ingress on GKE needs about 5-6 minutes before it starts working properly
Not sure our solution applies in you case. We also faced similar issue(not exact), we didn't want to change the deployed ingress(i.e. can't add server-alias) So we some how made sure that all host address typed in browser/request translates to what is configured in ingress.
In this example, we would have created entry in local /etc/hosts
<actual ingress IP> www.secretwish.in

How to make Traefik compatible with Microk8s

I have a working setup on Minikube with Traefik as ingress controller. I tried to use that setup on Microk8s but Traefik is not able to work and although I can see the Traefik dashboard and it says that everything is working but every time I try to use the ingress urls I face timeout but if I use the endpoint IP of that service (which I can see in the traefik dashboard) I am able to access to that service but not fully. I can have access to IP/service1 but I can't have access to any of its sub urls, IP/service1/sub-service1 not working.
I also tried microk8s.enable ingress but it created an nginx ingress for me and then I disabled it because I want to use traefik.
Do I need to change my configuration so it becomes compatible with Microk8s? If yes how?
I have to mention that I have two ingress files:
traefik-ui.yaml: which contains both the service and ingress for my traefik. I use this service+ingress to access the traefik dashboard and as I mentioned it works
wws-ingress.yaml: is my main ingress which enables the communication with my components inside kubernetes and this is the part that doesn't work.
My yaml files:
traefik-ui.yaml:
---
apiVersion: v1
kind: Service
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- name: web
port: 80
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
rules:
- host: traefik-ui.minikube
http:
paths:
- path: /
backend:
serviceName: traefik-web-ui
servicePort: web
wws-ingress.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: wws
annotations:
kubernetes.io/ingress.class: "traefik"
traefik.frontend.rule.type: PathPrefixStrip
traefik.frontend.passHostHeader: "true"
traefik.backend.loadbalancer.sticky: "true"
#traefik.ingress.kubernetes.io/rule-type: ReplacePathRegex
traefik.wss.protocol: http
traefik.wss.protocol: https
spec:
rules:
- host: streambridge.local
http:
paths:
- path: /streambridge
backend:
serviceName: streambridge
servicePort: 9999
- path: /dashboard
backend:
serviceName: dashboard
servicePort: 9009
- path: /gateway
backend:
serviceName: gateway
servicePort: 8080
- path: /rdb
backend:
serviceName: rethinkdb
servicePort: 8085
Minikube commands (this works without a problem):
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-ds.yaml
kubectl apply -f traefik-ui.yaml
kubectl apply -f wws-ingress.yaml
And in Microk8s I tried:
microk8s.kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-rbac.yaml
microk8s.kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-ds.yaml
microk8s.kubectl apply -f traefik-ui.yaml
microk8s.kubectl apply -f wws-ingress.yaml
After testing my setup on another machine and seeing that it is working there I found out that something is wrong with my machine and after spending a good amount of time on this with the help of two of my colleagues and trying everything we found out that the problem is related to iptable in my machine and we solved it as described here: https://github.com/ubuntu/microk8s/issues/72

Kubernetes Ingress - Rewrite path

I’m trying to redirect the incoming connections with an ingress of a cluster created in IBM Cloud.
I’m able to successfully set up the ingress and contact the pod.
However, when the connection reaches the endpoint
http://app1.myaddress.cloud/test1
is not rewrited to the right pod url ( The path still contains the /test1 and I want to remove that part).
Do you have any idea how to solve the issue?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- app1.myaddress.cloud
secretName: myclustername
rules:
- host: app1.myaddress.cloud
http:
paths:
- path: /test
backend:
serviceName: hello-world-service-1
servicePort: 30001
I found the official IBM Cloud tutorial here.
https://cloud.ibm.com/docs/containers?topic=containers-ingress_annotation