K8s 网络(笔记) 电脑版发表于:2020/7/14 17:13  >#K8s 网络(笔记) [TOC] <br/> K8s 网络 ------------ - Docker容器网络回顾 - K8s CNI - Flannel 网络插件跨node的 pod to pod - Cluster Service是什么? - Kube Proxy起了什么作用 Docker 容器的网络模型 ------------ tn>Docker 容器网络的原始模型主要有三种:Bridge(桥接)、Host(主机)以及Container(容器)。 <br/> >### Host(主机) tn>设置容器共享使用节点主机的网络命名空间。 (网络命名空间 是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中。) >### Bridge(桥接) tn>Bridge 是借助于虚拟网桥设备建立的容器网络连接 (是一个虚拟网络设备,所以具有网络设备的特征,可以配置IP,MAC地址等;其次,bridge是一个虚拟交换机,和物理交换机有类似的功能。) >### Container(容器) tn>多个容器共享同一个网络名称空间,从而彼此之间能够以本地通信的方式建立连接 <br/> tn>在Docker守护进程首次启动时,它会在当前节点上创建一个名为`docker0`的桥设备,并默认配置其使用 `172.17.0.0/16` 网络,该网络是 `Bridge` 模型的一种实现,也是创建 Docker 容器时默认使用的网络模型。 >### veth-pair (网络对) tn> veth-pair 一个设备收到协议栈的数据发送请求后,会将数据发送到另外一个设备上去。一端挂在docker()上,另一端挂在容器上。相当于电灯(主机)与插座(容器)之间的电线。 安装网桥管理工具 ------------ ```bash yum install bridge-utils yum install tcpdump ``` 动手实践网络命名空间 ------------ >创建网络namespace ```bash ip netns add ns2 ``` >创建一对veth pair ```bash ip link add A type veth peer name B ``` >添加到docker0 bridge ```bash brctl addif docker0 A ``` >启用A veth ```bash ip link set A up ``` >将B接口放到ns2 ```bash ip link set B netns ns2 ``` >命名为eth0 ```bash ip link exec ns2 ip link set dev B name eth0 ``` >开启接口2 ```bash ip netns exec ns2 ip link set eth0 up ``` >配置一个可用ip ```bash ip netns exec ns2 ip addr add 172.17.0.5/16 dev eth0 ``` >配置默认网关 ```bash ip netns exec ns2 ip route add default via 172.17.0.1 ``` >在某个命名空间下执行命令 ```bash ip netns exec ns2 ifconfig ``` >在两个容器内分别查看他们的ifindex ```bash cat /sys/class/net/eth0/ifindex ``` >对veth 进行网络抓包 ```bash tcpdump -nnt -i veth645cee7 ``` Netfilter & iptables ------------ tn>为了更好地理解K8S中的Service,需要理解Linux网络中的IpTables和 Netfilter <br/> Netfilter-iptables由两部分组成,一部分是Netfilter的"钩子",另一部分则是知道这些钩子函数如何工作的一套规则--这些规则存储在被称为iptables的数据结构之中。钩子函数通过访问iptables来判断应该返回什么值给Netfilter框架。 <br/> iptables命令 是netfilter项目的一部分。通过iptables命令配置,内核空间的netfilter来执行对网络的响应/处理/转发等处理。 <br/> Netfilter是在Linux内核中的一个软件框架,用于管理网络数据包。不仅具有网络地址转换的功能,也具备数据包内容修改、以及数据包过滤等防火墙功能。 iptables命令 https://wangchujiang.com/linux-command/c/iptables.html iptables图文详解 https://www.ylkb.net/2017/intro-iptables.html https://www.zsythink.net/archives/1199 深入理解netfilter and iptables https://arthurchiao.github.io/blog/deep-dive-into-iptables-and-netfilter-arch-zh/ Kube-proxy(userspace) ------------  tn>`kube-proxy`会监控`apiserver`修改的`Pod`的IP变化,然后 `kube-proxy` 会把新的地址更新到应用中。所有访问 `VIP` 的网络在 `iptables`的影响下,直接路由到 `kube-proxy`,再由 `kube-proxy` 把请求转发到不同的 `Pod` 下进行处理。 Kube-proxy(iptables) ------------  tn>`kube-proxy`这里相当于异步了,起到监控 `apiserver` 修改的`Pod`的IP变化以及更新到 `iptables` 的作用。当客户端访问 `vIP` 时,`iptables` 可以检测到您的网络包,然后通过`Service`直接转发到随机的`Pod`下面进行处理。虽然通过各个node节点上的iptables规则来实现service的负载均衡,但是随着 `service` 数量的增大,`iptables` 模式由于线性查找匹配、全量更新等特点,其性能会显著下降。性能对比如下:  Kube-proxy(ipvs) ------------ tn> `kube-proxy` 的用法是一种 <font style="color:red">0(n)</font> 算法,其中的 **n** 随集群规模同步增长,这里的集群规模,更明确的说就是服务和后端 `Pod` 的数量。 <br/> tn> `IPVS` 模式下, `kube-proxy` 使用 `IPVS` 负载均衡代替了 `iptable`。这种模式同样有效,`IPVS` 的设计就是用来为大量服务进行负载均衡的,它有一套优化过的 `API`,使用优化的查找算法,而不是简单的从列表中查找规则。 `kube-proxy` 在 `IPVS` 模式下,其连接过程的复杂度为 <font style="color:red">0(1)。</font>其中算法包括了: **1.轮询** **2.最小连接数** **3.源哈希** **4.目标哈希** **5.最小延迟** 从下面来看,随着服务的数量越多,平均响应时间的就越来越突出,在到 `10000` 个服务数量的时候 `IPVS` 比 `iptables` 相应时间上快了**一半**  Service DNS ------------