Kubernetes nginx在AWS中基于HTTPS的入口路径路由

时间:2019-10-31 15:30:17

标签: amazon-web-services nginx kubernetes amazon-elb

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


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

所需的设置是:

客户端->弹性负载平衡器-> nginx入口->吊舱

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

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

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

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

我可以将ELB定义为HTTPS,但是在过程中还有第二个不必要的协商/中断/重新加密步骤,如果可能的话,我要避免该步骤。

1 个答案:

答案 0 :(得分:1)

为了更清楚一点,我将从OSI model开始,它告诉我们 TCP 是4级协议,而 HTTP / HTTPS是7级协议。因此,坦白地说,HTTP/HTTP数据是encapsulatedTCP数据,然后再进行其余级别的封装以将数据包传输到另一个网络设备。

如果您设置Classic (TCP) LoadBalancer,它将在读取TCP部分后停止读取数据包数据,这足以决定(根据LB配置)此数据包指向哪个IP address和哪个IP port应该交付。之后,LB获取TCP有效负载数据,并将其与另一个TCP层数据包装在一起,并将其发送到目标点(这又导致应用了所有其他OSI层)。

要使您的配置按预期工作,必须使用nginx-ingress-controller公开NodePort service Pod。然后,可以将经典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和目标群集节点IP 服务NodePort TCP 端口(l.m.n.k:30xxx)的TCP端口,然后将其发送到选定的目的地。
  3. Kubernetes节点接收TCP数据包,并使用iptables规则再次更改TCP数据包的目标IP和目标端口,并将数据包(根据Nodeport Service配置)转发到目标Pod。在这种情况下,它将是nginx-ingress-controller pod。
  4. Nginx-ingress-controller pod接收TCP数据包,并且由于必须根据TCP数据将其本地传输,因此从其中提取HTTP / HTTP数据并将数据(HTTP / HTTPS请求)发送到Nginx进程内部。 Pod中的Nginx容器,
  5. 容器中的
  6. Nginx进程接收HTTP / HTTPS请求,对其进行解密(如果使用HTTPS)并分析所有HTTP标头。
  7. 根据nginx.conf设置,Nginx进程更改HTTP请求并将其发送到为已配置的主机和URL路径指定的集群服务。
  8. Nginx进程将已更改的HTTP请求发送到后端应用程序。
  9. 然后将TCP标头添加到HTTP请求中,并将其发送到后端服务IP_address:TCP_port
  10. 为后端服务定义的
  11. iptables规则将数据包传递到服务端点之一(应用程序Pod)。

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

注意:如果要在应用程序Pod上终止SSL以具有端到端SSL加密,则可能需要将nginx配置为绕过SSL流量。

底线:配置为向Kubernetes集群传输TCP流量的ELB如果采用正确的配置,则可与nginx-ingress控制器完美配合。

在GKE(Google Kubernetes引擎)中,如果您创建类型为:LoadBalancer的服务,它将创建您完全将流量转发到服务NodePort的TCP LB,然后Kubernetes负责将其传递到Pod。 AWS的EKS(Elastic Kubernetes服务)的工作方式非常相似。