如何在GKE上强制使用SSL的Kubernetes Ingress

65

有没有办法在入站连接上使用负载均衡器强制进行SSL升级?或者如果这不可能,我可以禁用端口:80吗?我还没有找到一个好的文档页面来概述YAML文件中这样的选项。非常感谢!


"SSL 升级传入连接" 是什么意思?你能详细说明一下吗?另外,你能详细说明一下你正在尝试做什么吗? - Madhusudan.C.S
1
我想将连接重定向到HTTP端口80,最好是在Kubernetes Ingress负载均衡器上重定向到HTTPS端口443。如果不行,那么最好的策略是什么?同时负载平衡80和443,并在LB后面放置一个haproxy来进行转发? - Simon Heinzle
10个回答

63

https://github.com/kubernetes/ingress-gce#frontend-https

您可以通过注释kubernetes.io/ingress.allow-http: "false"阻止HTTP,或通过指定自定义后端将HTTP重定向到HTTPS。不幸的是,GCE目前尚不能直接为您处理L7层的重定向或重写。(请参见https://github.com/kubernetes/ingress-gce#ingress-cannot-redirect-http-to-https)

更新:现在GCP已经处理负载均衡器的重定向规则,包括HTTP到HTTPS。目前似乎没有一种方法可以通过Kubernetes YAML创建这些规则。


1
这是为什么在我的nginx HTTP服务器块中返回301到HTTPS会导致301循环的原因吗? - Bcf Ant
1
是否有任何可用的资源可以详细说明如何使用自定义后端执行重定向?或者您能否在那部分扩展您的答案?我的应用程序不运行在Apache/nginx上,因此添加这样的服务意味着拼图中的另一个部分,我无法弄清楚如何正确路由事物。 - zagrimsan
1
我能够为自己的需求找到解决方案(并且找出如何插入额外的Pod),将其发布在https://dev59.com/2Krka4cB1Zd3GeqPcl_E#49750913。 - zagrimsan
1
通过这篇文章 https://www.digitalocean.com/community/questions/best-way-to-configure-nginx-ssl-force-http-to-redirect-to-https-force-www-to-non-www-on-serverpilot-free-plan-by-using-nginx-configuration-file-only 我了解到如何使用nginx将HTTP重定向到HTTPs。但是nginx conf要求提供ssl证书文件的位置。在我的情况下,我正在使用GCP托管的证书。我不知道nginx conf文件与GCP托管证书有什么关系。 - Savaratkar
4
现在有一种通过FrontendConfig在k8s yaml中支持重定向的方法:https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#https_redirect - Andrej Palicka
显示剩余4条评论

31

这个问题已经在被接受的答案的评论中正确回答了。但由于评论被埋没了,我错过了几次。

从GKE版本1.18.10-gke.600开始,您可以添加一个k8s前端配置以将http重定向到https。

https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#https_redirect

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: ssl-redirect
spec:
  redirectToHttps:
    enabled: true

# add below to ingress
# metadata:
#   annotations:
#     networking.gke.io/v1beta1.FrontendConfig: ssl-redirect

这太完美了! - Luv33preet
这应该是被接受的答案,因为其他答案只是简单地禁用了HTTP而没有任何重定向。 - TeChn4K
2
一开始,ssl-redirect 对我来说无法工作,因为我已经在我的 Ingress 中有了这个配置 kubernetes.io/ingress.allow-http: "false"。请记得删除 ingress.allow-http 配置,否则 ssl-redirect 将无法正常工作。 - Frank Escobar
在我的GKE UI中,我没有看到任何FrontendConfig文件的位置,如何打开此文件? - Piyush Dolar
真的是正确的答案!谢谢George ;) - elliot

15

最近进行了检查,注释保持不变,但最新版本现在是{apiVersion: networking.k8s.io/v1beta1}。 - CarlosJ

14
如果您没有绑定到GCLB Ingress Controller,您可以看看Nginx Ingress Controller。这个控制器在多个方面与内置控制器不同。首先,您需要自己部署和管理它。但是,如果您愿意这样做,您将获得不依赖于GCE LB(20美元/月)并获得IPv6 / websockets支持的好处。 文档指出:
默认情况下,如果针对该入口启用了TLS,则控制器会重定向(301)到HTTPS。如果您想全局禁用该行为,则可以在NGINX配置映射中使用ssl-redirect:“false”
最近发布的0.9.0-beta.3带有一个额外的注释,可以明确强制执行此重定向:
使用注释ingress.kubernetes.io/force-ssl-redirect强制重定向到SSL。

对于nginx ingress控制器,我尝试了nginx.ingress.kubernetes.io/force-ssl-redirect: "true"并且它有效。有关注释的完整列表,请访问https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/annotations.md - Balkrishna
仍然觉得这里是最好的答案。 - Randy L
1
更新的注释文档链接:https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md - Archonic
1
GCE负载均衡器支持WebSockets,至少从2018年5月开始支持 - 您能调整这个答案吗? - Cameron

9
谷歌已回应我们的请求,并正在其负载平衡器上测试HTTP-> HTTPS SSL重定向。他们最新的回答说,在2020年1月底之前,这项功能应该会进入 Alpha 版本。
他们的评论如下:
“感谢您对此问题的耐心等待。该功能目前正在测试中,我们预计将在1月底之前进入Alpha阶段。随着我们接近Alpha发布,我们的PM团队将有更多详细信息的公告。”
我希望我们在不久的将来会有一个简单明了的解决方案来解决这个非常常见的特性。
更新(2020年4月):
HTTP(S) rewrite现在是一个普遍可用的功能。但它还有一些缺陷,并且不幸的是,它不能与GCE Ingress Controller 进行开箱即用的工作。但时间会证明,希望会出现原生解决方案。

3
直译为“字面上,5年后”。 - Michal
1
没关系:“不幸的是,那会将我们的Alpha发布日期推迟数周。” - Michal
2
@Michal 终于发布了:https://issuetracker.google.com/issues/35904733#comment95 然而,我相信在 Kubernetes YAML 中设置自动配置的时间会更长... - Cyral
感谢@Cyral,我会更新Josh的回答。如果不满意,请随意回滚。 - Michal
现在GCE Ingress Controller中是否可用? - Guru
现在可以使用了。在此页面上搜索“重定向”。 - Josh

8

简要更新。 这里

现在可以创建一个FrontEndConfig来配置Ingress。希望能够帮助。

示例:

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: 301

您需要确保您的负载均衡器支持HTTP和HTTPS协议。


首先,感谢您的回复。请考虑直接在您的答案中包含解决方案。如果本文的URL发生变化,您的答案将变得无用。 - alexzimmer96
谢谢,但您没有包含用于使用此前端的入口配置。 - TeChn4K
1
@TeChn4K 请查看 https://www.doit-intl.com/say-goodbye-to-improvised-https-redirection-workarounds/ 了解如何将 FrontendConfig 与 Ingress 关联。 - Yoni Rabinovitch

4

我已经长时间研究这个问题。如果有人不清楚上面的帖子,请按注释重新构建您的入口 -- kubernetes.io/ingress.allow-http: "false" -- 然后删除您的入口并重新部署。注释将使入口只为443创建负载均衡器,而不是同时为443和80创建。

然后您需要进行计算HTTP LB,而不是GKE的LB。

GUI方向: 创建一个负载平衡器并选择HTTP(S)负载平衡 - 开始配置。

选择 - 从Internet到我的VMs并继续

为LB选择一个名称

保留后端配置为空。

在主机和路径规则下,选择高级主机和路径规则,并将操作设置为重定向客户端到不同的主机/路径。 将主机重定向字段保留为空。 选择前缀重定向并将路径值保留为空。 选择308作为重定向响应代码。 勾选启用HTTPS重定向框。

对于前端配置,请将http和端口80保留,对于ip地址选择用于您的GKE入口的静态IP地址。

创建此LB。

现在您将所有http流量都发送到这里,并且308重定向到您的GKE https入口。非常简单的配置设置,并且运作良好。

注意:如果您只尝试删除GKE生成的80端口LB(而不执行注释更改和重建入口),然后添加新的重定向计算LB,它确实可以工作,但是您将开始看到关于Ingress的错误消息,显示字段'resource.ipAddress""的值无效,已在使用中,并将导致冲突,无效。它正在尝试启动80端口的LB,但无法启动,因为您已经有一个在使用相同IP的80端口的LB。它确实可以工作,但错误很烦人,而且GKE一直在尝试构建它(我想)。


谢谢!这正是我们需要做的。 - Will Brode
我认为这对应于官方谷歌文档中的“创建HTTP LB2”步骤:https://cloud.google.com/load-balancing/docs/https/setting-up-http-https-redirect - George

2
感谢@Andrej Palicka的评论,根据他提供的页面:https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#https_redirect现在我有了一个更新的且可行的解决方案。
首先,我们需要定义一个FrontendConfig资源,然后告诉Ingress资源使用这个FrontendConfig。
示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-app-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: myapp-prd
    networking.gke.io/managed-certificates: managed-cert
    kubernetes.io/ingress.class: "gce"
    networking.gke.io/v1beta1.FrontendConfig: myapp-frontend-config
spec:
  defaultBackend:
    service:
      name: myapp-app-service
      port:
        number: 80
---
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: myapp-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: MOVED_PERMANENTLY_DEFAULT

1
你可以在你的集群上禁用HTTP(请注意,你需要重新创建集群才能将此更改应用于负载均衡器),然后通过在同一IP地址上创建额外的负载均衡器设置HTTP到HTTPS的重定向。我也花了几个小时来解决同样的问题,最终采取了上述方法,它完美地工作了。

0

在Kubernetes中进行HTTPS重定向有点复杂。根据我的经验,你可能会想使用一个类似于Ambassador或者ingress-nginx的入口控制器来控制对你的服务的路由,而不是让负载均衡器直接路由到你的服务。

假设你正在使用一个入口控制器,那么:

  • 如果你在外部负载均衡器上终止TLS并且该负载均衡器运行在L7模式(即HTTP/HTTPS),那么你的入口控制器需要使用X-Forwarded-Proto,并相应地发出重定向。
  • 如果你在外部负载均衡器上终止TLS并且该负载均衡器运行在TCP/L4模式,那么你的入口控制器需要使用PROXY协议来进行重定向。
  • 你也可以直接在入口控制器中终止TLS,这样它就拥有完成重定向所需的所有信息。

这里有一个关于如何在Ambassador中进行此操作的教程


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接