【问题标题】:Kubernetes nginx ingress path-based routing of HTTPS in AWSAWS中基于Kubernetes nginx入口路径的HTTPS路由
【发布时间】:2020-02-27 00:15:01
【问题描述】:

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


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

所需的设置是:

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

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

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

    要使您的配置按预期工作,需要使用NodePort service 公开nginx-ingress-controller Pod。然后可以将经典 ELB 配置为将流量传送到任何集群节点到为该 NodePort 服务选择的端口。通常它在3000032767 之间。 Sou 你的 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 端口到集群 node 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 请求)发送到内部的 Nginx 进程Pod 中的 Nginx 容器,
    5. 容器中的 Nginx 进程接收 HTTP/HTTPS 请求,解密它(如果是 HTTPS)并分析所有 HTTP 标头。
    6. 根据nginx.conf的设置,Nginx 处理更改 HTTP 请求并将其传递给集群服务,指定配置的主机和 URL 路径。
    7. Nginx 进程将更改后的 HTTP 请求发送到后端应用程序。
    8. 然后将TCP头添加到HTTP请求中,并将其发送到后端服务IP_address:TCP_port
    9. 为后端服务定义的 iptables 规则,将数据包传送到服务端点之一(应用程序 Pod)。

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-14
      • 2021-12-27
      • 2020-06-26
      • 2021-12-14
      • 2019-06-22
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      相关资源
      最近更新 更多