为了更清楚,我将从OSI model开始,它告诉我们TCP 是4级协议,HTTP/HTTPS是7级 协议。所以,坦率地说,HTTP/HTTP 数据是 encapsulated 到 TCP 数据,然后再进行休息级别封装以将数据包传输到另一个网络设备。
如果您设置Classic (TCP) LoadBalancer,它在读取TCP部分后停止读取数据包数据,这足以决定(根据LB配置)该数据包应该传送到哪个IP address和哪个IP port。之后,LB 获取 TCP 有效负载数据,并用另一个 TCP 层数据将其包裹起来,然后将其发送到目标点(这反过来会导致应用所有其他 OSI 层)。
要使您的配置按预期工作,需要使用NodePort service 公开nginx-ingress-controller Pod。然后可以将经典 ELB 配置为将流量传送到任何集群节点到为该 NodePort 服务选择的端口。通常它在30000 和32767 之间。 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 的以下流量分配顺序:
- 客户端将带有 HTTP/HTTPS 请求的 TCP 数据包发送到 ELB_IP:ELB_port (
a.b.c.d:80)。
- ELB 接收 IP 包,分析其 TCP 数据,从后端池(Kubernetes 集群节点的整个列表)中找到合适的端点,并在内部创建另一个具有相同 HTTP/HTTPS 数据的 TCP 包,并替换目标 IP 和目标TCP 端口到集群 node IP 和 Service NodePort TCP 端口 (
l.m.n.k:30xxx),然后将其发送到选定的目的地。
- Kubernetes 节点接收到 TCP 数据包并使用 iptables 规则再次更改 TCP 数据包的目标 IP 和目标端口,并将数据包(根据 Nodeport 服务配置)转发到目标 pod。在这种情况下,它将是 nginx-ingress-controller pod。
- Nginx-ingress-controller pod 接收到 TCP 数据包,因为根据 TCP 数据必须在本地下发,从其中提取 HTTP/HTTP 数据并将数据(HTTP/HTTPS 请求)发送到内部的 Nginx 进程Pod 中的 Nginx 容器,
- 容器中的 Nginx 进程接收 HTTP/HTTPS 请求,解密它(如果是 HTTPS)并分析所有 HTTP 标头。
- 根据
nginx.conf的设置,Nginx 处理更改 HTTP 请求并将其传递给集群服务,指定配置的主机和 URL 路径。
- Nginx 进程将更改后的 HTTP 请求发送到后端应用程序。
- 然后将TCP头添加到HTTP请求中,并将其发送到后端服务
IP_address:TCP_port。
- 为后端服务定义的 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 服务)的工作方式非常相似。