使HTTPS与Traefik和GCE Ingress一起使用

时间:2018-11-02 02:32:15

标签: https kubernetes google-kubernetes-engine traefik traefik-ingress

我的要求很简单-在外部负载均衡器后面时,似乎不可能使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处理此问题的最佳方法是什么!

1 个答案:

答案 0 :(得分: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_proto的值为http重定向到HTTPS,则在任何地方都没有记录,但这只是一般的假设。无论如何,Ingress对HTTPS后端一无所知(您未指定如何配置HTTPS GCE LB端点)。

您可以看到here中已说明如何使GCE LB直接创建直接转发到您的HTTPS后端的HTTPS端点。基本上,您可以尝试向HTTPS Traefik服务添加service.alpha.kubernetes.io/app-protocols批注:

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

希望这会有所帮助。