I want to test my (Helm packaged) Kubernetes application locally using minikube, with a Kubernetes ingress to proxy HTTP to the HTTP services my application provides. But this is not working because the ingress (or ingress controller) is insisting that connections are HTTPS, despite me not requesting TLS. How do I ensure the ingress allows HTTP?
kubectl get --output=yaml ingress
shows that there is an ingress resource, for HTTP, without TLS:
apiVersion: v1
items:
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
creationTimestamp: "2019-10-06T10:54:38Z"
generation: 1
labels:
app.kubernetes.io/instance: quarreling-shrimp
app.kubernetes.io/managed-by: Tiller
app.kubernetes.io/name: mc
app.kubernetes.io/version: 2.3.1-SNAPSHOT
helm.sh/chart: mc-2.3.1
name: quarreling-shrimp-mc
namespace: default
resourceVersion: "126597"
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/quarreling-shrimp-mc
uid: 296f8d69-8f40-49c5-b352-acbc6ec1cc19
spec:
rules:
- http:
paths:
- backend:
serviceName: quarreling-shrimp-mc-be-svc
servicePort: 8080
path: /api
- backend:
serviceName: quarreling-shrimp-mc-fe
servicePort: 80
path: /
status:
loadBalancer:
ingress:
- ip: 192.168.122.66
kind: List
metadata:
resourceVersion: ""
selfLink: ""
But when I try to access the application using HTTP, the response tries to redirect to use HTTPS. This is the output of curl -i 192.168.122.66
:
HTTP/1.1 308 Permanent Redirect
Server: openresty/1.15.8.1
Date: Sun, 06 Oct 2019 11:22:40 GMT
Content-Type: text/html
Content-Length: 177
Connection: keep-alive
Location: https://192.168.122.66/
<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>openresty/1.15.8.1</center>
</body>
</html>
minikube uses an Nginx Ingress controller. That controller does a permanent redirect (HTTP status code 308) from initial HTTP to HTTPS:
By default the controller redirects (308) to HTTPS if TLS is enabled for that ingress
But, as you point out, the documentation suggests it should not do a redirect in your case because you have not enabled TLS.
I've observed that once I add host:
field to the particular Ingress resource without TLS enabled, the resulting curl
command returns HTTP/1.1 200
with no redirect action:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: some-svc
servicePort: 80
path: /
$ curl -v http://$(kubectl get svc -l component=controller -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}') -H 'Host: example.com'
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200
But an HTTP GET without a matching host causes a redirect:
$ curl -v http://$(kubectl get svc -l component=controller -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
> GET / HTTP/1.1
> Host: XX.XX.XX.XX
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 308 Permanent Redirect
Therefore, I suppose that although the host:
field is optional, if you don't specify it in the target Ingress
resource, the Ingress controller will not properly recognize TLS related settings.