Kubernetes 从懵圈到熟练 – 集群网络详解(转)
阿里云K8S集群网络目前有两种方案,一种是flannel方案,另外一种是基于calico和弹性网卡eni的terway方案。Terway和flannel类似,不同的地方在于,terway支持Pod弹性网卡,以及NetworkPolicy功能。
今天这篇文章,我们以flannel为例,深入分析阿里云K8S集群网络的实现方法。我会从两个角度去分析,一个是网络的搭建过程,另外一个是基于网络的通信。我们的讨论基于当前的1.12.6版本。
鸟瞰
总体上来说,阿里云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阶段,这么分类有助于我们理解这些复杂的配置。而理解了各个配置,集群通信原理就比较容易理解了。
Kubernetes 从懵圈到熟练 – 集群网络详解(转)的更多相关文章
- K8s 从懵圈到熟练 – 集群网络详解
作者 | 声东 阿里云售后技术专家 导读:阿里云 K8S 集群网络目前有两种方案:一种是 flannel 方案:另外一种是基于 calico 和弹性网卡 eni 的 terway 方案.Terway ...
- Kubernetes从懵圈到熟练:读懂这一篇,集群节点不下线
排查完全陌生的问题,完全不熟悉的系统组件,是售后工程师的一大工作乐趣,当然也是挑战.今天借这篇文章,跟大家分析一例这样的问题.排查过程中,需要理解一些自己完全陌生的组件,比如systemd和dbus. ...
- Kubernetes 从懵圈到熟练:集群服务的三个要点和一种实现
作者 | 声东 阿里云售后技术专家 文章来源:Docker,点击查看原文. 以我的经验来讲,理解 Kubernetes 集群服务的概念,是比较不容易的一件事情.尤其是当我们基于似是而非的理解,去排查服 ...
- Kubernetes K8S之Taints污点与Tolerations容忍详解
Kubernetes K8S之Taints污点与Tolerations容忍详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master C ...
- Kubernetes K8S之CPU和内存资源限制详解
Kubernetes K8S之CPU和内存资源限制详解 Pod资源限制 备注:CPU单位换算:100m CPU,100 milliCPU 和 0.1 CPU 都相同:精度不能超过 1m.1000m C ...
- Kubernetes K8S之资源控制器Job和CronJob详解
Kubernetes的资源控制器Job和CronJob详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2 ...
- Kubernetes K8S之affinity亲和性与反亲和性详解与示例
Kubernetes K8S之Node节点亲和性与反亲和性以及Pod亲和性与反亲和性详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-mas ...
- K8s 从懵圈到熟练 – 镜像拉取这件小事
作者 | 声东 阿里云售后技术专家 导读:相比 K8s 集群的其他功能,私有镜像的自动拉取,看起来可能是比较简单的.而镜像拉取失败,大多数情况下都和权限有关.所以,在处理相关问题的时候,我们往往会轻松 ...
- kubernetes创建资源对象yaml文件例子--pod详解
apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数据/属性 name: ...
随机推荐
- 烽火传递【单调队列优化dp】
题目大意: 1.给出长度为n的数组,要求每m个连续的元素之间必须选一个值作为代价,求该数组的最小代价. 题解思路: 1.显然是线性dp,dp[i]表示选择第 i 个元素时的最小总代价.很明显状态转移方 ...
- LeetCode 680. 验证回文字符串 Ⅱ(Valid Palindrome II) 1
680. 验证回文字符串 Ⅱ 680. Valid Palindrome II 题目描述 给定一个非空字符串 s,最多删除一个字符.判断是否能成为回文字符串. 每日一算法2019/5/4Day 1Le ...
- Visual Studio 2019 离线安装方法
1. 网址 1.1 阅读官方离线安装教程 离线安装官网 仔细阅读离线安装官网,差不多就能学会如何下载. 1.2 工作负荷和组件 ID 进入这个网址,Visual Studio 工作负荷和组件 ID,单 ...
- 剑指offer66:机器人的运动范围
1 题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器 ...
- css拓展
自定义居中 .second-listleft{/*固定位置*/ position: relative; float: left; width: 25%; height: 100%; backgroun ...
- 怎样获取iframe节点的window对象
需要使用iframeElement.contentWindow; var frame = document.getElementById('theFrame'); var frameWindow = ...
- Linux修改主机名方法
[root@lyx ~]# vim /etc/hosts vim代表修改,进入hosts文件进行添加192.168.10.128 hadoop128 [root@lyx ~]# hostname ...
- CSS3Ps -Photoshop图层特效转CSS3代码
CSS3Ps 这个ps插件可以将ps图层特效直接转化成css3代码,对前端非常有益. 插件下载:http://css3ps.com/Download/
- 链接标签<a>去掉下划线
1.去掉下划线 text-decoration:none:
- vue函数化组件 functional
需要在组件中把functional 设置为true 一个函数化组件像这样: Vue.component('testcomponent', { functional: true, // 为了弥补缺少的实 ...