AWS 中 HTTPS 的 Kubernetes nginx ingress 基于路径的路由

Kubernetes nginx ingress path-based routing of HTTPS in AWS

问题:在 Kubernetes 中,当它被定义为 TCP 时,如何配置 nginx 入口以将来自弹性负载均衡器的流量视为 HTTPS?


我正在 AWS 环境中使用 Kubernetes 集群。我想使用 nginx 入口对 HTTPS 流量进行基于路径的路由;但是,我不想在 AWS 弹性负载均衡器上进行 SSL 终止或重新加密。

所需的设置是:

客户端 -> 弹性负载均衡器 -> nginx ingress -> pod

要求:
1.流量端到端加密
2.必须使用AWS ELB(流量不能从外界直接进入Kubernetes)。

我遇到的问题是要在 ELB 上进行 SSL 直通,我必须将 ELB 配置为 TCP 流量。但是,当ELB定义为TCP时,所有流量都会绕过nginx。

据我所知,我可以设置一个 TCP passthrough via a ConfigMap,但这只是另一个通道;它不允许我在 nginx 中进行基于路径的路由。

我正在寻找一种方法将 ELB 定义为 TCP(用于直通),同时仍然让入口将流量视为 HTTPS。

我可以将 ELB 定义为 HTTPS,但是过程中还有第二个不必要的 negotiate/break/reencrypt 步骤,我想尽可能避免。

为了更清楚,我将从 OSI model, which tells us that TCP is level 4 protocol and HTTP/HTTPS is level 7 protocol. So, frankly speaking HTTP/HTTP data is encapsulatedTCP 数据开始,然后再进行其余级别封装以将数据包传输到另一个网络设备。

如果你设置Classic (TCP) LoadBalancer它在读取TCP部分后停止读取数据包数据,这足以决定(根据LB配置)哪个IP address和哪个IP port这个应该传送数据包。之后,LB 获取 TCP 有效载荷数据并将其与另一个 TCP 层数据包裹起来并将其发送到目标点(这反过来会导致应用所有其他 OSI 层)。

为了使您的配置按预期工作,需要公开 nginx-ingress-controller Pod using NodePort service。然后,可以将经典 ELB 配置为将流量传送到任何集群节点到为该 NodePort 服务选择的端口。通常它在 3000032767 之间。所以您的 LB 池将如下所示:

假设集群节点的 IP 地址为 10.132.10.1...10,NodePort 端口为 30276

ELB Endpoint 1:  10.132.10.1:30276
ELB Endpoint 2:  10.132.10.2:30276
...
ELB Endpoint 10: 10.132.10.10:30276

注意:在 AWS ELB 的情况下,我猜,应该使用节点 DNS 名称而不是 IP 地址。

因此它应该导致从客户端到 Kubernetes 应用程序 Pod 的流量分配顺序如下:

  1. 客户端发送带有HTTP/HTTPS请求的TCP数据包到ELB_IP:ELB_port (a.b.c.d:80).
  2. ELB 接收 IP 数据包,分析其 TCP 数据,从后端池(整个 Kubernetes 集群节点列表)中找到合适的端点,并创建另一个包含相同 HTTP/HTTPS 数据的 TCP 数据包,并替换目标IP和目标TCP端口到集群节点IPService NodePort TCP端口(l.m.n.k:30xxx)然后发送到选择的目标.
  3. Kubernetes 节点收到TCP 数据包,使用iptables 规则再次更改TCP 数据包的目的IP 和目的端口,并将数据包(根据Nodeport 服务配置)转发到目的pod。在这种情况下,它将是 nginx-ingress-controller pod。
  4. Nginx-ingress-controller pod收到TCP数据包,因为根据TCP数据它必须在本地传递,从中提取HTTP/HTTP数据并发送数据(HTTP/HTTPS请求) 到 Pod 中 Nginx 容器内的 Nginx 进程,
  5. 容器中的 Nginx 进程接收 HTTP/HTTPS 请求,对其进行解密(在 HTTPS 的情况下)并分析所有 HTTP header。
  6. 根据nginx.conf设置,Nginx处理改变HTTP请求并将其传递给集群服务,指定为配置的主机和URL路径。
  7. Nginx 进程将更改后的 HTTP 请求发送到后端应用程序。
  8. 然后在HTTP请求中加入TCPheader发送给后端服务IP_address:TCP_port.
  9. 为后端服务定义的 iptables 规则,将数据包传送到服务端点之一(应用程序 Pods)。

注意:要在入口控制器上终止 SSL,您必须在 SAN 部分创建包含 ELB IP 和 ELB FQDN 的 SSL 证书。

注意:如果您想在应用程序Pod 上终止SSL 以进行端到端SSL 加密,您可能需要配置nginx 以绕过SSL 流量。

底线:配置为向 Kubernetes 集群传送 TCP 流量的 ELB 如果您以正确的方式配置它,可以与 nginx-ingress 控制器完美配合。

在 GKE(Google Kubernetes Engine)中,如果您使用 type:LoadBalancer 创建一个服务,它会准确地为您创建 TCP LB,它将流量转发到服务节点端口,然后 Kubernetes 负责将其传送到荚。 AWS 的 EKS(弹性 Kubernetes 服务)的工作方式非常相似。