traefik实现nginx proxy_redirect效果
问题背景
traefik
本身使用了正常的80
和443
端口。
然后分别在web
和websecure
的entrypoint
上创建了route
。
然后为www-outer
(在web entrypoint
上)配置了重定向至https
的middleware
。
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
annotations:
kubernetes.io/ingress.class: ingress-traefik
generation: 1
labels:
app.kubernetes.io/instance: www
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: www
app.kubernetes.io/version: 1.0.0
name: www-outer
namespace: hf
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`www.hftest.com`)
middlewares:
- name: redirect-to-https
services:
- kind: Service
name: www
namespace: hf
passHostHeader: true
port: 8000
responseForwarding:
flushInterval: 1ms
scheme: http
strategy: RoundRobin
weight: 100
middleware
文件
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: redirect-to-https
namespace: hf
spec:
redirectScheme:
permanent: true
scheme: https
此时访问traefik
正常。
但是在与其他公司联调时,由于外网无法使用标准的80
和443
端口,因此改用了8080
和8443
端口。
也就是说外网ip
的8080
映射到traefik
的80
, 8443
映射到443
。
这时外网访问就出问题了,现象就是浏览器中打不开。
问题排查
用curl
调试如下:
# curl -i http://www.hftest.com:8080
HTTP/1.1 301 Moved Permanently
Location: https://www.hftest.com/
Date: Fri, 16 Sep 2022 09:39:38 GMT
Content-Length: 17
Content-Type: text/plain; charset=utf-8
Moved Permanently
可以看到,traefik
返回了不带端口的https
链接,而这个在外网的确是访问不到的。
nginx proxy_redirect选项
nginx
有proxy_redirect
参数可以解决这个问题。
但是现在使用的是traefik
的ingress
控制器,没用ingress-nginx
。
traefik
是否有类似的选项呢?
RedirectScheme
中的port
选项
RedirectScheme
的middleware
是有一个port
选项的,可以定义重定向后的端口。
这个我没有试,猜想,应该是可以在重定向之后带上自己设置的端口,比如8443
。
但是,在内网的就没法用了。当然也可以为traefik
加上8080
和8443
的entrypoint
来支持这种情况。
还是感觉不太优雅。
问题解决
使用RedirectRegex
的middleware
这个middleware
可以支持正则来进行重定向操作,相对RedirectScheme
仅能重定向scheme
,相对作用更广泛。
使用两个RedirectRegex
的middleware
即可解决上面的问题。
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: redirect-8080-to-8443
spec:
redirectRegex:
regex: ^http://www.hftest.com:8080/(.*)
replacement: https://www.hftest.com:8443/${1}
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: redirect-http-to-https-by-regex
spec:
redirectRegex:
regex: ^http://www.hftest.com/(.*)
replacement: https://www.hftest.com/${1}
如果觉得在ingressroute
中写两个middleware
麻烦,还可以使用chain
将这两个整合到一起,然后写一个即可。
这样就可以解决从外网访问时,因外网使用了与traefik
不同端口带来的重定向问题了。