环境
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04 LTS
Release: 24.04
Codename: noble
先说原理
- iptables 如果服务过多 或者pod 过多 就要则添加海量的iptabes规则
- iptables 使用的具体算法主要是线性搜索,也可以称为顺序搜索或顺序匹配算法
- 逐条匹配如果海量增加,查找效率大幅度下降
- 但是如果采用 ip_set 作为一个hash表 使用 目标 IP-目标端口-源 IP 可以位置确定唯一一个路由
- 在使用ipvs vip路由到真实的 real ip pod上 效率大幅度提升
开始实验 模拟两个pod 服务

- 添加三个网络命名空间 网桥、pod-x、pod-y
ip link add dev bridge_home type bridge
ip netns add netns_pod_x
ip netns add netns_pod_y
mkdir -p /etc/netns/netns_pod_x && echo "nameserver 114.114.114.114" | tee -a /etc/netns/netns_pod_x/resolv.conf
mkdir -p /etc/netns/netns_pod_y && echo "nameserver 114.114.114.114" | tee -a /etc/netns/netns_pod_y/resolv.conf
ip netns exec netns_pod_x ip link set dev lo up
ip netns exec netns_pod_y ip link set dev lo up
ip address add 10.0.0.1/24 dev bridge_home
ip link add dev veth_pod_x type veth peer name veth_ns_pod_x
ip link add dev veth_pod_y type veth peer name veth_ns_pod_y
- 虚拟网口对端加入pod-x、pod-y所在命名空间
ip link set dev veth_ns_pod_x netns netns_pod_x
ip link set dev veth_ns_pod_y netns netns_pod_y
ip link set dev veth_pod_x master bridge_home
ip link set dev veth_pod_y master bridge_home
ip link set dev veth_pod_x up
ip link set dev veth_pod_y up
ip netns exec netns_pod_x ip link set dev veth_ns_pod_x up
ip netns exec netns_pod_y ip link set dev veth_ns_pod_y up
ip netns exec netns_pod_x ip address add 10.0.0.11/24 dev veth_ns_pod_x
ip netns exec netns_pod_y ip address add 10.0.0.21/24 dev veth_ns_pod_y
ip link set bridge_home up
ip netns exec netns_pod_x ip route add default via 10.0.0.1
ip netns exec netns_pod_y ip route add default via 10.0.0.1
- 允许通过 在过滤器表(filter table)中,数据包转发(FORWARD)时可以进出进入桥接设备
iptables --table filter --append FORWARD --in-interface bridge_home --jump ACCEPT
iptables --table filter --append FORWARD --out-interface bridge_home --jump ACCEPT
- 将源地址10.0.0.0/24进行伪装 ,在NAT 表中,添加此规则规则
iptables --table nat --append POSTROUTING --source 10.0.0.0/24 --jump MASQUERADE
- 开启两个终端,前台模式模拟 pod-x、pod-y的服务 服务运行时不要关闭终端
ip netns exec netns_pod_x python3 -m http.server 8080
ip netns exec netns_pod_y python3 -m http.server 8080
测试宿主机 、 pod-x、pod-y命名空间测试 pod-x、pod-y上的模拟服务
curl 10.0.0.11:8080
curl 10.0.0.21:8080
ip netns exec netns_pod_x curl 10.0.0.21:8080
ip netns exec netns_pod_y curl 10.0.0.11:8080
主角登场 ipvs
apt install ipset ipvsadm bridge-utils --yes
ipvsadm --add-service --tcp-service 10.100.100.100:8080 --scheduler rr
ipvsadm --add-server --tcp-service 10.100.100.100:8080 --real-server 10.0.0.11:8080 --masquerading
curl 10.100.100.100:8080
- 模拟 pod-y 内部的受限制的命名空间内访问模拟服务 fail...
ip netns exec netns_pod_y curl 10.100.100.100:8080
pod 内无法访问其他服务 处理办法 一 虚拟网络接口Hairpin模式
- 创建虚拟dummy 接口,它提供路由数据包的功能不提供转发功能
ip link add dev dustin-ipvs0 type dummy
ip addr add 10.100.100.100/32 dev dustin-ipvs0
modprobe br_netfilter && sysctl --write net.bridge.bridge-nf-call-iptables=1
ip netns exec netns_pod_y curl 10.100.100.100:8080
ip netns exec netns_pod_x curl 10.100.100.100:8080
- 失败原因 因为网络 pod_x、 pod_y 、bridge_home 之间是二层转发 相同网段的直接走二层
- ipvs 通过iptables转发时,iptables是三层 、所以开启混杂模式、无论什么数据包都转发、不验证MAC地址
sysctl --write net.ipv4.vs.conntrack=1
ip link set bridge_home promisc on
brctl hairpin bridge_home veth_dustin off
ip netns exec netns_pod_x curl 10.100.100.100:8080
pod 内无法访问其他服务 处理办法 二 开启网桥混杂模式
- 每次都使用pod 一个 iptables 规则做对源地址做NAT 显然是不可以接受的
- 同样每次对网口使用hairpin 也是不合适的
- 使用 ipset
ipset create DUSTIN-LOOP-BACK hash:ip,port,ip
iptables --table nat --append POSTROUTING --match set --match-set DUSTIN-LOOP-BACK dst,dst,src --jump MASQUERADE
ipset add DUSTIN-LOOP-BACK 10.0.0.11,tcp:8080,10.0.0.11
curl 10.100.100.100:8080
ip netns exec netns_pod_x curl 10.100.100.100:8080
ip netns exec netns_pod_y curl 10.100.100.100:8080
后续其他pod 只需添加 ipvs 和ipset 即可
ipvsadm --add-server --tcp-service 10.100.100.100:8080 --real-server 10.0.0.21:8080 --masquerading
ipset add DUSTIN-LOOP-BACK 10.0.0.21,tcp:8080,10.0.0.21
查看ipvs转发策略
