关于tc的介绍可看上篇:看图理解linux内核网络流量控制工具tc(Traffic Control)
该实验是我们为了验证能否使用tc来实现某个功能的。
在k8s集群中,验证在一个demoset的pod中,是否能使用tc来拦截部署在同node上的其它pod的流量?
写一个demeset部署我们用来执行tc命令的pod
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ubuntu-daemonset
spec:
selector:
matchLabels:
app: ubuntu-daemonset
template:
metadata:
labels:
app: ubuntu-daemonset
spec:
hostNetwork: true
containers:
- name: ubuntu
image: public.ecr.aws/ubuntu/ubuntu:24.10
command: ["sleep", "infinity"]
securityContext:
privileged: true # 添加这行来启用特权模式
需要注意的地方:
- 需要使用特权模式启动容器,否则没有权限执行tc命令。
- 需要让Pod共用宿主机Node的网络接口,这样才能拦截到Node上其它Pod的网络流量。
如果集群有多个Node会部署多个Pod,选择其中一个Pod进入shell,然后添加qdsic和filter+action。
如果容器没有tc命令,则需要安装:
apt-get update
apt-get install -y iproute2
我们还需要知道node的网络设备接口,如果ifconfig命令找不到则需要安装:
apt-get update
apt-get install -y net-tools
添加qdsic和filter+action。
tc qdisc add dev eth0 root handle 1: htb
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip src 10.156.6.100/32 match ip dst 10.194.0.2/32 action drop
- 这里src ip就是我们拦截的目标pod的ip
- dst ip就是流量出口目标ip,是一个nfs服务
如果执行tc qdisc add
失败:Error: NLM_F_REPLACE needed to override.
,意思是尝试添加的队列规则(qdisc)已经存在,但可以覆盖替换。
可以查看已经存在的qdisc是不是htb的,如果是可以直接用。
root@/# tc qdisc show dev eth0
qdisc mq 8004: root
如果不是则需要替换:
tc qdisc replace dev eth0 root handle 1: htb
结论是,这个方法可行。
顺便分享一下我们的调研结论:其实我们是想通过这个方式去拦截nfs文件读写,阻止某个pod去读写某个nfs文件系统。但由于pv是由csi驱动的node组件这个pod挂载的,只有这个pod安装了nfs的client,能够与nfs文件系统交互,然后node组件是将这个目录挂载到应用pod的挂载点而已,实际我们在应用pod往磁盘写数据,最终网络上是通过csi这个node组件的nfs client去写到nfs文件系统的。所以我们无法拦截应用Pod,只能拦截csi node组件的pod。
为了验证这个结论,我把csi驱动(我们自己实现的csi驱动)卸载后,所有挂盘的Pod写操作都卡住了。