k8s 网络基础

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s 网络基础相关的知识,希望对你有一定的参考价值。

参考技术A

author:sufei
说明:本文主要记录在学习k8s网络方面的相关知识

 Linux在内核网络栈中引入网络命名空间,将 独立的网络协议栈隔离 到不同的命令空间中,彼此间无法通信;

1、Linux操作系统,解析和封装网络包是通过一个网络协议栈完成,下层为上层服务,这个 协议栈中即包括如软件也包括硬件网络设 备。网络命名空间就是以软件方式隔离出单独的网络栈信息;

2、不同network namespace的软硬件资源相互不可见,好像处在物理隔离的不同物理机上一样,彼此隔离;

3、不同的网络命名空间会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源

4、实验:可以借助 ip netns 命令来完成对 Network Namespace 的各种操作,如:

问题 :什么是转移设备?

 可以在不同的 Network Namespace 之间转移设备(如veth)。由于一个设备只能属于一个 Network Namespace ,所以转移后在这个 Network Namespace 内就看不到这个设备了。 veth设备属于可转移设备 ,而很多其它设备(如lo、bridge等)是不可以转移的。

 veth pair 全称是 Virtual Ethernet Pair,是一个成对的端口,所有从这对端口一 端进入的数据包都将从另一端出来,反之也是一样。而veth pair就是为了在不同的 Network Namespace 直接进行通信,利用它可以直接将两个 Network Namespace 连接起来。

实验

 veth pair打破了 Network Namespace 的限制,实现了不同 Network Namespace 之间的通信。但veth pair有一个明显的缺陷,就是只能实现两个网络接口之间的通信。如果我们想实现多个网络接口之间的通信,就可以使用下面介绍的网桥(Bridge)技术( 类似于物理交换机 )。
 简单来说,网桥就是把一台机器上的若干个网络接口“连接”起来。其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去。以使得网口之间的报文能够互相转发。

 网桥是一个二层网络设备,通过网桥可以将linux支持的不同的端口连接起来,并实现类似交换机那样的多对多的通信。

实验:

 Netfilter负责在内核中执行各种挂接的规则(过滤、修改、丢弃等),运行在内核 模式中;Iptables模式是在用户模式下运行的进程,负责协助维护内核中Netfilter的各种规则表;通过二者的配合来实现整个Linux网络协议栈中灵活的数据包处理机制。

 iptables/netfilter(简称iptables)组成了Linux平台下的包过滤防火墙,可以完成封包过滤、封包重定向和网络地址转换(NAT)等功能。这部分主要了解两部分知识:

 应用层不管是要发送还是接收网络消息,都需要通过linux内核提供的一系列关卡。每个”关卡“担负着不同的工作。这里的”关卡“被称为”链“。如下图:

 Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关(如上面的172.17.0.1)。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

 Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

 下面具体来说说docker容器的几种网络模式,以便后续学习k8s网络。

 在host模式下( –net=host),容器不会去建立新的网络命名空间,而直接使用宿主机的网络设备以及网络协议栈。这样自然不会虚拟出自己的网卡,配置自己的IP等。其特点如下:

 这个模式就是在创建容器时,指定网络(–net=container:NAME_or_ID)与之前容器在同一个网络命名空间中,而不是和宿主机共享(这也就是k8s中pod内各容器的一种网络模式)。下面说明几点:

 none模式(–net=none)Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

 bridge模式是docker容器的默认模式,当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器在bridge模式下会连接到这个虚拟网桥上,并由网桥自动分配ip。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

 下面说明这个模式下的工作方式:

 首先我们来看看k8s想要一个什么样的网络,也就是k8s网络设计的要求,具体如下:

 下面简单从几中不同的通信要求来看看k8s网络实现。

 在 Kubernetes 的世界里,IP 是以 Pod 为单位进行分配的。一个 Pod 内部的所有容器共享一个网络堆栈。实际上就是docker container网络模式。可以直接通过本地localhost进行网络访问。这个模式在mysql容器化中就是agent容器与mysql容器的网络通信方式。

 Pod1和Pod2都是通信veth pair连接到同一个docker0网桥上,它们的IP地址都是从docker0网段上动态获取的,它们和网桥本身的IP是同一个网段的。可以通过docker0作为交换机进行通信,也就是采用的docker bridge网络模式进行通信。

 由于在同一个网桥docker0上即可以保证分配的pod IP不会冲突,且可以相互通信,而如果需要跨Node物理节点,则无法通过docker网络直接满足要求了,那这些要求具体有哪些呢?

解决方案

方法一:k8s中通过在etcd中记录正在运行中pod的IP分配信息,这样我们就可以满足Pod IP与Node IP之间映射关系的记录;

方法二:可以在etcd中规划配置好所有主机docker0网桥的子网范围,从而满足Pod IP不冲突的要求;如:

方法三:要实现Pod跨Node通信,以k8s默认网络Flannel为例,就是采用overlay(覆盖网络)实现。具体下面说明:

问题:什么是覆盖网络?

覆盖网络就是应用层网络,是指建立在另一个网络上的网络。怎么理解呢?简单理解就是将TCP数据包装在另一种网络包里面进行路由转发和通信,另一种网络包目前可以是UDP、VxLAN、AWS VPC和GCE路由等数据转发方式。默认以UDP为例来说明flannel工作方式。

下面看看具体实现

问题 :为保证各node内docker容器分配的ip地址不冲突,每个节点上的Docker会使用不同的IP地址段?如何实现的呢?

问题 :为什么在发送节点上的数据会从docker0路由到flannel0虚拟网卡,在目的节点会从flannel0路由到docker0虚拟网卡?

以上是关于k8s 网络基础的主要内容,如果未能解决你的问题,请参考以下文章

[k8s系列六]K8S网络补充之DNS

k8s的Flannel网络

k8s网络之Flannel网络

Linux里面k8s有几种网络模式?

计算机网络-k8s网络

k8s之calico网络