1

我追求一个非常简单的要求——但在外部负载均衡器后面时,似乎不可能让 Traefik 将流量从 HTTP 重定向到 HTTPS。

这是我的 GCE 入口

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: platform
  name: public-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "kubernetes-cluster-dev-ip"
    kubernetes.io/ingress.class: "gce"
    ingress.gcp.kubernetes.io/pre-shared-cert: "application-dev-ssl,application-dev-graphql-ssl"
spec:
  backend:
    serviceName: traefik-ingress-service
    servicePort: 80

它接收来自 HTTP(S) 的流量,然后转发到 Traefik 到端口 80。

我最初尝试使用 Traefik 重定向与此配置匹配模式的方式:

[entryPoints]
  [entryPoints.http]
    address = ":80"
    compress = true
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
    address = ":443"
    compress = true
    [entryPoints.https.tls] 

但显然会进入无限重定向循环,因为负载均衡器总是将流量代理到 Traefik 端口 80。

完成这项工作的简单解决方案正是 GCE 建议的 https://github.com/kubernetes/ingress-gce#ingress-cannot-redirect-http-to-https

能够检查http_x_forwarded_proto标题并基于此重定向。

Nginx 等效

# Replace '_' with your hostname.
server_name _;
if ($http_x_forwarded_proto = "http") {
    return 301 https://$host$request_uri;
}

有人可以建议用 Traefik 处理这个问题的最佳方法是什么,拜托!

4

1 回答 1

2

回顾一下,您有一个 GCE L7(第 7 层)负载均衡器代理 Traefik 中的另一个 L7 负载均衡器,您可以使用它来代理另一个后端服务。所以看起来你有这样的东西:

GCE L7 LB HTTP 80
=> Forwarded to Traefik HTTP 80
=> Redirect initial request to HTTPS 443 
=> The client thinks it needs to talk to GCE L7 LB HTTPS 443
=> GCE L7 LB HTTP 443
=> Forwarded to Traefik HTTP 80
=> Infinite loop

你需要有这样的东西:

GCE L7 LB HTTP 80
=> Forwarded to Traefik HTTP 80
=> Redirect initial request to HTTPS 443 
=> The client thinks it needs to talk to GCE L7 LB HTTPS 443
=> GCE L7 LB HTTP 443
=> Forwarded to Traefik HTTP 443

如果 Traefik 基于http_x_forwarded_protobeing的值重定向到 HTTPS,任何地方都没有记录http,但这是一般假设。在任何情况下,Ingress都对 HTTPS 后端一无所知(您没有指定如何配置 HTTPS GCE LB 端点)。

您可以看到这里记录了如何使 GCE LB 直接创建一个直接转发到您的 HTTPS 后端的 HTTPS 端点。基本上,您可以尝试将service.alpha.kubernetes.io/app-protocols注解添加到 HTTPS Traefik 服务:

apiVersion: v1
kind: Service
metadata:
  name: traefik-https
  annotations:
      service.alpha.kubernetes.io/app-protocols: '{"my-https-port":"HTTPS"}'
  labels:
    app: echo
spec:
  type: NodePort
  ports:
  - port: 443
    protocol: TCP
    name: my-https-port
  selector:
    app: traefik

所以你会有这样的事情:

GCE L7 LB HTTP 80
=> Forwarded to Traefik HTTP 80
=> Redirect initial request to HTTPS 443 
=> The client thinks it needs to talk to GCE L7 LB HTTPS 443
=> GCE L7 LB HTTP 443
=> Forwarded to Traefik HTTPS service
=> Service forward to Traefik port 443

希望这可以帮助。

于 2018-11-02T08:48:35.737 回答