Skip to content

假设场景:

  • 用户通过 www.example.com/myapp/dosomething 访问应用服务。
  • K8s 集群部署在云厂商(如 AWS, GCP, Azure)IDC。
  • 使用 Ingress Controller (如 Nginx Ingress) 进行 L7 路由。
  • 应用服务以 Deployment Workload 形式部署,并通过一个 ClusterIP 类型的 Service 暴露。

以下是一张描述外部流量请求该应用服务的流量走向图,以及流经的各个网络组件作用说明。

请修复一下有语法错误的mermaid图,请确保不要更改原图的内容部分,只修改语法格式上的错误。

流量走向及各组件作用说明:

  1. 用户浏览器/客户端:

    • 作用: 发起对 www.example.com/myapp/dosomething 的 HTTP(S)请求,这是流量的起点。
  2. DNS 服务器:

    • 作用: 接收来自客户端的域名解析请求,将域名 www.example.com 解析为其配置的 A 记录或 CNAME 记录对应的 IP 地址。这个 IP 地址通常是外部负载均衡器 (ELB) 的公网 IP。
  3. 互联网:

    • 作用: 公共网络,负责将用户的请求从客户端路由到目标 IP 地址(即 ELB 的 公网IP)。
  4. 防火墙/WAF:

    • 作用:
      • 防火墙: 网络安全的第一道防线,根据预设规则允许或拒绝流量,通常在 IDC 网络边缘进行 IP、端口级别的访问控制。
      • WAF (可选): 应用层防火墙,检测和阻止常见的 Web 攻击,如 SQL 注入、XSS 等。通常部署在 ELB 之前或集成在 ELB 中。
  5. 外部负载均衡器 (ELB):

    • 作用:
      • 接收公网流量: 拥有公网 IP,是外部流量进入 K8s 集群的主要入口。
      • SSL/TLS 终止 (可选): 可以在这里卸载 SSL/TLS 加密,将解密后的 HTTP 流量转发给后端,减轻 K8s 内部服务的压力。
      • 流量分发: 将接收到的外部流量根据其配置的规则(如轮询、最少连接等)分发到 K8s 集群的一个或多个 Worker Node 上的特定端口(通常是 Ingress Controller Service 暴露的 NodePort,或者直接到 Ingress Controller Pod 的 IP,如果 LB 与 K8s 集成度高)。
      • 健康检查: 检查后端 K8s Node(或 Ingress Controller Pods)的健康状况,只将流量转发到健康的节点。
  6. K8s Worker Node & NodePort/HostPort:

    • Worker Node 作用: K8s 集群中的工作节点,实际运行应用程序 Pod 和其他 K8s 组件(如 kube-proxy, Ingress Controller Pod)。
    • NodePort/HostPort 作用:
      • 当 Ingress Controller 的 Service 类型为 NodePort 时,LB 将流量发送到 Worker Node 的 NodePortkube-proxy 会将该 NodePort 的流量转发给 Ingress Controller Pod。
      • 如果 Ingress Controller Pod 使用 HostPort(不推荐,但可能),LB 也会直接将流量发送到该 Node 的指定端口。
      • 对于云厂商的 LoadBalancer Service 类型,云厂商的 LB 可能直接与 Ingress Controller Pods 的 IP 通信,绕过 NodePort,但底层仍然是 Node 接收流量。
  7. Ingress Controller Pod (e.g., Nginx, Traefik, Caddy):

    • 作用:
      • L7 路由: 这是一个运行在 K8s Pod 内的特殊应用服务器/反向代理。它监听来自外部负载均衡器的流量(通过其 Service)。
      • 规则匹配: 读取并解析 K8s Ingress 资源 (H) 中定义的路由规则(如基于主机名 www.example.com 和路径 /app)。
      • 流量转发: 根据匹配到的规则,将请求转发到 K8s 集群内部对应的 Service (I1)
      • SSL/TLS 终止 (可选): 如果 ELB 没有做 SSL/TLS 终止,Ingress Controller 也可以配置为进行 SSL/TLS 终止。
      • 其他高级功能: 路径重写、请求头修改、认证、限流等。
  8. Ingress 资源 (Ingress Resource - API 对象):

    • 作用: K8s API 对象,定义了外部 HTTP(S) 流量如何路由到集群内部 Service 的规则集合。它本身不处理流量,而是被 Ingress Controller 读取和应用。例如,规则可以指定 host: www.example.com, path: /app -> serviceName: my-web-app, servicePort: 80
  9. Service (ClusterIP for 'my-web-app'):

    • 作用:
      • 抽象和稳定入口: 为一组提供相同功能的 Pod(即 my-web-app 的多个副本)提供一个统一的、稳定的内部虚拟 IP 地址(ClusterIP)和 DNS 名称。
      • 内部负载均衡: 将发往其 ClusterIP 的流量分发到其后端健康的 Pod。
      • 服务发现: Ingress Controller 通过 Service 名称找到这个 ClusterIP。
  10. Endpoints / EndpointSlices:

    • 作用:
      • Pod IP 列表: Service Controller 会自动创建和更新与 Service 关联的 Endpoints (或更现代的 EndpointSlices) 对象。这些对象包含了该 Service 背后所有健康 Pod 的实际 IP 地址和端口。
      • kube-proxy 和 Ingress Controller (某些实现) 会监视这些对象以了解哪些 Pod 是当前可用的。
  11. kube-proxy (运行在每个 Node 上):

    • 作用:
      • Service 实现: 在每个 Node 上运行,监视 API Server 中 Service 和 Endpoints/EndpointSlices 的变化。
      • 网络规则编程: 根据 Service 和 Endpoints/EndpointSlices 的信息,在 Node 上配置网络规则(通常使用 iptablesIPVS)。这些规则实现了 Service 的 ClusterIP 到后端某个具体 Pod IP 的目标网络地址转换 (DNAT) 和负载均衡。
      • 当 Ingress Controller Pod (G1) 将请求发送到 my-web-app Service 的 ClusterIP (I1) 时,kube-proxy 在 G1 所在的 Node (Node 1) 或目标 Pod 所在的 Node (Node X) 上的规则会将这个虚拟 ClusterIP 转换为一个实际的 Pod IP (L1 或 L2 的 IP)。
  12. CNI 网络插件 (e.g., Calico, Flannel, Cilium, Weave Net):

    • 作用:
      • Pod IP 分配: 负责为集群中的每个 Pod 分配唯一的 IP 地址。
      • Pod 间通信: 实现 Pod 之间(包括跨 Node 的 Pod)的网络连接。它可能通过创建覆盖网络 (Overlay Network) 或配置底层网络路由 (Underlay Network) 来实现。
      • 网络策略执行 (某些 CNI): 实现 K8s NetworkPolicy,控制 Pod 间的网络访问。
      • 一旦 kube-proxy 完成了 Service IP 到 Pod IP 的转换,CNI 负责确保数据包能从当前 Node (可能是 Ingress Controller Pod 所在的 Node) 正确路由到目标 Pod (L1 或 L2) 所在的 Node 及具体的 Pod IP。
  13. Pod (my-web-app-pod-A / my-web-app-pod-B):

    • 作用: K8s 中可部署和管理的最小计算单元。它包含一个或多个容器。这里是 my-web-app 的一个实例。它拥有由 CNI 分配的独立 IP 地址。
  14. Container (web-app in Pod A / Pod B):

    • 作用: 实际运行 Web 应用程序(如 Node.js、Python、Golang 应用)的容器。它监听 Pod 内的特定端口(例如 8080),接收由 CNI 网络路由过来的请求,并处理业务逻辑,最终返回响应。

响应流量走向 (简述):

响应流量通常会沿着请求路径反向回流:

Container -> Pod IP -> (CNI 网络) -> Node (kube-proxy 可能参与 SNAT) -> Ingress Controller Pod -> ELB -> 防火墙/WAF -> 互联网 -> 用户浏览器/客户端。

关键点总结:

  • 分层解耦: 每一层都有明确的职责,从 ELB 的流量接入,到 Ingress Controller 的 L7 路由,再到 Service 的内部服务发现和负载均衡,最后到 Pod 内容器的应用处理。
  • 动态性: Service 和 Endpoints/EndpointSlices 机制确保了即使 Pod IP 地址和数量动态变化,服务访问依然稳定。
  • 网络虚拟化: ClusterIP 是虚拟 IP,实际的路由和转发由 kube-proxy 和 CNI 插件共同实现。

这个流程在不同的 K8s 配置和云厂商环境下可能会有细微差别(例如,Service Type 为 LoadBalancer 时,云厂商会自动创建 ELB 并直接指向 Service 的 NodePort 或 Pods),但核心概念和组件的作用是相似的。