Appearance
假设场景:
- 用户通过
www.example.com/myapp/dosomething
访问应用服务。 - K8s 集群部署在云厂商(如 AWS, GCP, Azure)IDC。
- 使用 Ingress Controller (如 Nginx Ingress) 进行 L7 路由。
- 应用服务以 Deployment Workload 形式部署,并通过一个 ClusterIP 类型的 Service 暴露。
以下是一张描述外部流量请求该应用服务的流量走向图,以及流经的各个网络组件作用说明。
请修复一下有语法错误的mermaid图,请确保不要更改原图的内容部分,只修改语法格式上的错误。
流量走向及各组件作用说明:
用户浏览器/客户端:
- 作用: 发起对
www.example.com/myapp/dosomething
的 HTTP(S)请求,这是流量的起点。
- 作用: 发起对
DNS 服务器:
- 作用: 接收来自客户端的域名解析请求,将域名
www.example.com
解析为其配置的 A 记录或 CNAME 记录对应的 IP 地址。这个 IP 地址通常是外部负载均衡器 (ELB) 的公网 IP。
- 作用: 接收来自客户端的域名解析请求,将域名
互联网:
- 作用: 公共网络,负责将用户的请求从客户端路由到目标 IP 地址(即 ELB 的 公网IP)。
防火墙/WAF:
- 作用:
- 防火墙: 网络安全的第一道防线,根据预设规则允许或拒绝流量,通常在 IDC 网络边缘进行 IP、端口级别的访问控制。
- WAF (可选): 应用层防火墙,检测和阻止常见的 Web 攻击,如 SQL 注入、XSS 等。通常部署在 ELB 之前或集成在 ELB 中。
- 作用:
外部负载均衡器 (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)的健康状况,只将流量转发到健康的节点。
- 作用:
K8s Worker Node & NodePort/HostPort:
- Worker Node 作用: K8s 集群中的工作节点,实际运行应用程序 Pod 和其他 K8s 组件(如 kube-proxy, Ingress Controller Pod)。
- NodePort/HostPort 作用:
- 当 Ingress Controller 的 Service 类型为
NodePort
时,LB 将流量发送到 Worker Node 的NodePort
。kube-proxy
会将该NodePort
的流量转发给 Ingress Controller Pod。 - 如果 Ingress Controller Pod 使用
HostPort
(不推荐,但可能),LB 也会直接将流量发送到该 Node 的指定端口。 - 对于云厂商的 LoadBalancer Service 类型,云厂商的 LB 可能直接与 Ingress Controller Pods 的 IP 通信,绕过 NodePort,但底层仍然是 Node 接收流量。
- 当 Ingress Controller 的 Service 类型为
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 终止。
- 其他高级功能: 路径重写、请求头修改、认证、限流等。
- 作用:
Ingress 资源 (Ingress Resource - API 对象):
- 作用: K8s API 对象,定义了外部 HTTP(S) 流量如何路由到集群内部 Service 的规则集合。它本身不处理流量,而是被 Ingress Controller 读取和应用。例如,规则可以指定
host: www.example.com, path: /app -> serviceName: my-web-app, servicePort: 80
。
- 作用: K8s API 对象,定义了外部 HTTP(S) 流量如何路由到集群内部 Service 的规则集合。它本身不处理流量,而是被 Ingress Controller 读取和应用。例如,规则可以指定
Service (ClusterIP for 'my-web-app'):
- 作用:
- 抽象和稳定入口: 为一组提供相同功能的 Pod(即
my-web-app
的多个副本)提供一个统一的、稳定的内部虚拟 IP 地址(ClusterIP)和 DNS 名称。 - 内部负载均衡: 将发往其 ClusterIP 的流量分发到其后端健康的 Pod。
- 服务发现: Ingress Controller 通过 Service 名称找到这个 ClusterIP。
- 抽象和稳定入口: 为一组提供相同功能的 Pod(即
- 作用:
Endpoints / EndpointSlices:
- 作用:
- Pod IP 列表: Service Controller 会自动创建和更新与 Service 关联的 Endpoints (或更现代的 EndpointSlices) 对象。这些对象包含了该 Service 背后所有健康 Pod 的实际 IP 地址和端口。
kube-proxy
和 Ingress Controller (某些实现) 会监视这些对象以了解哪些 Pod 是当前可用的。
- 作用:
kube-proxy (运行在每个 Node 上):
- 作用:
- Service 实现: 在每个 Node 上运行,监视 API Server 中 Service 和 Endpoints/EndpointSlices 的变化。
- 网络规则编程: 根据 Service 和 Endpoints/EndpointSlices 的信息,在 Node 上配置网络规则(通常使用
iptables
或IPVS
)。这些规则实现了 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)。
- 作用:
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。
- 作用:
Pod (my-web-app-pod-A / my-web-app-pod-B):
- 作用: K8s 中可部署和管理的最小计算单元。它包含一个或多个容器。这里是
my-web-app
的一个实例。它拥有由 CNI 分配的独立 IP 地址。
- 作用: K8s 中可部署和管理的最小计算单元。它包含一个或多个容器。这里是
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),但核心概念和组件的作用是相似的。