k8s-docker操作笔记3

Posted 技术支持department

tags:

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

参考文档:

​https://dustinspecker.com/​

​https://dustinspecker.com/posts/ipvs-how-kubernetes-services-direct-traffic-to-pods/​

​https://kubernetes.io/blog/2018/07/09/ipvs-based-in-cluster-load-balancing-deep-dive/​

  1. ipset是iptables的扩展,可以让你添加规则来匹配地址集合。不同于常规的iptables链是线性的存储和遍历,ipset是用索引数据结构存储,甚至对于大型集合,查询效率非常都优秀。

IP sets are a framework inside the Linux kernel, which can be administered by the ​​ipset utility. Depending on the type, an IP set may store IP addresses, networks, (TCP/UDP) port numbers, MAC addresses, interface names or combinations of them in a way, which ensures lightning speed when matching an entry against a set。​

  1. IPVS基本上是一种高效的Layer-4交换机,它提供负载平衡的功能。Ipvs具体实现是由ipvsadm这个程序来完成,因此判断一个系统是否具备ipvs功能,只需要察看ipvsadm 程序是否被安装。
sudo apt install ipset ipvsadm --yes
  1. using IPVS by first creating a virtual service;​rr​ for round-robin is chosen, which is the default scheduler kube-proxy uses。
sudo ipvsadm \\
--add-service \\
--tcp-service 10.100.100.100:8080 \\
--scheduler rr
  1. 命令:IPVS to direct TCP requests for ​10.100.100.100:8080​ to ​10.0.0.11:8080​​(By not specifying ​--masquerading​, IPVS attempts to use routing to direct the traffic, which will fail)由于 IPVS 未实现 ​​POST_ROUTING​​​ Hook 点,所以它需要 iptables 配合完成 IP 伪装等功能。k8s-docker操作笔记3_协议栈
sudo ipvsadm \\
--add-server \\
--tcp-service 10.100.100.100:8080 \\
--real-server 10.0.0.11:8080 \\
--masquerading
curl 10.100.100.100:8080 //ok
sudo ip netns exec netns_leah curl 10.100.100.100:8080 //no-ok

Netfilter 是一个基于用户自定义的 Hook 实现多种网络操作的 Linux 内核框架。Netfilter 支持多种网络操作,比如包过滤、网络地址转换、端口转换等,以此实现包转发或禁止包转发至敏感网络。

针对 Linux 内核 2.6 及以上版本,Netfilter 框架实现了 5 个拦截和处理数据的系统调用接口,它允许内核模块注册内核网络协议栈的回调功能,这些功能调用的具体规则通常由 Netfilter 插件定义,常用的插件包括 iptables、IPVS 等,不同插件实现的 Hook 点(拦截点)可能不同。另外,不同插件注册进内核时需要设置不同的优先级,例如默认配置下,当某个 Hook 点同时存在 iptables 和 IPVS 规则时,iptables 会被优先处理。

Netfilter 提供了 5 个 Hook 点,系统内核协议栈在处理数据包时,每到达一个 Hook 点,都会调用内核模块中定义的处理函数。调用哪个处理函数取决于数据包的转发方向,进站流量和出站流量触发的 Hook 点是不一样的。

内核协议栈中预定义的回调函数有如下五个:

NF_IP_PRE_ROUTING: 接收的数据包进入协议栈后立即触发此回调函数,该动作发生在对数据包进行路由判断(将包发往哪里)之前。

NF_IP_LOCAL_IN: 接收的数据包经过路由判断后,如果目标地址在本机上,则将触发此回调函数。

NF_IP_FORWARD: 接收的数据包经过路由判断后,如果目标地址在其他机器上,则将触发此回调函数。

NF_IP_LOCAL_OUT: 本机产生的准备发送的数据包,在进入协议栈后立即触发此回调函数。

NF_IP_POST_ROUTING: 本机产生的准备发送的数据包或者经由本机转发的数据包,在经过路由判断之后,将触发此回调函数。

iptables 实现了所有的 Hook 点,而 IPVS 只实现了 LOCAL_IN、LOCAL_OUT、FORWARD 这三个 Hook 点。既然没有实现 PRE_ROUTING,就不会在进入 LOCAL_IN 之前进行地址转换,那么数据包经过路由判断后,会进入 LOCAL_IN Hook 点,IPVS 回调函数如果发现目标 IP 地址不属于该节点,就会将数据包丢弃。

如果将目标 IP 分配给了虚拟网络接口,内核在处理数据包时,会发现该目标 IP 地址属于该节点,于是可以继续处理数据包。

——启用 bridge-nf-call-iptables 这个内核参数 (置为 1),表示 bridge 设备在二层转发时也去调用 iptables 配置的三层规则 (包含 conntrack),(网桥是虚拟的二层设备,同节点的 Pod 之间通信直接走二层转发,导致没有调用 conntrack,回包时没有原路返回),开启这个参数就能够解决上述 Service 同节点通信问题。

sudo ip link add dev dustin-ipvs0 type dummy
sudo ip addr add 10.100.100.100/32 dev dustin-ipvs0
sudo modprobe br_netfilter
sudo sysctl --write net.bridge.bridge-nf-call-iptables=1
sudo ip netns exec netns_leah curl 10.100.100.100:8080 //ok
--------
sudo ip netns exec netns_dustin curl 10.100.100.100:8080 //nok
//有一个办法可以不用配置每个 veth 接口,那就是开启网桥的混杂模式
sudo ip link set bridge_home promisc on
//启用混杂模式后为什么还是不能解决这个问题,因为混杂模式和下面的选项要一起启用才能对 IPVS 生效
sudo sysctl --write net.ipv4.vs.conntrack=1
sudo ip netns exec netns_dustin curl 10.100.100.100:8080 //ok

IPVS 及其负载均衡算法只针对首个数据包,后继的包必须被 conntrack 表优先反转,如果没有 conntrack,IPVS 对于回来的包是没有任何办法的。可以通过 conntrack -L 查看.

什么是混杂模式呢?普通模式下网卡只接收发给本机的包(包括广播包)传递给上层程序,其它的包一律丢弃。混杂模式就是接收所有经过网卡的数据包,包括不是发给本机的包,即不验证MAC地址

ipset is not specific to IPVS. We can leverage ipset with just iptables and some CNI plugins like Calico do!

  1. 为什么 kubernetes 环境要求开启 bridge-nf-call-iptables

​https://imroc.cc/post/202105/why-enable-bridge-nf-call-iptables/​​

https://imroc.cc/k8s/faq/volume-permission-denied/

  1. 为什么k8s iptables模式下不使用ipset呢?因为 iptables 属于 “过气” 的技术,需要和它划清界限,甚至连 IPVS 现在也属于 “过气” 的技术了,eBPF 当道!

以上是关于k8s-docker操作笔记3的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记:python3,代码片段(2017)

操作栏标签片段中的片段?

Oracle-常用数据库对象笔记(片段)

VSCode自定义代码片段——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程