恢弘志士之气,不宜妄自菲薄。这篇文章主要讲述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/??
- ipset是iptables的扩展,可以让你添加规则来匹配地址集合。不同于常规的iptables链是线性的存储和遍历,ipset是用索引数据结构存储,甚至对于大型集合,查询效率非常都优秀。
- IPVS基本上是一种高效的Layer-4交换机,它提供负载平衡的功能。Ipvs具体实现是由ipvsadm这个程序来完成,因此判断一个系统是否具备ipvs功能,只需要察看ipvsadm 程序是否被安装。
sudo apt install ipset ipvsadm --yes
- 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
- 命令: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 伪装等功能。
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!
- 为什么 kubernetes 环境要求开启 bridge-nf-call-iptables
【k8s-docker操作笔记3】??https://imroc.cc/k8s/faq/volume-permission-denied/??
- 为什么k8s iptables模式下不使用ipset呢?因为 iptables 属于 “过气” 的技术,需要和它划清界限,甚至连 IPVS 现在也属于 “过气” 的技术了,eBPF 当道!
推荐阅读
- #yyds干货盘点# linux实现pxe自动装机 理论方法
- #2021年底大盘点#内核态和用户态
- 对象存储MinIO的简介与部署
- K8SService
- #yyds干货盘点#启动流程和grub故障排错
- #yyds干货盘点#Windows Server之AD组策略介绍
- echo的使用和{}的替换结构
- 如何在 Linux 中使用 apt 命令管理包
- #yyds干货盘点#Golang 切片(slice)扩容机制源码剖析