深入解读docker网络与kubernetes网络

前言:你是否学习使用k8s很久很久了可是对于网络这块仍旧似懂非懂呢? 您是否对网上一堆帖子有如下的抱怨:

  • 打开多个博客,然后发现有区别么?
  • 明显是直译过来的,越看越迷糊
  • “因为xxx,所以yyy”,......怎么就从xxx到yyy了?

       所以,就想用通俗的语言,用一般人类的思维历程将我学到的分享出来,在学习的过程中我我会将我读到了哪些文档一并贴出来,有理解偏差的还请指正,但是基本理论都是经过反复推敲和验证的,得为自己的言行负责呀~

大纲:

1.概述

   1.1Linux的namespace+cgroup

   1.2容器的网络

   1.3pod的网络

    插播1:Docker和容器的关系

2.Docker容器网络详解

   2.1 CNM&libnetwork

   2.2 单机网络---brige类型的网络

   2.3 多机网络---overlay类型的网络

3.pod的网络详解

   2.1 kubernetes网络概述

   2.2 详解pod内的网络

   2.3 详解pod间的网络

  

网络概述


 

1,Linux的namespace+cgroup
 namespace和cgroup是Linux 内核的两大特性,namespace的诞生据说就是为了支持容器技术,那么这俩特性到底干了啥呢?

 - namespace:linux支持多种类型的namespace,包括Network,IPC,PID, Mount, UTC, User。创建不同类型的namespace就相当于从不同资源维度在主机上作隔离。

 - cgroup:为了不让某个进程一家独大,而其他进程饿死,所以它的作用就是控制各进程分配的CPU,Memory,IO等。

 - namespace+cgroup也适用进程组,即多进程运行在一个单独的ns中,此时该ns下的进程就可以交互了。

参考:https://coolshell.cn/articles/17010.html

2,容器
容器实际上是结合了namespace 和 cgroup 的一般内核进程,注意,容器就是个进程

所以,当我们使用Docker起一个容器的时候,Docker会为每一个容器创建属于他自己的namespaces,即各个维度资源都专属这个容器了,此时的容器就是一个孤岛,也可以说是一个独立VM就诞生了。当然他不是VM,网上关于二者的区别和优劣有一对资料.

更进一步,也可以将多个容器共享一个namespace,比如如果容器共享的是network 类型的namespace,那么这些容器就可以通过 localhost:[端口号]  来通信了。因为此时的两个容器从网络的角度看,和宿主机上的两个内核进程没啥区别。

在下面的详解部分会有试验来验证这个理论

3,kubernetes的pod
       根据前面的描述我们知道,多进程/多容器可以共享namespace,而k8s的pod里就是有多个容器,他的网络实现原理就是先创建一个共享namespace,然后将其他业务容器加入到该namespace中。
       k8s会自动以"合适"的方式为他们创建这个共享namespace,这正是"pause"容器的诞生。

       pause容器:创建的每一个pod都会随之为其创建一个所谓的"父容器"。其主要由两个功能:

  • (主要)负责为pod创建容器共享命名空间,pod中的其他业务容器都将被加入到pause容器的namespace中
  •   (可选) 负责回收其他容器产生的僵尸进程,此时pause容器可以看做是PID为1的init进程,它是所有其他容器(进程)的父进程。但在k8s1.8及以后,该功能缺省是关闭的(可通过配置开启)

         水鬼子:我猜这个功能是利用了共享PID类型的Namespace吧


插播1:Docker和容器的关系
容器:我们前面说了,就是一个具有独立资源空间的Linux进程
Docker:是一个容器引擎,用来创建运行管理容器,即由它负责去和linux 内核打交道,给我们创建出来一个容器来。
容器可以被任何人创建出来,但是现在流行由Docker创建出来的,所以我们总说Docker容器,甚至提到docker就意味着说的是容器TOT

 

Docker容器网络详解


 

 从范围上分:
   单机网络:none,host, bridge
   跨主机网络:overlay,macvlan,flannel等

从生成方式分:
   原生网络:none,host, bridge
   自定义网络:
      使用docker原生实现的驱动自定义的网络:bridge(自定义),overlay,macvlan,
      使用第三方驱动实现的自定义网络:flannel等

在学习网络的时候肯定遇到过关于CNM这个概念,所以首先,我们一起学习下CNM&libnetwork

CNM&libnetwork
       libnetwork是Docker团队将Docker的网络功能从Docker的核心代码中分离出来形成的一个单独的库,libnetwork通过插件的形式为Docker提供网络功能。基于代码层面再升华一下,可以将docker的网络抽象出一个模型来,就叫CNM(Container Networking Model),该模型包含三大块:

  • Sandbox:容器的网络栈,包含interface,路由表,DNS设置等,可以看做就是linux network类型的namespace本身,该有的网络方面的东西都要有,另外还包含一些用于连接各种网络的endpoint
  • Endpoint : 用来将sandbox接入到network中。典型的实现是Veth pair技术(Veth pair是Linux固有的,是一个成对的接口,用来做连接用)
  • Network : 具体的网络实现,比如是brige,VLAN等,同样它包含了很多endpoint(那一头)

      一句话:sandbox代表容器,network代表容器外的网络驱动形成的网络,endpoint连接了二者

       另外,CMN还提供了2个可插拔的接口,让用户可以自己实现驱动然后接入该接口,支持驱动有两类:网络驱动和IPAM驱动,看看这俩类驱动干什么的?

  • Network Drivers: 即真正的网络实现,可以为Docker Engine或其他类型的集群网络同时提供多种驱动,但是每一个具体的网络只能实例化一个网络驱动。细分为本地网络驱动和远端网络驱动:   

          - 本地网络驱动:对应前面说到的原生网络
          - 远端网络驱动:对应前面说的自定义网络

  • IPAM Drivers — 构建docker网络的时候,每个docker容器如果不手动指定的话是会被分配ip地址的,这个分配的任务就是由该驱动完成的,同样的,Docker Engine还是给我们提供了缺省的实现。

 

整个的原理模型图如下,参见官网:

参考:https://success.docker.com/article/networking
(一定要好好看看这篇文章,我英文不行看了整整2天,很有收获)
 

好了,收,开始真正进入docker网络的学习,我们挑2个代表性的网络一起研究下

 

单机网络---brige类型的网络

原理如下图(

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值