乐趣区

华为云技术分享跟唐老师学习云网络-Kubernetes网络实现

当今 K8s 独霸天下之时,咱们站在更高的角度,好好的看看 K8s 网络是以什么理念构筑的。以及一个容器集群的好保姆,是如何分别照顾 南北流量和东西流量的。

一、简单介绍下 Kubernetes

略。。容器集群管理的事实标准了,不知道要打屁股。

(ps:本章节可参考唐老师的《K8S 前世今生》文章)

二、世界上的集群都一个样

有点标题党哈,不过我接触过的各种集群也不少,各种各样:

Ø OpenStack:在一大堆物理机上面,管理(启动 / 停止)VM 的。

Ø SGE,Slurm,PBS:在一大堆电脑集群里面,管理(启动 / 停止)App 的。

Ø Yarn:在一大堆电脑集群里面,管理(启动 / 停止)大数据 App 的。

Ø CloudFoundry:在一大堆电脑集群里面,管理(启动 / 停止)容器的

Ø Kubernetes:在一大堆电脑集群里面,管理(启动 / 停止)容器的。

它们都有一些共同特点:

2.1 跨节点跑 xx 程序

这个 xx 程序一定是首先单机可以运行的。比如 OpenStack:单机上面可以用 qemu 启动 VM,想跨节点管理 VM,就引入了 OpenStack。Kubernetes 也一样:单机上面可以跑 Docker 容器;想跨节点管理容器,就得引入集群管理老大的概念。

2.2 有一个管事的老大

A)集群管理的老大,负责让手下的某个小弟干活。别管是命令式(直接下命令)的,还是申明式(发告示)的,小弟收到命令后,乖乖干活就是了。

B)同时,这个集群管理的老大,需要有脑子,不然小弟数量多了管不好。所以它需要拿笔记一记。比如 OpenStack 的老大得带个 Mysql 数据库;Kubernetes 把笔记记在了 ETCD 里面(不过 ETCD 这个本子太小,记得东西不能太大,这是另话)。

C)不管哪种老大,都得有个军师。一个新活来到老大这里,那么多小弟,指派给谁不是干呀。这活实际分配给哪个小弟,这得军师说了算,所以每中集群软件都自己写了一套 Scheduler 算法,可谓程序员间浪费重复轮子之典型代表。

2.3 小弟上面都有一个 Agent

这个小弟上面的 Agent,时刻向老大汇报自己的状态:活不活着,忙还是闲,方便老大派活。同时,Agent 也就是那台电脑里面的地头蛇了,帮忙老大负责各种临时事物。只是大家的取名不一样:

OpenStack:取名 Nova

Kubernetes:取名 Kubelet

Yarn:取名 NodeManager

2.4 老大怎么给小弟发号施令

一般老大都是通过:消息队列来,给小弟发号施令的,而不是亲自上门(直连)下达命令。原因么,当然是小弟可能临时出门(故障)了呗~ 直接上门可能不通,放消息队列里面就可靠多了。等小弟出差回来,还能看到老大下达的任务令。

Ø OpenStack:用 RabbitMQ 发号施令

Ø Kubernetes:用 ETCD 发号施令

Ø CloudFoundry:用 NATS 发号施令

上面这些组件都是带消息通知的功能,区别有些有名,有些没那么出名罢了。

比如我们的 K8s:

特别需要提一下:K8s 这个老大不简单,找了个 ETCD 这个好帮手。这小家伙挺神,既能当笔记本记点事情(代替 OpenStack 中的 Mysql),又能当公告牌,通知点消息(代替 OpenStack 中的 Rabbit)。所以 K8s 这个容器集群管理相对 OpenStack 这个虚机管理不需要数据库,666~

三、K8s 怎么设计容器网络的呢

3.1 南北流量

要看到 K8s 诞生的时候,那时是有 CloudFoundry 和 Docker 的,且都已经比较成熟。那时作为 PaaS 一哥的 CF 对容器网络的抽象:

主要考虑平台外部,怎么访问容器里面的 App。而平台内部的 App 之间如何互相访问,几乎没有太多的设计。

由上图所示,可以看到,平台外部访问,一般都是上下画的,所以也叫做 南北流量。我们这么叫,也是便于程序员之间沟通和理解。

Ps:PaaS 的基本原型大致都这样:

3.2 东西流量

K8s 吸取了前辈们的精华,除了平台外部访问 App,还新增考虑了平台内部,App 之间如何互相访问。

即 K8s 通过增加一个负载均衡的“LB”设备,来搞定平台内部的 App 间互相访问。给每个 App 取个别名,在 LB 上面登记一下,就可以被内部其他 App 访问。

由上图所示,可以看到,平台内部访问,一般都是水平画的,所以也叫做 东西流量。一个完整的 PaaS 平台,就是需要南北流量 + 东西流量,全套治理的。

3.3 Docker 原生访问方式

还记得唐老师的《Docker 网络实现》章节吧,Docker 容器可以通过“节点 IP+ 节点 Port”的方式访问到容器。原理的容器所在节点,设置了 NAT 规则。报文一到达节点,根据目的端口,转发进入容器。

3.4 小结:K8s 中 3 种访问容器的通道

(1)通过南北流量(从集群外部访问 App)访问 App 容器

(2)通过东西流量(集群内 App 之间)访问 App 容器

(3)通过 Docker 原生自带的方式,访问 App 容器

下一章节,我们简单介绍下每种方式,K8s 分别怎么去实现的。

四、K8s 怎么实现容器访问

虽然 K8s 上面,有多种访问 App 容器的方法。但是不管用什么方式访问,一个 App 想要能被访问,就得得到 K8s 的同意。K8s 把这个许可证叫做“Service”:也就是不管什么南北流量、东西流量,你的 App 想要能被访问,就得先申请 Service 许可证。

4.1 南北流量

要实现一个 App 的访问通道,一定要 2 个东西:(1)LB 负载均衡器 +(2)注册映射关系。

映射关系就是:报文来了,应该转发给哪个 App 实例?即:找到“哪个 App + 哪个实例”。

负载均衡器呢,一般大家爱用 Nginx,不过也有其他类型的实现。

K8s 比 CF 聪明的地方是,没有自己去实现 LB。而只定义了 App 需要怎么样才能登记到 LB 上面。即只定规范,不限制实现(这种思路,在 k8s 里面好多,比如存储的 CSI,运行时的 CRI 的,容器网络的 CNI 都是这样。)

Ø 4 层 LB

最简单的 4 层 LB 实现,K8s 取了个名字:LoadBalancer(1)

即定义:xx 协议 +xx 端口 =》xx 应用,具体规则自己去看资料。

Ø 7 层 LB

为了定义 7 层 LB 的规则,K8s 给规范取了名字:Ingress(2)

即定义:xx 网址 +xx-URL 路径 =》xx 应用,具体规则也自己看 K8s 资料。

南北 LB 都是全局级的,即:全局一个(HA 多实例,咱也当一个整体)就行;不需要每个 Slaver 节点上一个。

4.2 东西流量

东西流量,也一样,需要 LB+ 规则注入。这里,K8s 设计就比较有意思。

逻辑上,如上图所示。在 LB 部分的实现上,K8s 很巧妙的要求每个节点上面都一个“小 LB”。

所以实现上,大致如上图所示。

Ø 本地 LB

本地 LB,要求每个节点都有。所以最开始的版本,K8s 使用了 Linux 使用广泛的 iptables 来实现。

后面由于 iptables 性能不是特别给力,又有了 IPVS 实现。然后其他各式各样的民间实现也有。

Ø 本地控制器

LB 需要一个控制器,每个本地“小 LB”带配备一个小控制器,一样的,也是每个节点一个。和小 LB 一一对应。K8s 给它取了个名字:Kube-proxy

Ø 假 IP 地址

每个 K8s 上的 App,都可以申请“行走江湖的名号”,用来代表自己。K8s 就会给你的 App 分配一个 Service 许可证,许可证上面带着“影子 IP”,任何集群内部只要访问这个 IP,就等于访问你的 App。

实现上:

1. 先到 K8s 那登记,说我想要个“名号”

2. 通过后,K8s 会告知每个节点上的本地 LB

3. 从此以后,每个 LB 都认识这个“影子 IP”了,访问它,就代表访问对应 App。

由于这个“名号”是集群颁布的,所以仅在集群内有效。K8s 取名:ClusterIP(3)

关于东西流量的故事,还可以去看看唐老师之前的《网络骗子》篇。

4.3 Docker 原生访问方式

除了上面几种访问方式,K8s 也为原生的 Docker 访问通道留了个名字:NodePort(4)

这种方式,在《Docker 网络实现》里面说过,靠主机 Host 转发实现。既然是主机搞定,所以这条路和本地 LB 实现,就合并一起搞定了。

如上图,K8s 下发规则的时候,顺便把这条路的规则也下发下去。

ps:由于每个本地 LB 都收到了 K8s 的通告小皮鞭,所以每个 K8s 的节点,都开通了 NodePort 通道哦。即:无论哪个 Slaver 节点的 Port 都可以通往该 App。

4.4 小结

K8s 在实现容器网络的时候,造了很多概念:

(1)LoadBalancer

(2)Ingress

(3)ClusterIP

(4)NodePort

本质都是一样的,就是 LB+ 登记规范。如果你看过《DNS 篇》+《Docker 网络实现》,这些就比较好理解。

ps:具体本地 LB 怎么实现?真有兴趣可以去搜搜 Kube-proxy 的代码解读。我本身不是很关心,因为其实你给每个节点安装一个 Nginx 也可以做到的。

五、总结

K8s 的网络概念,特别是 Service,是 K8s 里面的精华,务必需要搞明白。

(1)K8s 南北流量,用 Loadbalancer(4 层)和 Ingress(7 层)搞定。

(2)K8s 的东西流量,用 Service 概念搞定。特别的,还给了个“行走江湖用的名号”,取名 ClusterIP(一个不存在的假 IP 地址)。

(3)容器所在 Host 组网,存在 Docker 原生通道,K8s 给重新包装了个名字:NodePort。所以只要报文到达 Slaver 节点,就能通到容器里面。

另外,提一下一直没有说的东西(怕概念太多,影响理解):K8s 的整个网络底座,是要求节点 IP 和容器 IP 是能互相连通的(即:在节点上面 ping 容器 IP,是可以通的)。具体则是通过容器网络实现的。这个实现很多,Flannel,Calico 等,本质要么隧道,要么子网(可以看看物理网络里面的《VLAN 和 Vxlan》篇,关于如何划分门派的篇章)。

作者:华为云云享专家 tsjsdbd

点击关注,第一时间了解华为云新鲜技术~

退出移动版