Following the example at https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/README.md my ingress.yaml looks like:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-app
annotations:
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
- secretName: my-app
rules:
- host: t.my-app.com
http:
paths:
- backend:
serviceName: my-app
servicePort: 80
I expect it to block all http traffic, but unfortunately this is not happening! I am still getting 443 and 80 both! I have spent hours on hours trying to get if there is anything wrong with the annotation, but I simply cannot find any way to deduce that!
Related
I am playing a little bit with path-based routing via Kubernetes ingresses (we use Nginx ingress). We have one service up and running behind authentication via external service like the one in the first snippet. This service is already used by other services in our ecosystem, however, as the development progresses, the service now has management API and we need to turn off the authentication for specific paths. According to this answer, this is not possible for basic auth and, according to what I have tried (second snippet), it is not possible for authentication via external service either. Is there any other way to allow specific paths without authentication without completely rearchitecting ingresses and domains/paths?
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: path-based-routing-1
annotations:
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: nginx-external
nginx.ingress.kubernetes.io/auth-url: http://authorizer.dev.svc.cluster.local
spec:
tls:
- hosts:
- 'routing.example.com'
secretName: routing.example.com
rules:
- host: 'routing.example.com'
http:
paths:
- path: /
backend:
serviceName: path-based-routing-1
servicePort: 80
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: path-based-routing-2
annotations:
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/auth-type: ""
kubernetes.io/ingress.class: nginx-external
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- 'routing.example.com'
secretName: routing.example.com
rules:
- host: 'routing.example.com'
http:
paths:
- path: /management-api
backend:
serviceName: path-based-routing-2
servicePort: 80
I have setup traefik 2.2 in my self managed kubernetes cluster with Let's Encrypt support.
So far everything works. But the ingress Route configuration in my eyes is still clumsy. It only works if I define two IntgresRoutes - one for HTTP with a redirect middleware to https and one for the https. So my objects look like this:
# Middleware for Redirect http -> https
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: https-redirect
spec:
redirectScheme:
scheme: https
# IngressRoute http for a simple whoami service
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
name: whoami-notls
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`mydomain.foo.com`)
kind: Rule
services:
- name: whoami
port: 8080
# redirect http to https
middlewares:
- name: https-redirect
# IngresRoute https
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
name: whoami-tls
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`mydomain.foo.com`)
kind: Rule
services:
- name: whoami
port: 8080
tls:
certResolver: default
Is there not a more easy way to simply tell traefik that my service - which is listening on port 8080 - should be redirected to HTTPS in any case. Why do I need two separate ingresRoutes in my setup?
In the announcements for traefik 2.2. there was something like this:
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: foo
namespace: bar
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web, websecure
traefik.ingress.kubernetes.io/router.middlewares: redirect-http#kuberntes-crd
spec:
rules:
- host: foo.com
http:
paths:
- path: ""
backend:
serviceName: service1
servicePort: 80
It looks very simple. But this did not work for me - traefik is not recognizing this Ingress configuration.
With the help of the Traefik.io team in this discussion, I now solved the problem:
To use traefik annotations in Ingress make sure that in your deployment object you have added the ‘kubernetesingress’ provider:
...
spec:
containers:
- args:
- --api
....
- --providers.kubernetescrd=true
- --providers.kubernetesingress=true
....
For a global redirect form HTTP to HTTPS you can also configure this in your traefik deplyoment object:
# permanent redirecting of all requests on http (80) to https (443)
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.websecure.http.tls.certResolver=default
Now you can configure your ingress in an easy way:
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: myingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web, websecure
spec:
rules:
- host: example.foo.com
http:
paths:
- path: /
backend:
serviceName: whoami
servicePort: 80
See also my latest Blog post.
I have a Spring Boot application responsible for getting citizens and a NGINX Ingress controller configured with ssl-passthrough to expose my cluster to outside.
When I do:
https://myhostname.com/citizens
It perfectly works. This is the configuration I am using:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: myhostname.com
http:
paths:
- path: /
backend:
serviceName: myservice
servicePort: 443
But I would like to have something like:
https://myhostname.com/myservice/citizens
It would be something similar to math Simple fanout approach that is described in the kubernetes docs:
https://kubernetes.io/docs/concepts/services-networking/ingress/#simple-fanout
Therefore, in my Spring application I have configured a contextPath so when locally I do:
https://localhost:8080/myservice/citizens
I get the desired result
For NGINX I have set up the following:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myhostname.com
http:
paths:
- path: /myservice
backend:
serviceName: myservice
servicePort: 443
What am I doing wrong?
Solution:
I've been researching a little and I've realized that the approach that I was trying to achieve is not possible with ssl-passthrough as the proxy is blind and it doesn't know the path to where route the traffic.
Therefore, the solution would be to use subdomains and not paths, because thanks to the SNI protocol, the NGINX controller will know to which hostname the client is trying to connect.
The final solution would be something similar to this
If your backend is expecting the whole path /myservice/citizens you can just use it to point it to the service without the rewrite-target directive, since it only dictates how URIs are going to be treated in the backend:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: myhostname.com
http:
paths:
- path: /myservice/citizens
backend:
serviceName: myservice
servicePort: 443
Be aware that this assumes that your service is able to redirect requests to 8080, which is your backend listening port, so it has to match it.
I have a setup that is not too much different than the user guide for use with k8s. For some reason I can only access http://app.minikube and not https://app.minikube.
Can someone look at my setup and see what I am obviously missing?
apiVersion: v1
kind: Service
metadata:
name: myapp
labels:
app: myapp
spec:
ports:
- name: http
port: 80
targetPort: 7777
selector:
app: myapp
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myingress
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: app.minikube
http:
paths:
- path: /
backend:
serviceName: myapp
servicePort: http
tls:
- secretName: mytls
FYI, according to the Traefik user guide, the hosts definition in tls is unneeded, which is why I left it out.
The field hosts in the TLS configuration is ignored. Instead, the domains provided by the certificate are used for this purpose. It is recommended to not use wildcard certificates as they will match globally)
You're missing the hosts section:
tls:
- hosts:
- my-host.example.com
secretName: my-secret
I have configured an ingress on a kubernetes cluster from Google Cloud. I followed the instructions as is on this doc.
My manifest:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-proxy
annotations:
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- foo.bar.com
secretName: foo-bar-secret
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: foo-bar-service
servicePort: 80
path: /*
From the documentation, it specifies that ssl-redirect
is by default true if tls is configured but it doesn't work. I've also tried to set force-ssl-redirect to true(default is false), still no luck.
I'm confused if there is actually a bug or I'm doing something wrong, because when I run kubectl describe ing web-proxy, it displays that annotations were set:
Annotations:
force-ssl-redirect: true
[...]
Any suggestions?
EDIT 1:
I was using the 1.8.3.gke.0 version but when I upgraded to 1.8.4.gke.0 this seems to have solved the problem.
I'll keep this post updated while I test more annotations(like: nginx.ingress.kubernetes.io/from-to-www-redirect)