作者 | 声东 阿里云售后技术专家

导读:阿里云 K8S 集群网络目前有两种方案:一种是 flannel 方案;另外一种是基于 calico 和弹性网卡 eni 的 terway 方案。Terway 和 flannel 类似,不同的地方在于 terway 支持 Pod 弹性网卡,以及 NetworkPolicy 功能。本文中,作者基于当前的 1.12.6 版本,以 flannel 为例,深入分析阿里云 K8S 集群网络的实现方法。

鸟瞰

总体上来说,阿里云 K8S 集群网络配置完成之后,如下图所示:包括集群 CIDR、VPC 路由表、节点网络、节点的 podCIDR、节点上的虚拟网桥 cni0、连接 Pod 和网桥的 veth 等部分。

类似的图大家可能在很多文章中都看过,但因为其中相关配置过于复杂,比较难理解。这里我们可以看下这些配置背后的逻辑。

基本上我们可以把这些配置分三种情况来理解:集群配置,节点配置以及 Pod 配置。与这三种情况对应的,其实是对集群网络 IP 段的三次划分:首先是集群 CIDR,接着是为每个节点分配 podCIDR(即集群 CIDR 的子网段),最后在 podCIDR 里为每个 Pod 分配自己的 IP。

集群网络搭建

初始阶段

集群的创建,基于云资源 VPC 和 ECS,在创建完 VPC 和 ECS 之后,我们基本上可以得到如下图的资源配置。我们得到一个 VPC,这个 VPC 的网段是 192.168.0.0/16,我们得到若干 ECS,他们从 VPC 网段里分配到 IP 地址。

集群阶段

在以上出初始资源的基础上,我们利用集群创建控制台得到集群 CIDR。这个值会以参数的形式传给集群节点 provision 脚本,并被脚本传给集群节点配置工具 kubeadm。kubeadm 最后把这个参数写入集群控制器静态 Pod 的 yaml 文件 kube-controller-manager.yaml。

集群控制器有了这个参数,在节点 kubelet 注册节点到集群的时候,集群控制器会为每个注册节点,划分一个子网出来,即为每个节点分配 podCIDR。如上图,Node B 的子网是 172.16.8.1/25,而 Node A 的子网是 172.16.0.128/25。这个配置会记录到集群 node 的 podCIDR 数据项里。

节点阶段

经过以上集群阶段,K8S 有了集群 CIDR,以及为每个节点划分的 podCIDR。在此基础上,集群会下发 flanneld 到每个阶段上,进一步搭建节点上,可以给 Pod 使用的网络框架。这里主要有两个操作:

  • 第一个是集群通过 Cloud Controller Manager 给 VPC 配置路由表项。路由表项对每个节点有一条,每一条的意思是,如果 VPC 路由收到的目的地址是某一个节点 podCIDR 的 IP 地址,那么路由会把这个网络包转发到对应的 ECS 上;
  • 第二个是创建虚拟网桥 cni0 以及与 cni0 相关的路由。这些配置的作用是,从阶段外部进来的网络包,如果目的 IP 是 podCIDR,则会被节点转发到 cni0 虚拟局域网里。

注意:实际实现上,cni0 的创建,是在第一个使用 Pod 网络的 Pod 被调度到节点上的时候,由下一节中 flannal cni 创建的,但是从逻辑上来说,cni0 属于节点网络,不属于 Pod 网络,所以在此描述。

Pod 阶段

在前边的三个阶段,集群实际上已经为 Pod 之间搭建了网络通信的干道。这个时候,如果集群把一个 Pod 调度到节点上,kubelet 会通过 flannel cni 为这个 Pod 本身创建网络命名空间和 veth 设备,然后,把其中一个 veth 设备加入到 cni0 虚拟网桥里,并为 Pod 内的 veth 设备配置 IP 地址。这样 Pod 就和网络通信的干道连接在了一起。
这里需要强调的是,前一节的 flanneld 和这一节的 flannel cni 完全是两个组件。flanneld 是一个 daemonset 下发到每个节点的 pod,它的作用是搭建网络(干道),而 flannel cni 是节点创建的时候,通过 kubernetes-cni 这个 rpm 包安装的 cni 插件,其被 kubelet 调用,用来为具体的 pod 创建网络(分枝)。理解这两者的区别,有助于我们理解 flanneld 和 flannel cni 相关的配置文件的用途。比如 /run/flannel/subnet.env,是 flanneld 创建的,为 flannel cni 提供输入的一个环境变量文件;又比如 /etc/cni/net.d/10-flannel.conf,也是 flanneld pod(准确的说,是 pod 里的脚本 install-cni)从 pod 里拷贝到节点目录,给 flannel cni 使用的子网配置文件。

通信

以上完成 Pod 网络环境搭建。基于以上的网络环境,Pod 可以完成四种通信:本地通信;同节点 Pod 通信;跨节点 Pod 通信;以及 Pod 和 Pod 网络之外的实体通信。

其中本地通信,说的是 Pod 内部,不同容器之间的通信。因为 Pod 内网容器之间共享一个网络协议栈,所以他们之间的通信,可以通过 loopback 设备完成。

同节点 Pod 之间的通信,是 cni0 虚拟网桥内部的通信,这相当于一个二层局域网内部设备通信。

跨节点 Pod 通信略微复杂一点,但也很直观,发送端数据包,通过 cni0 网桥的网关,流转到节点上,然后经过节点 eth0 发送给 VPC 路由。这里不会经过任何封包操作。当 VPC 路由收到数据包时,它通过查询路由表,确认数据包目的地,并把数据包发送给对应的 ECS 节点。而进去节点之后,因为 flanneld 在节点上创建了 cni0 的路由,所以数据包会被发送到目的地的 cni0 局域网,再到目的地 Pod。

最后一种情况,Pod 与非 Pod 网络的实体通信,需要经过节点上 iptables 规则做 SNAT,而此规则就是 flanneld 依据命令行 --ip-masq 选项做的配置。

总结

以上是阿里云 K8S 集群网络的搭建和通信原理。我们主要通过网络搭建和通信两个角度去分析 K8S 集群网络。其中网络搭建包括初始阶段、集群阶段、节点阶段以及 Pod 阶段,这么分类有助于我们理解这些复杂的配置。而理解了各个配置,集群通信原理就比较容易理解了。

“ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

K8s 从懵圈到熟练 – 集群网络详解的更多相关文章

  1. Kubernetes 从懵圈到熟练 – 集群网络详解(转)

    阿里云K8S集群网络目前有两种方案,一种是flannel方案,另外一种是基于calico和弹性网卡eni的terway方案.Terway和flannel类似,不同的地方在于,terway支持Pod弹性 ...

  2. K8s 从懵圈到熟练 – 镜像拉取这件小事

    作者 | 声东 阿里云售后技术专家 导读:相比 K8s 集群的其他功能,私有镜像的自动拉取,看起来可能是比较简单的.而镜像拉取失败,大多数情况下都和权限有关.所以,在处理相关问题的时候,我们往往会轻松 ...

  3. Kubernetes K8S之固定节点nodeName和nodeSelector调度详解

    Kubernetes K8S之固定节点nodeName和nodeSelector调度详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-mas ...

  4. Kubernetes K8S之通过helm部署metrics-server与HPA详解

    Kubernetes K8S之通过helm部署metrics-server与 Horizontal Pod Autoscaling (HPA)详解 主机配置规划 服务器名称(hostname) 系统版 ...

  5. Kubernetes从懵圈到熟练:读懂这一篇,集群节点不下线

    排查完全陌生的问题,完全不熟悉的系统组件,是售后工程师的一大工作乐趣,当然也是挑战.今天借这篇文章,跟大家分析一例这样的问题.排查过程中,需要理解一些自己完全陌生的组件,比如systemd和dbus. ...

  6. Kubernetes 从懵圈到熟练:集群服务的三个要点和一种实现

    作者 | 声东 阿里云售后技术专家 文章来源:Docker,点击查看原文. 以我的经验来讲,理解 Kubernetes 集群服务的概念,是比较不容易的一件事情.尤其是当我们基于似是而非的理解,去排查服 ...

  7. Kubernetes K8S之Ingress详解与示例

    K8S之Ingress概述与说明,并详解Ingress常用示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...

  8. 036.集群网络-K8S网络模型及Linux基础网络

    一 Kubernetes网络模型概述 1.1 Kubernetes网络模型 Kubernetes网络模型设计的一个基础原则是:每个Pod都拥有一个独立的IP地址,并假定所有Pod都在一个可以直接连通的 ...

  9. Hadoop配置第1节-集群网络配置

    Hadoop-集群网络配置 总体目标:完成zookeeper+Hadoop+Hbase 整合平台搭建   进度:1:集群网络属性配置2:集群免密码登陆配置3:JDK的安装4:Zookeeper的安装5 ...

随机推荐

  1. zoj 3724 树状数组经典

    问题:n个点,对于每个点i,都有一条连向i+1的有向边,另外有m条其他的有向边,有q个询问(u,v)求u到v的最短路   将m条有向边和q个询问对所表示的点对一起排序,(u,v)u大的排前,u一样的v ...

  2. CodeForces 628 D Magic Numbers 数位DP

    Magic Numbers 题意: 题意比较难读:首先对于一个串来说, 如果他是d-串, 那么他的第偶数个字符都是是d,第奇数个字符都不是d. 然后求[L, R]里面的多少个数是d-串,且是m的倍数. ...

  3. Dungeon Master POJ - 2251 [kuangbin带你飞]专题一 简单搜索

    You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of un ...

  4. d3.js 制作简单的俄罗斯方块

    d3.js是一个不错的可视化框架,同时对于操作dom也是十分方便的.今天我们使用d3.js配合es6的类来制作一个童年小游戏--俄罗斯方块.话不多说先上图片. 1. js tetris类 由于方法拆分 ...

  5. 手工释放服务器的swap分区缓存

    时间     恢复时间 状态 信息 主机 问题 • 严重性 持续时间 确认 动作 2019-03-21 20:29:30     09:51:30     -ai-代理 Lack of free sw ...

  6. C# 表达式树Lambda扩展(四)

    一.前言 本来计算这篇文章在后面需要运用的时候写的,但是既然写到表达式的扩展呢,就一起写完吧. 看到这个标题就有一种疑问,Lambda表达式本来就是表达式树,还需要怎么扩展?那就看看下面的内容,你就知 ...

  7. SpringBoot 2.0 + Apache Dubbo 2.7.3 最新版整合方案

    前言 2018年2月16日,Apache Dubbo 加入 Apache 基金会孵化器.2019年5月16日,Apache 软件基金会董事会决议通过了 Apache Dubbo 的毕业申请,这意味着 ...

  8. android中shape 的使用

    android 开发中 对于 shape 和 selector的使用,一直都不是很熟练, 记录一下.便于以后参考. 举个项目中例子图 对于上面的2个radiobutton ,背景我们可以让美工做一个. ...

  9. 【学习笔记】第七章 python3核心技术与实践--输入与输出

    [第六章]思考题答案,仅供参考: # coding:utf-8import time#方法一start_time = time.perf_counter()s = ''for n in range(0 ...

  10. 降低 80% 的读写响应延迟!我们测评了 etcd 3.4 新特性(内含读写发展史)

    作者 | 陈洁(墨封)  阿里云开发工程师 导读:etcd 作为 K8s 集群中的存储组件,读写性能方面会受到很多压力,而 etcd 3.4 中的新特性将有效缓解压力,本文将从 etcd 数据读写机制 ...