「网络拓扑」Kubernetes 网络模型来龙去脉( 三 )


「网络拓扑」Kubernetes 网络模型来龙去脉
本文插图
它的实现是这样的:首先是由一群 Pod 组成一组功能后端 , 再在前端上定义一个虚 IP 作为访问入口 。 一般来说 , 由于 IP 不太好记 , 我们还会附赠一个 DNS 的域名 , Client 先访问域名得到虚 IP 之后再转成实 IP 。 Kube-proxy 则是整个机制的实现核心 , 它隐藏了大量的复杂性 。 它的工作机制是通过 apiserver 监控 Pod/Service 的变化(比如是不是新增了 Service、Pod)并将其反馈到本地的规则或者是用户态进程 。
一个 LVS 版的 Service我们来实际做一个 LVS 版的 Service 。 LVS 是一个专门用于负载均衡的内核机制 。 它工作在第四层 , 性能会比用 iptable 实现好一些 。
假设我们是一个 Kube-proxy , 拿到了一个 Service 的配置 , 如下图所示:它有一个 Cluster IP , 在该 IP 上的端口是 9376 , 需要反馈到容器上的是 80 端口 , 还有三个可工作的 Pod , 它们的 IP 分别是 10.1.2.3, 10.1.14.5, 10.1.3.8 。
「网络拓扑」Kubernetes 网络模型来龙去脉
本文插图
它要做的事情就是:
「网络拓扑」Kubernetes 网络模型来龙去脉
本文插图

  • 第 1 步 , 绑定 VIP 到本地(欺骗内核);
首先需要让内核相信它拥有这样的一个虚 IP , 这是 LVS 的工作机制所决定的 , 因为它工作在第四层 , 并不关心 IP 转发 , 只有它认为这个 IP 是自己的才会拆到 TCP 或 UDP 这一层 。 在第一步中 , 我们将该 IP 设到内核中 , 告诉内核它确实有这么一个 IP 。 实现的方法有很多 , 我们这里用的是 ip route 直接加 local 的方式 , 用 Dummy 哑设备上加 IP 的方式也是可以的 。
  • 第 2 步 , 为这个虚 IP 创建一个 IPVS 的 virtual server;
告诉它我需要为这个 IP 进行负载均衡分发 , 后面的参数就是一些分发策略等等 。 virtual server 的 IP 其实就是我们的 Cluster IP 。
  • 第 3 步 , 为这个 IPVS service 创建相应的 real server 。
我们需要为 virtual server 配置相应的 real server , 就是真正提供服务的后端是什么 。 比如说我们刚才看到有三个 Pod , 于是就把这三个的 IP 配到 virtual server 上 , 完全一一对应过来就可以了 。 Kube-proxy 工作跟这个也是类似的 。 只是它还需要去监控一些 Pod 的变化 , 比如 Pod 的数量变成 5 个了 , 那么规则就应变成 5 条 。 如果这里面某一个 Pod 死掉了或者被杀死了 , 那么就要相应地减掉一条 。 又或者整个 Service 被撤销了 , 那么这些规则就要全部删掉 。 所以它其实做的是一些管理层面的工作 。
啥?负载均衡还分内部外部
最后我们介绍一下 Service 的类型 , 可以分为以下 4 类 。
1. ClusterIP集群内部的一个虚拟 IP , 这个 IP 会绑定到一堆服务的 Group Pod 上面 , 这也是默认的服务方式 。 它的缺点是这种方式只能在 Node 内部也就是集群内部使用 。
2. NodePort供集群外部调用 。 将 Service 承载在 Node 的静态端口上 , 端口号和 Service 一一对应 , 那么集群外的用户就可以通过 : 的方式调用到 Service 。
3. LoadBalancer给云厂商的扩展接口 。 像阿里云、亚马逊这样的云厂商都是有成熟的 LB 机制的 , 这些机制可能是由一个很大的集群实现的 , 为了不浪费这种能力 , 云厂商可通过这个接口进行扩展 。 它首先会自动创建 NodePort 和 ClusterIP 这两种机制 , 云厂商可以选择直接将 LB 挂到这两种机制上 , 或者两种都不用 , 直接把 Pod 的 RIP 挂到云厂商的 ELB 的后端也是可以的 。


推荐阅读