一个kubernetes网络简明教程[Part 1]

翻译: icebug

所有我学到的关于kubernetes网络的事情

你可能已经在kubernetes集群当中跑了一堆服务并且正在享受其带来的好处. 或者至少, 你已经计划这么干了. 虽然已经有一大堆工具可以用来安装或者管理集群, 你任然想知道这一切到底是怎么回事. 另外, 当出现故障时到哪里去寻找解决方案? 我知道, 因为我遇到过.

当然, Kubernetes刚开始使用时非常简单. 但还是让我直面它吧--它就是一只引擎盖下面的怪兽. 这里有很多可剥离的组件, 如果你想在失败面前处乱不惊, 知道如何将它们完美地组在一起工作则是一项必备技能. 其中最复杂, 也是最有挑战的一部分就是网络了.

所以我开始着手去理解网络在kubernetes当中究竟是如何工作的. 我读文档, 看演讲, 甚至翻阅了源代码, 如下是我的一些发现.

Kubernetes网络模型

在kubernetes的核心当中, Kubernetes网络有一个重要的基础设计哲学.

每一个Pod都有一个独一无二的IP.

这个Pod IP被这个Pod当中的所有容器所共享, 并且它可以从其他所有的Pod当中路由过来. 你注意到了一些“pause”字样的容器运行在你的Kubernetes节点当中吗? 它们被称为“沙盒容器”, 它们的唯一作用就是保留和占据一个被Pod当中所有容器所共享的网络命名空间(netns). 就这样, 一个Pod IP并不会随着Pod当中的一个容器的起停而改变. 这种一个Pod一个IP的模型的一个巨大的好处就是跟宿主机永远也不会有IP或者端口冲突, 我们甚至都不用管应用用的是什么端口.

有了上面的基础, Kubernetes目前唯一的需求就是这些Pod IP是可路由或者说可以被所有其他Pod访问的, 不管这些Pod运行在什么节点上.

节点内网络通信

第一步先要确保同一个节点上的Pod可以相互通信, 然后再把这个想法扩展到跨节点通信以及互联网通信等.

在每一个Kubernetes节点上, 在这里假设是一台Linux机器, 会有一个root网络命名空间(root表示基命名空间, 区别于系统当中的超级用户root) -- root netns.

主要的网络接口eth0在root netns当中.

同样的, 每一个Pod也都有它自己的netns, 有一个虚拟的以太网络接口对连接到root netns当中. 这只是一个基础的管道对, 一端连接到root netns当中, 另一端连接到Pod netns当中.

Kubernetes节点 (root命名空间)

我们把Pod这端的接口命名为eth0, 所以Pod并不知道底下的宿主机并认为自己已经设置了root netns, 另一端连接root netns的接口的命名为vnetxxx的样式.

Kubernetes节点 (Pod网络命名空间)

你可以通过ifconfig命令或者ip a命令在你的节点上看到所有的接口.

这一切对于节点上的所有Pod都一样. 对于想要想要互相通信Pod, 还需要用到Linux以太网网桥cbr0, Docker用了一个相似的网桥命名为docker0. 你可以通过brctl show看到所有的网桥.

Kubernetes Node (Linux network bridge)

假设一个网络包要从Pod 1到Pod 2.

  1. 网络包从eth0离开Pod 1的netns并通过vnetxxx进入到root netns.
  2. 网络包被传到网桥cbr0, 网桥通过发送“who has this IP?”的ARP请求来发现网络包需要转发到的目的地.
  3. vethyyy回答到它有这个IP, 所以网桥知道应该把网络包转发到哪里.
  4. 网络包到达vethyyy接口, 并通过管道对进入到Pod 2的netns.


Kubernetes Node (same node pod-to-pod communication)

以上就是一个节点当中的容器是如何进行网络通信的内容. 很显然, 还有别的方式, 但这可能是最简单的方式, 并且Docker也是采用的这种方式.

节点间的网络通信

正如我前面提到的, Pod也需要在各个节点之间能够相互访问. Kubernetes并不管它是如何实现的. 我们能用L2(跨节点ARP), L3(跨节点进行IP路由 -- 像云服务提供商的路由表), overlay 网络, 甚至用信鸽. 只要能网络流量能到达另一个节点上指定的Pod, 这一切都没有关系. 每一个节点都会被分配一个独一无二的CIDR块(一个IP地址范围)用于Pod IP, 所以每一个Pod都有一个独一无二的不会和别的节点上的Pod相冲突的IP.

在大多数的情况下, 尤其是在云环境当中, 云计算提供厂商的路由表保证了网络包抵达正确的目的地. 同样的事情也能够通过在每个节点上设置正确的路由来完成. 这里还有一堆其他的网络插件用于完成这件事情.

下面我们有两个节点, 跟我们前面看到的一样, 每一个节点都含有不同的网络命名空间, 网络接口和一个网桥.


Kubernetes Nodes with route table (cross node pod-to-pod communication)

假设一个网络包从pod1到pod4(在一个不同的节点上)

  1. 网络包从eth0离开Pod 1的netns, 并从vethxxx进入root netns.
  2. 网络包被传到cbr0网桥, 通过ARP请求来寻找网络包目的地.
  3. 网络包从cbr0传到主网络接口eth0, 因为在这个节点上没有人有Pod 4的IP地址.
  4. 网络包开始离开node 1, 走上了一条出发端是Pod 1, 目的端是Pod 4的线上.
  5. 路由表上已经设置好了各个节点上CIDR的路由, 并且将网络包路由到CIDR块含有Pod 4 IP的节点.
  6. 所以网络包到达了node 2的主网络接口eth0, 虽然Pod 4不是eth0的IP, 网络包仍然被转发到cbr0, 因为节点被配置为可以进行IP转发, 节点的路由表会寻找任何匹配Pod 4 IP的路由. 然后找到cbr0作为这个节点CIDR块的目的地. 你可以通过route -n命令查看节点的路由表, 然后会发现一条关于cbr0的路由如下:

  7. cbr0网桥获取到网络包, 发出一个ARP请求, 然后发现IP属于vethyyy.
  8. 网络包通过管道对抵达Pod4.

这是一篇关于Kubernetes网络基础的文章, 所以假如下次Kubernetes网络出现问题了, 别忘了检查那些网桥和路由表.

[翻译] 一个kubernetes网络简明教程[Part 1]的更多相关文章

  1. Java网络编程简明教程

    Java网络编程简明教程 网络编程  计算机网络相关概念 计算机网络是两台或更多的计算机组成的网络,同一网络内的任意两台计算机可以直接通信,所有计算机必须遵循同一种网络协议. 互联网 互联网是连接计算 ...

  2. 2017-2018-2 20179207 《网络攻防技术》python简明教程(1-10)

    Python3简明教程(一) 开始python之旅 使用交互模式的 Python3解释器 简单使用 vim 编写 Python3 脚本 执行 Python3 脚本 Python3 代码风格建议 Pyt ...

  3. Python 简明教程 --- 2,第一个Python 程序

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 如果你发现特殊情况太多,那你肯定是用错方法了. -- Carig Zerouni 当你在自己的电脑上 ...

  4. Docker简明教程

    Docker简明教程 [编者的话]使用Docker来写代码更高效并能有效提升自己的技能.Docker能打包你的开发环境,消除包的依赖冲突,并通过集装箱式的应用来减少开发时间和学习时间. Docker作 ...

  5. Python 简明教程 --- 9,Python 编码

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. -- Joshua Bloch 目录 1, ...

  6. Java8简明教程(转载)

    ImportNew注:有兴趣第一时间学习Java 8的Java开发者,欢迎围观<征集参与Java 8原创系列文章作者>. 以下是<Java 8简明教程>的正文. “Java并没 ...

  7. HTML简明教程(一)

    HTML简明教程(一) 内容主体来自:W3School 一.HTML 简介 二.HTML 基础 三.HTML 元素 四.HTML 属性 五.HTML 标题 六.HTML 段落 七.HTML 文本格式化 ...

  8. Boost.Build 简明教程

    Boost.Build 简明教程 目录1. 介绍2. 构建过程3. 基本任务4. 项目管理5. 最佳实践6. 规则参考7. 特征参考 介绍 编译器和平台无关编译系统Boost.Build是一个高级编译 ...

  9. Qemu下安装Sun Solairs8简明教程 转

    http://blog.csdn.net/stonesharp/article/details/8928393 Qemu下安装Sun Solairs8简明教程(Centos6. / Win7) 作者: ...

随机推荐

  1. ffmpeg在asp.net 视频转换

    ffmpeg是一个源于Linux的工具软件,是FLV视频转换器,可以轻易地实现FLV向其它格式avi.asf. mpeg的转换或者将其它格式转换为flv.在视频播客中,我们通常使用它把我们上传的视频转 ...

  2. ngrep 比 tcpdump 更方便查看的抓包显示工具

    ngrep 是grep(在文本中搜索字符串的工具)的网络版,他力求更多的grep特征,用于搜寻指定的数据包 一: ngrep的安装 CentOS6.2 64位 wget http://nchc.dl. ...

  3. P4147 玉蟾宫

    P4147 玉蟾宫 给定一个 \(N * M\) 的矩阵 求最大的全为 \(F\) 的子矩阵 Solution 悬线法 限制条件为转移来的和现在的都为 \(F\) Code #include<i ...

  4. strace常用参数详解

    strace常用参数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. strace命令大家应该比我熟悉吧,如果你不知道,呵呵,会可能跟我一样被人说:“我怀疑你是假运维”,不过没关 ...

  5. 5、JDBC-元信息

    DatabaseMetaData:描述数据库的元数据对象 获取所有数据库 import org.junit.jupiter.api.AfterEach; import org.junit.jupite ...

  6. JS控制CSS3,添加浏览器兼容前缀

    不同浏览器对于有些css3属性名字定义的时候,会带上特有的前缀,所以在css编写的时候,经常会一个属性写多个不同的前缀进行兼容.比如: div { transform: rotate(30deg); ...

  7. 阿里云(四)Linux 实例常用内核网络参数介绍与常见问题处理

    Linux 实例常用内核网络参数介绍与常见问题处理 https://help.aliyun.com/knowledge_detail/41334.html

  8. 20155237 2016-2017-2 《Java程序设计》第8周学习总结

    20155237 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 NIO与NIO2 认识NIO Channel: 衔接数据节点(与IO中的流对比) isOpe ...

  9. JavaScript动态修改CSS

    链接:https://www.cnblogs.com/aademeng/articles/6279060.html 在很多情况下,都需要对网页上元素的样式进行动态的修改.在JavaScript中提供几 ...

  10. UBUNTU18.4环境下使用更好用的搜索引擎(无奈,只能起这样的标题)

    初步安装 更新软件源 sudo apt-get update 安装pip (一个安装和管理 Python 包的工具) sudo apt-get install python-pip sudo apt- ...