当前位置: 首页 > news >正文

一起误删cni0虚拟网卡引发的k8s事故

起因:

由于生产K8S集群需要踢出一个已存在的节点后重新加入,在清理node节点环境的过程中,误将需要在node节点上执行的删除cni0虚拟网卡的操作在master节点上执行了。由于资源问题,我们的master节点也部署了很多的业务pod。这个操作导致master节点上非hostnetwork的pod的网络通信全部中断。很多业务受到了影响,告警也很及时。

误操作命令:

ip link del cni0

紧急修复:

为了尽快恢复业务,我直接将master节点强制排水了。将节点上的pod驱逐到了其它节点上,使得业务尽快得以恢复。

kubectl drain master01 --ignore-daemonsets --delete-emptydir-data
// 注意排水后,观察pod重调度部署情况。确认所有pod正常启动恢复业务!

后续:

业务是恢复了,但是master节点上的pod网络还是不通的。我想到了两种恢复手段。第一,直接将节点踢出集群,然后重新加入。第二,尝试手工恢复cni0虚拟网卡,将pod网络接回来。第一种简单粗暴些,考虑到重新加入集群执行的脚本中,因为迭代过的原因,可能有些参数或者内核参数变更过。为了避免出现修改影响到master组件。我倾向于尝试第二种方式。

要将pod网络接回来,就要了解K8S flannel组件的通信原理和连接方式。需要理解pod虚拟veth pair对是如何工作的?这里主要涉及flannel的工作原理,网络名称空间的基本机制和操作。

首先,flannel(vxlan模式)的工作原理如下:

如下是pod进出网络流量大致流程:

  • pod中产生数据,根据pod的路由信息,将数据发送到cni0;

  • cni0 根据node节点的路由表,将数据发送到隧道设备flannel.1;

  • flannel.1查看数据包的目的ip,从flanneld获得对端隧道设备的必要信息,封装数据包;

  • flannel.1将数据包发送到对端设备。对端节点的网卡接收到数据包,发现数据包为overlay数据包,解开外层封装,并发送内层封装到flannel.1设备;

  • 数据达到node节点的flannel.1设备查看数据包,根据路由表匹配,将数据发送给cni0设备;

  • cni0匹配路由表,发送数据给网桥上对应的端口。

从通信过程可以知道,pod的网络需要连接到cni0网桥,而cni0和flannel.1网桥之间是没有连接的,通过node节点的路由表来实现转发通信的。所以,这里只需要将node节点所有的pod的网络虚拟对(veth pair)找到,然后将其中一端连接到重新创建的cni0虚拟网桥应该就可以了。变成了如下两个问题:

第一:如何创建cni0网桥并配置正确对应的参数?

由于flannel使用的是vxlan模式,所以创建cni0网桥的时候需要注意mtu值的设置。如下,创建cni0网桥:

// 创建cni0设备,指定类型为网桥
# ip link add cni0 type bridge
# ip link set dev cni0 up
// 为cni0设置ip地址,这个地址是pod的网关地址,需要和flannel.1对应网段
# ifconfig cni0 172.28.0.1/25
// 为cni0设置mtu为1450
# ifconfig cni0 mtu 1450 up


// 查看创建情况
# ifconfig cni0
cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 172.28.0.1  netmask 255.255.255.128  broadcast 172.28.0.127
        ether 0e:5e:b9:62:0d:60  txqueuelen 1000  (Ethernet)
        RX packets 487334  bytes 149990594 (149.9 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 629306  bytes 925100055 (925.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
// 此时查看路由表,也已经有了去往本机pod网段的cni0信息
# route -n | grep cni0
172.28.0.0      0.0.0.0         255.255.255.128 U     0      0        0 cni0

第二:如何准确找出每个pod的对应的veth pair虚拟对,是否和名称空间有关系?

在一台只有两个pod的节点上查看虚拟网卡的情况,发现在node主机上可以看到两个veth前缀的虚拟网卡,它们的另一端在pod中,并且pod的netns也可以通过show命令看到。值得注意的是,在node节点同网络名称空间下的vethf0978d0c和vethb9525687的连接设置master为cni0。所以,找到所有的veth前缀的虚拟网卡,并将其挂载到cni0上即可。

// 这里通过一个简单的脚本批量将veth的虚拟网卡挂载到cni0网桥上
for veth in $(ip addr | grep veth | grep -v master | awk -F'[@|:]' '{print $2}' | sed 's/ //g')
do
 ip link set dev $veth master cni0
done

通过以上两步操作后,失联的pod已经可以ping通,并和其它节点的pod正常通信了。测试新建删除pod都是正常的。

至此,手工恢复cni0算是完成了。如果还有下次 ip link del cni0的操作,可以不做节点排水操作。通过这个方式以最快,影响最小的方式恢复pod网络通信。这里也暴露了一个问题,那就是master节点的操作规范问题,对于生产环境,我们应该尽可能避免直接登录到master节点上进行操作,应该在其它管理机上授权k8s权限去操作。然后master节点尽量和业务分开独立部署,以保证master节点的稳定性。

相关文章:

  • QT软件开发-基于FFMPEG设计录屏与rtsp、rtmp推流软件(支持桌面与摄像头)(四)
  • redux中间件函数
  • 【前端面试知识题】- 4.1 JavaScript
  • 客户端架构
  • iOS Xcode 14 创建新项目Pod init及Pod install 报错
  • 金融行业借力泛微今承达,合同统一数字化管理、风险全过程把控
  • 计算机视觉项目实战-基于特征点匹配的图像拼接
  • 软件过程与建模学习之:Individuals,Motivation and Teams
  • 【某南方·高中梦校面试】
  • 三分钟细数几款可视化前端开发工具
  • 【定制项目】【M15 消防安全宣传】主要模块:视频 + 音频 + 图标 + 问答游戏
  • 计算机毕业设计-基于协同过滤算法的旅游管理系统-基于SSM的旅游定制系统(源码+讲解+文档)
  • 蓝凌OA漏洞分析与处置方案
  • JAVA基础(四十五)——集合之Map接口
  • Python+审计实务与案例分析库 毕业设计-附源码211526
  • Angular 响应式表单 基础例子
  • AngularJS指令开发(1)——参数详解
  • Apache的基本使用
  • es6
  • Github访问慢解决办法
  • GitUp, 你不可错过的秀外慧中的git工具
  • Linux CTF 逆向入门
  • Python_OOP
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 当SetTimeout遇到了字符串
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 小程序测试方案初探
  • 昨天1024程序员节,我故意写了个死循环~
  • ​2020 年大前端技术趋势解读
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (2)Java 简介
  • (6)STL算法之转换
  • (第一天)包装对象、作用域、创建对象
  • (二)Eureka服务搭建,服务注册,服务发现
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (一)VirtualBox安装增强功能
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (转)项目管理杂谈-我所期望的新人
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net和php怎么连接,php和apache之间如何连接
  • .NET下的多线程编程—1-线程机制概述
  • .NET中两种OCR方式对比
  • .net专家(张羿专栏)
  • @Autowired 与@Resource的区别
  • @Transient注解
  • @我的前任是个极品 微博分析
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题
  • [ 网络基础篇 ] MAP 迈普交换机常用命令详解
  • [Flexbox] Using order to rearrange flexbox children
  • [LeetCode] 93. Restore IP Addresses 复原IP地址
  • [LeetCode]—Copy List with Random Pointer 深度复制带“任意指针”的链表