早期AKS的网络模型主要有CNI和kubenet两种, CNI的Pods使用Node节点所在子网的地址空间, 如果Node节点数比较多,需要非常多的虚拟网络地址空间,在一些大型的网络架构中可能是不允许的, kubenet 插件虽然使用了独立的地址空间,但是跨Node的Pod之间的网络通信需要依赖于平台托管的UDR规则, 而CNI Overlay的网络模型正好避免了这两个问题,成为当下用户使用比较多的AKS网络插件模型
Portal创建AKS时选择Azure CNI Overlay,用户可以选择已经存在的虚拟网络或者平台自动创建新的作为Node部署的虚拟网络,如果不使用自定义配置其Pod地址空间默认是10.244.0.0/16 ,虚拟网络的地址空间是10.224.0.0/12
如果使用Azure CLI创建AKS, 需要添加对应的参数来使用Overlay插件:
--network-plugin azure
--network-plugin overlay
另外用户已经在使用的CNI模型的AKS cluster还可以迁移到Overlay模型,不过这个操作后Node和Pod都会经历一次重启和网络初始化的过程:
一个已经创建成功的使用了Overlay插件的AKS集群通过下面三条命令的输出结果,可以看到通过一个名称是Nodenetwork的自定义资源定义(CRD)并注入到API server中,生成了一个新的API资源名称是Nodenetworkconfigs(nnc),应用是部署在kube-system名称空间azure-cns的Pod中,每个节点运行一个, 主要是用来初始化Pod的网络配置,如果这几个Pod的状态Not ready, 其它的Pod也将无法获取到IP地址。
用的比较多的在Node上抓包的方法是通过debug shell,这种方式通过创建使用了Host网络的Pod,可以直接通过Pod上运行抓包命令,相关的官网文档: https://docs.azure.cn/zh-cn/aks/node-access
但有些场景下,由于一些网络限制, debug shell Pod无法正常创建,这时候需要去通过直接登录Node抓包. 我们可以把Node看作为虚拟网络中部署的虚拟机, 可以在Node节点的虚拟网络中创建一台虚拟机或者使用peering网络的虚拟机作为跳板登录Node节点,具体步骤如下:
首先,我们一般需要重置Node节点的登录密码或者秘钥(默认登录Node的用户名和密码都是创建的过程中自动生成的),为了安全起见,我们就以秘钥的方式登录Node节点.
通过Node节点名称在Azure portal上找到对应的VMSS,输入用户自定义的秘钥名称后,点击update,会下载名称是aks.pem的私钥到本地:
接下来需要选中其中一个Node节点,将实例升级到最新模型以应用新生成的秘钥配置,此操作会导致选中的Node重启,为了减少影响,所以只升级其中一个Node用于登录:
然后在跳板机上通过VMSS的实例私有IP,通过-i选项指定从portal下载的私钥登录Node 并sudo su – 切到超户权限进行后续的操作:
这时候我们就可以使用tcpdump在AKS的Node上抓包了. 如果默认镜像是Ubuntu的Node节点已经预装了这个命令,如果使用了Azure Linux的节点需要使用tnf install tcpdump 安装
1) 通过ip addr 命令查看Node关联的所有网卡名称:
2) 可以通过tcpdump -i any -n 实时的抓取所有网卡的数据包:
3) 但这种方式抓的包会特别多,不容易进一步分析,大部分时候需要抓取某一个Pod的,但如何得知这个Pod的网卡在Node的名称是什么呢?可以参考下面的思路:
A:首先我们可以通过下面两条命令获取要抓包其中一个Pod的eth0的index 和link number(如下图 45和46):
B:然后在Node上通过 ip addr 命令找到link 45和index 46的接口, tcpdump命令-i的参数的值是这个接口名称@前的部分。
4) 对于系统内没有内置cat命令的Pod,可以使用下面的方法:
在Node上运行crictl ps-l命令查看容器的ID,然后找到容器运行的Pid,并使用nsenter 命令进入这个容器的Net名称空间,这时候就可以运行抓包命令, 这时候抓的是这个Pod的流量。
5) 如下是一些场景中可能会用到的抓包方法
A: #抓包前进行长ping某个IP的端口(paping命令需要安装)
nohup paping 8.8.8.8 -p 53 | while read ping; do echo "$(date); $ping" >> /mnt/paping.txt ; done &
B: #长时间抓包,每个包的大小1M进行轮询并保存在/mnt目录下
nohup tcpdump -i any -C 1 -w /mnt/aks.cap -Z root &
C: #通过脚本抓取指定开始结束时间的所有的访问某个端口的包并保持在/mnt下
#!/bin/bash
StartTime="xx:xx" #define the start time when the capture command will be running,for instance : 12:00
EndTime="xx:xx" # define the stop time
PORT=" " # define the port, which is a port filter for tcpdump
PS=" " #define packet size (The units of file size are millions of bytes (1,000,000 bytes)
PacketsName=" " #define packets name
while [ "$(date +%H:%M)" != "$StartTime" ]; do
sleep 10
done
tcpdump -i any -Z root tcp port $PROT -C $PS -w /mnt/$PacketsName.cap &
TCPDUMP_PID=$!
while [ "$(date +%H:%M)" != "$EndTime" ]; do
sleep 60
done
kill -INT $TCPDUMP_PID

