【NPU】Ascend Device Plugin 超深度源码分析 — Part 3 设备管理基类 + 910设备管理器 + 热重置容错引擎之一
·
Ascend Device Plugin 超深度源码分析 — Part 3
设备管理基类 + 910设备管理器 + 热重置容错引擎
分析文件清单
序号 文件 行数 核心职责 1 pkg/device/ascendcommon.go~1823 AscendTools 基类:所有NPU设备管理的公共能力层 2 pkg/device/ascend910.go~2223 HwAscend910Manager:910系列设备的设备发现、健康监测、热重置容错 3 pkg/device/ascendtolerance.go~996 HotResetTools:热重置管理器实现,CM同步、任务级容错策略 4 pkg/device/ascendcommon_v2.go~56 A5超节点扩展属性 getter/setter
目录
一、模块定位
1.1 业务职责
这四个文件共同构成了 Ascend NPU Device Plugin 的设备管理层核心引擎,负责在 Kubernetes 集群中管理华为昇腾910系列NPU设备的完整生命周期。
| 模块 | 业务职责 |
|---|---|
| AscendTools (ascendcommon.go) | 所有NPU设备管理的公共基类:设备发现、健康状态判定、故障码处理、设备IP获取、Pod注解校正、设备信息ConfigMap管理、K8s事件写入、虚拟设备管理、手动隔离NPU处理、升级故障原因缓存 |
| HwAscend910Manager (ascend910.go) | 910系列设备专用管理器:NPU发现(物理/虚拟/共享)、Volcano调度ListAndWatch、优雅容错(在线热重置/离线热重置/隔离)、Ring级别设备重置、A3卡关联设备重置、带外重置(OutBand Reset)、设备信息CM更新、网络健康检测、DPU故障管理 |
| HotResetTools (ascendtolerance.go) | 热重置容错引擎:全局设备故障缓存管理、任务级故障策略决策(L2/L3/L5分级)、Reset CM同步与文件落盘、Pod/CM事件驱动处理、故障设备-Pod映射、任务/设备重置状态管理 |
| ascendcommon_v2.go | A5超节点属性扩展:SuperPodType/Size、NodeInternalIP、RackID 的 getter/setter |
1.2 系统位置
1.3 支持的设备类型
二、模块整体结构
2.1 类结构与接口定义
2.1.1 核心类图
2.1.2 包级全局变量
2.1.3 故障策略级别映射表
2.2 核心方法清单
2.2.1 AscendTools 基类方法
| 方法 | 作用 | 调用者 |
|---|---|---|
SetDmgr/GetDmgr | 设备管理器接口注入/获取 | 外部初始化 |
SetKubeClient/GetKubeClient | K8s客户端注入/获取 | 外部初始化 |
GetChipAICore | 获取AI Core数量 | 外部 |
GetName | 获取设备名称(如"Ascend910") | 多处 |
convertLogicIDsToDeviceNames | LogicID列表→设备名字符串 | handleManuallySeparateNPU |
handleManuallySeparateNPUFaultInfo | 处理手动隔离NPU故障信息 | UpdateNodeDeviceInfo |
LoadDeviceInfoCm | 从DeviceInfo CM加载缓存 | 外部初始化 |
asyncReleaseAutoFill | 异步释放自动填充故障 | LoadDeviceInfoCm |
UpdateNodeDeviceInfo | 更新节点设备信息到CM | 910/310P ListAndWatch |
writeDeviceInfoCm | 写设备信息到CM缓存 | UpdateNodeDeviceInfo |
getNodeDeviceInfoCache | 构建节点设备信息缓存结构 | writeDeviceInfoCm |
updateLastInfo | 更新上次信息快照 | writeDeviceInfoCm |
checkAndInitNodeDeviceInfo | 初始化设备信息缓存 | UpdateNodeDeviceInfo |
compareDeviceList | 比较设备列表(忽略fault_time) | UpdateNodeDeviceInfo |
delVirDevInfo | 删除虚拟设备信息 | UpdateNodeDeviceInfo |
assembleNpuDeviceStruct | 组装NpuDevice结构体 | assemblePhy/Virtual/ShareDevices |
assemblePhyDevices | 组装物理设备 | GetNPUs |
assembleVirtualDevices | 组装虚拟设备(vNPU) | GetNPUs |
assembleSpecVirtualDevice | 组装特定虚拟设备规格 | assembleVirtualDevices |
assemble310PMixedPhyDevices | 310P混合物理设备组装 | 310P GetNPUs |
removeDuplicate | 设备类型去重 | GetNPUs |
getResetInfoData | 从CM解析重置信息 | isTaskInReset等 |
getRealUsedDevices | 获取实际使用中的设备 | getDevStatesDevSet |
filterSoftShareDevices | 过滤软共享可用设备 | getDevStatesDevSet |
getDevStatesDevSet | 获取设备状态集合 | DoWithVolcanoListAndWatch |
getUsedDevices | 获取kubelet已分配设备 | getDevStatesDevSet |
groupDevsByStatus | 按健康状态分组设备 | getDevStatesDevSet |
getFaultTimeAndLevelMap | 构建故障时间-级别映射 | getDeviceFaultsWithMode |
combineFaultTimeMaps | 合并故障时间映射 | - |
getDpuFaults | 获取DPU子健康故障 | getDeviceFaults |
getDeviceFaults | 获取设备故障列表(芯片+网络) | groupDevsByStatus |
getDeviceFaultsWithMode | 按故障模式获取故障详情 | getDeviceFaults |
removeDuplicateErr | 故障码去重 | getDeviceFaultsWithMode |
getDavinCiDev | 获取DaVinci设备信息 | GetNPUs |
getVirtualDevice | 获取虚拟设备信息 | GetNPUs |
GetDeviceIP | 获取设备IP(支持v4/v6) | 多处 |
getDcmiDeviceIP | DCMI接口获取设备IP | GetDeviceIP |
getDeviceListIP | 批量获取设备IP | getConfigAnno |
getConfigAnno | 构建Pod配置注解 | AddPodAnnotation |
AddPodAnnotation | 校正Pod注解 | ListAndWatch循环 |
UpdateHealth | 更新设备健康状态 | ListAndWatch循环 |
GetChange | 检测设备状态变化 | ListAndWatch循环 |
setAICoreHealthyIfVNpu | vNPU场景同步AI Core健康 | UpdateHealth |
setHealthyIfDuoCard | Duo卡场景同步健康 | UpdateHealth |
getUnHealthyCard | 获取不健康卡列表 | setHealthyIfDuoCard |
ClassifyDevices | 按类型分类设备(包级函数) | ListAndWatch |
classifyDevByType | 按类型分类辅助函数 | ClassifyDevices |
isHealthy | 判定设备是否健康 | writeNewFaultCode |
isNetworkHealthy | 判定网络是否健康 | writeNewFaultCode |
npuIsUsedNow | 检查NPU当前是否有任务 | isHealthy |
getVGroupID | 获取虚拟设备组ID | AppendVGroupInfo |
AppendVGroupInfo | 追加vGroup信息 | AddPodAnnotation |
CheckDeviceTypeLabel | 校验节点设备类型标签 | ListAndWatch |
CreateVirtualDevice | 创建虚拟设备 | 动态vNPU场景 |
DestroyVirtualDevice | 销毁虚拟设备 | 动态vNPU场景 |
GetChipAiCoreCount | 获取芯片AI Core总数 | 初始化 |
writeNewFaultCode | 刷新故障码到设备 | UpdateHealth |
getCurDeviceFaultCode | 获取当前设备故障码 | flushFaultCodesWithInit |
flushFaultCodesWithInit | 刷新故障码并初始化 | writeNewFaultCode |
moreThanFiveMin | 故障是否超过5分钟 | LogFaultModeChange |
networkMoreThanFiveMin | 网络故障是否超5分钟 | LogFaultModeChange |
LogFaultModeChange | 记录故障模式变更 | 外部调用 |
getNPUsByShareMode | 共享模式NPU列表 | assembleShareModeDevices |
assembleShareModeDevices | 组装共享模式设备 | 310P GetNPUs |
SetDeviceUsage | 设置设备用途(训练/推理) | 初始化 |
GetDeviceUsage | 获取设备用途 | 多处 |
GetServerBoardId | 获取服务器板ID | SetDeviceUsage |
GetIfCardsInResetting/SetCardsInResetting | 卡重置状态管理 | 热重置流程 |
GetResetFailedTimes/SetResetFailedTimes | 重置失败次数管理 | 热重置流程 |
WriteFaultToEvent | 故障写入K8s Event | 后台goroutine |
WriteUpgradeReasonRemoveEvent | 升级原因释放事件 | writeDeviceInfoCm |
doWriteFaultToEvent | 实际写Event | WriteFaultToEvent |
SetSuperPodID/GetSuperPodID | 超Pod ID管理 | A5场景 |
SetServerIndex/GetServerIndex | 服务器索引管理 | A5场景 |
HandleDropCardFaultEvents | 处理掉卡故障 | 故障检测循环 |
generateCardDropFaultEvents | 生成掉卡故障事件 | HandleDropCardFaultEvents |
checkCardDropFault | 检查掉卡故障 | generateCardDropFaultEvents |
HandleLostChipFaultEvents | 处理丢失芯片故障 | 故障检测循环 |
generateChipFaultEventsBasedOnFaultCacheChange | 基于缓存变化生成芯片故障 | HandleLostChipFaultEvents |
HandleLostNetworkFaultEvents | 处理丢失网络故障 | 故障检测循环 |
generateNetworkFaultEventsBasedOnFaultCacheChange | 基于缓存变化生成网络故障 | HandleLostNetworkFaultEvents |
queryNetworkStatusWithoutFaultCode | 无故障码时查询网络状态 | generateNetworkFaultEvents… |
getNetworkStatusCache | 带限流的网络状态缓存查询 | queryNetworkStatusWithoutFaultCode |
2.2.2 HwAscend910Manager 方法
| 方法 | 作用 |
|---|---|
NewHwAscend910Manager | 构造函数 |
getAscend910Name | 根据卡类型返回设备名 |
GetNPUs | 发现所有910 NPU设备(物理/虚拟) |
GraceTolerance | 优雅容错主入口 |
hotResetHandler | 热重置处理器(无任务场景) |
getDevFaultInfo | 获取设备故障信息 |
getResetIndex | 获取重置Ring索引 |
hotResetTryOutBand | 尝试带外重置 |
isFaultNeedRestart | 判断故障是否需要重启 |
startUpHotReset | 启动热重置流程 |
setAllDevUnhealthyOnRing | 设置Ring上所有设备不健康 |
setUnhealthyForA3 | A3卡设置关联设备不健康 |
GetAssociatedLogicIDs | 获取A3关联LogicID列表 |
clearDeviceStatus | 清除设备重置状态 |
handleResetProcess | 处理重置流程 |
checkFaultIsExist | 检查故障是否仍存在 |
upgradeHotResetError | 升级热重置错误为隔离 |
refreshDevFaultInfoForResetProcess | 刷新重置过程中的故障信息 |
execHotReset | 执行热重置 |
isChipActive | 检查芯片是否活跃(有任务) |
canBeReset | 检查所有芯片是否可重置 |
canA3BeReset | A3卡可重置检查 |
getBusyChipListFromPod | 从Pod列表获取繁忙芯片 |
DoWithVolcanoListAndWatch | Volcano调度ListAndWatch入口 |
updateDeviceInfo | 更新设备信息到CM |
isNeedBlockAllDevice | 是否需要阻塞所有设备调度 |
update910NodeLabel | 更新910节点标签 |
getHealthAndRecoverDev | 获取健康和恢复设备 |
getNewNetworkRecoverDev | 获取新网络恢复设备 |
getPatchLabel | 生成节点标签补丁 |
getRecoverLabelFromNodeSets | 从节点标签获取恢复集 |
toStandardDeviceFmt | 转为标准设备格式 |
updateHotResetCache | 更新热重置缓存 |
updateUpgradeErrorInfo | 更新升级错误信息 |
setTaskDevInfoCache | 设置任务设备信息缓存 |
handleUpdateCaches | 批量更新缓存 |
convertPhysicIdToLogicId | 物理ID→逻辑ID转换 |
isReSchedulingScene | 是否为重调度场景 |
isTaskInReset | 任务是否在重置中 |
filterDevStatus | 过滤重置中设备状态 |
filterDevStatusForA3 | A3卡过滤重置状态 |
processAllTask | 处理所有任务容错 |
policyLevelHandle | 策略级别处理 |
isolateSceneHandle | 隔离场景处理 |
runProcessTask | 运行任务处理 |
restartRequestProcess | L2故障处理(请求重启) |
handleSucceedRestartRequest | L2成功处理 |
checkDevErrorCode | 检查设备错误码清除 |
restartProcess | L3故障处理(设备重启) |
upgradeRestartProcess | L3升级为重置 |
upgradeRestartRequestProcess | L2升级为重置 |
updateResetCMStatus | 更新重置CM状态 |
updateResetCMStatusWithoutWait | 更新重置CM状态(不等) |
resetProcess | L5故障处理(强制重置) |
waitForAllFaultyDeviceProcessesToZero | 等待故障设备进程归零 |
canContinueGraceProcess | 检查是否可继续容错 |
updateResetCMStatusToIsolate | 更新CM为隔离状态 |
getA3LogicMapByAssociation | A3关联LogicID映射 |
getNeedResetDeviceLogicIdMap | 获取需重置设备映射 |
addAllLogicIdsToFaultMap | 添加Ring上所有LogicID |
checkNumberOfAllProcessIsZero | 检查所有进程是否归零 |
upgradeResetProcess | L5升级为隔离 |
preProcess | 预处理(写CM/设状态) |
postProcess | 后处理(清理状态) |
refreshDevFaultInfo | 刷新设备故障信息 |
getNeedResetDevMapForA3 | A3需重置设备映射 |
getResetIndexForA3 | A3重置索引 |
resetDeviceOnce | 执行一次设备重置 |
canResetDeviceByLogicID | 按LogicID检查可重置 |
canResetDevice | 检查设备可重置(忙/次数) |
execResetDevice | 执行设备重置(带内) |
execOutBandReset | 执行带外重置 |
scanDeviceForThirdParty | 第三方设备扫描 |
execRescan | 执行重新扫描 |
fillResetDevs | 补充设备信息(PhyID/CardID) |
updateResetInfo | 更新重置信息文件 |
resetDeviceOutBand | 带外重置单设备 |
isNetResetCompleted | 网络重置完成检查 |
waitDeviceResetComplete | 等待设备重置完成 |
isRunningDistributed | 是否分布式训练 |
isShouldCheckNet | 是否需检查网络 |
isRingResetComplete | Ring重置完成检查 |
tryResetDevice | 尝试重置设备(带内) |
tryResetDeviceOffline | 尝试离线重置设备 |
tryWriteIsolationInfo | 写隔离信息到CM |
isDevShouldBeIsolate | 设备是否应隔离 |
SetDpu | 设置DPU信息 |
2.2.3 HotResetTools 方法
| 方法 | 作用 |
|---|---|
NewHotResetManager | 构造函数(根据卡类型/用途/板ID确定Ring大小) |
getResetDevNumOnce | 获取单次重置设备数 |
SyncResetCM | 同步Reset CM(Pod/CM Informer) |
run | 工作队列消费循环 |
processNextWorkItem | 处理下一个工作项 |
handleEvent | 事件分发(Pod/CM) |
handlePodEvent | Pod事件处理 |
handlePodAddEvent | Pod添加事件(创建目录/写CM文件) |
writeCmToFileWhilePodAdd | Pod添加时写CM到文件 |
handlePodDeleteEvent | Pod删除事件(清理文件/目录) |
getPodFromCache | 从缓存获取Pod |
GetCMFromCache | 从缓存获取CM |
writeCMToFile | 写CM数据到文件 |
handleConfigMapEvent | CM事件处理 |
handleCMUpdateEvent | CM更新事件 |
handleCMDeleteEvent | CM删除事件 |
writeCmToFileSystem | 写CM到文件系统 |
checkConfigMap | CM过滤器(Reset/DataTrace前缀) |
GetResetDevNumOnce | 获取单次重置设备数 |
GetTaskDevFaultInfoList | 获取任务设备故障信息列表 |
GetTaskPod | 获取任务Pod |
GetAllTaskDevFaultInfoList | 获取所有任务故障信息 |
GetDevListInReset | 获取重置中设备列表 |
GetGlobalDevFaultInfo | 获取全局设备故障信息 |
GetDevProcessPolicy | 获取设备处理策略 |
GetTaskProcessPolicy | 获取任务处理策略(最高级别) |
GetDevIdList | 设备字符串→物理ID列表 |
GetDevListByPolicyLevel | 按策略级别筛选设备 |
GetNeedResetDevMap | 获取需重置设备映射 |
GetTaskResetInfo | 获取任务重置信息 |
GetTaskFaultRankInfo | 获取任务故障Rank信息 |
GetFaultDev2PodMap | 获取故障设备→Pod映射 |
GetTaskNameByPod | 从Pod获取任务名 |
GenerateTaskDevFaultInfoList | 生成任务设备故障列表(含Rank) |
UpdateFaultDev2PodMap | 更新故障设备→Pod映射 |
UpdateGlobalDevFaultInfoCache | 更新全局设备故障缓存 |
UpdateTaskDevListCache | 更新任务设备列表缓存 |
UpdateTaskDevFaultInfoCache | 更新任务故障信息缓存 |
UpdateTaskPodCache | 更新任务Pod缓存 |
UpdateFreeTask | 清理已结束任务的重置状态 |
isTaskDevListChange | 检查任务设备列表是否变化 |
IsCurNodeTaskInReset | 当前节点任务是否在重置 |
IsExistFaultyDevInTask | 任务中是否存在故障设备 |
SetTaskInReset | 设置任务重置状态 |
SetDevInReset | 设置设备重置状态 |
SetAllDevInReset | 设置任务所有设备重置 |
UnSetDevInReset | 取消设备重置状态 |
UnSetAllDevInReset | 取消任务所有设备重置 |
UnSetTaskInReset | 取消任务重置状态 |
DeepCopyDevInfo | 深拷贝设备信息 |
DeepCopyDevFaultInfoList | 深拷贝故障信息列表 |
2.3 内部调用关系
2.4 数据流入流出
三、核心业务逻辑深度解析
3.1 ascendcommon.go — AscendTools 基类深度解析
3.1.1 AscendTools 结构体定义
type AscendTools struct {
client *kubeclient.ClientK8s // K8s客户端,用于操作Pod/Node/CM/Event
dmgr devmanager.DeviceInterface // DCMI设备管理接口,直通NPU硬件
name string // 设备名称,如"Ascend910"或"Ascend910A5"→"npu"
deviceUsage string // 设备用途:"train"或"infer"
unHealthyKey string // CM中不健康设备的key后缀
devCount int32 // 最大设备数(=MaxDevicesNum)
healthDevice sets.String // 健康设备集合(未在结构体方法中直接使用)
boardId uint32 // 服务器板ID,用于区分A800IA2等型号
superPodID int32 // A5超Pod ID
serverIndex int32 // A5服务器索引
rackID int32 // A5机架ID
superPodType int8 // A5超Pod类型
superPodSize int32 // A5超Pod大小
nodeInternalIP string // A5节点内部IP
// 重置状态管理
cardInResetMap map[int32]bool // LogicID→是否正在重置
cardInResetLock sync.Mutex // 重置状态互斥锁
resetFailedTimesMap map[int32]int // LogicID→连续重置失败次数
resetFailedTimesLock sync.Mutex // 失败次数互斥锁
// 快照/增量检测
lastUpdateTimeStamp time.Time // 上次更新时间
lastUpgradeFaultReason common.UpgradeFaultReasonMap[common.LogicId] // 上次升级故障原因
lastManuallySeparateNPU string // 上次手动隔离NPU
lastSwitchFaultInfo common.SwitchFaultInfo // 上次交换机故障
lastUsedChipsByProcess sets.String // 上次进程使用的芯片
lastUsedChipsContainerMap map[string]sets.String // 上次容器使用芯片映射
lastDpuInfo common.DpuInfo // 上次DPU信息
}
设计意图:
AscendTools作为所有NPU设备管理器的公共基类,通过组合而非继承的方式被HwAscend910Manager等管理器嵌入dmgr接口注入实现了硬件层解耦,便于测试mockboardId缓存设计避免了重复调用DCMI获取板信息cardInResetMap+cardInResetLock提供了线程安全的重置状态跟踪last*系列字段实现了增量更新检测,避免无变化的CM写入
3.1.2 DevManager 接口
DevManager 接口定义了设备管理器的完整契约,包含40+方法,覆盖:
- 设备发现(
GetNPUs) - 调度集成(
DoWithVolcanoListAndWatch) - 容错处理(
GraceTolerance) - 健康管理(
UpdateHealth,GetChange) - Pod注解管理(
AddPodAnnotation) - 虚拟设备管理(
CreateVirtualDevice,DestroyVirtualDevice) - A5超节点属性(
SetSuperPodType/Size,SetRackID等) - 重置状态管理(
SetCardsInResetting,GetResetFailedTimes等) - 故障事件处理(
HandleDropCardFaultEvents,HandleLostChipFaultEvents等) - DPU管理(
SetDpu) - 设备信息加载(
LoadDeviceInfoCm)
3.1.3 核心流程:UpdateNodeDeviceInfo — 设备信息CM更新
逐行解析关键代码段:
// checkAndInitNodeDeviceInfo — 如果CM缓存为空,创建初始结构
func (tool *AscendTools) checkAndInitNodeDeviceInfo() {
nodeDeviceInfo := tool.GetKubeClient().GetDeviceInfoCMCache()
if nodeDeviceInfo == nil {
// 创建初始的设备信息缓存,包含空DeviceList和默认SuperPodID/ServerIndex
var nodeDeviceData = common.NodeDeviceInfoCache{
DeviceInfo: common.NodeDeviceInfo{
DeviceList: make(map[string]string, 1), // 空设备列表
UpdateTime: time.Now().Unix(), // 当前时间戳
},
SuperPodID: common.DefaultSuperPodID, // 默认超Pod ID
ServerIndex: common.DefaultServerIndex, // 默认服务器索引
}
// 生成校验码,用于后续CM数据完整性校验
nodeDeviceData.CheckCode = common.MakeDataHash(nodeDeviceData.DeviceInfo)
tool.GetKubeClient().SetNodeDeviceInfoCache(&nodeDeviceData)
}
}
// compareDeviceList — 比较设备列表是否一致(忽略fault_time字段)
func compareDeviceList(deviceList, newDeviceList map[string]string) bool {
// 双nil检查
if deviceList == nil && newDeviceList == nil { return true }
if deviceList == nil || newDeviceList == nil { return false }
if len(deviceList) != len(newDeviceList) { return false }
for key, value := range deviceList {
val, exists := newDeviceList[key]
if !exists { return false }
// 使用正则 re (`"fault_time":\d+,`) 移除fault_time字段后比较
// 设计意图:fault_time每次都会变化,但设备状态可能没变
str1 := re.ReplaceAllString(value, "")
str2 := re.ReplaceAllString(val, "")
if str1 != str2 { return false }
}
return true
}
3.1.4 核心流程:健康状态判定
isHealthy 方法逐行解析:
func (tool *AscendTools) isHealthy(device *common.NpuDevice) string {
// 获取故障类型:根据设备的FaultCodes和LogicID查询故障级别
faultType := common.GetFaultType(device.FaultCodes, device.LogicID)
// 条件1:正常/不处理/子健康 → 健康
// 条件2:FreeRestartNPU(空闲重启)且设备当前在用且优雅容错开启 → 健康
// 设计意图:设备在用时不执行空闲重启,等任务结束再处理
if faultType == common.NormalNPU || faultType == common.NotHandleFault ||
faultType == common.SubHealthFault ||
(faultType == common.FreeRestartNPU &&
tool.npuIsUsedNow(device.DeviceName) &&
common.ParamOption.GraceToleranceOn == true) {
return v1beta1.Healthy
}
// 条件3:预隔离故障但设备在用 → 健康(延迟隔离)
// 设计意图:设备有任务运行时不立即隔离,等任务完成后再隔离
if faultType == common.PreSeparateNPU && tool.npuIsUsedNow(device.DeviceName) {
hwlog.RunLog.Infof("detect %s but device is used, device name: %s",
faultType, device.DeviceName)
return v1beta1.Healthy
}
// 其他故障类型 → 不健康
return v1beta1.Unhealthy
}
3.1.5 核心流程:设备IP获取 (GetDeviceIP)
设计意图:IPv4/IPv6双栈自适应机制,先尝试IPv4,失败后切换IPv6,IPv6失败再回退IPv4。useIpv4全局变量实现状态记忆,避免每次都做双栈探测。
3.1.6 核心流程:Pod注解校正 (AddPodAnnotation)
func (tool *AscendTools) AddPodAnnotation(podDev *common.PodDeviceInfo, deviceType, hostIp string,
allDevices []common.NpuDevice) error {
// 1. 非预置虚拟设备时,追加vGroup信息到设备名
if !common.ParamOption.PresetVDevice {
tool.AppendVGroupInfo(podDev.RealDevice)
}
// 2. 排序设备列表,确保注解值一致性
sort.Strings(podDev.KltDevice)
sort.Strings(podDev.RealDevice)
allUsedDev := strings.Join(podDev.RealDevice, common.CommaSepDev)
// 3. 构建注解校验列表:huawei.com/Ascend910-2kl 和 AscendReal
annoChecker := []struct{ annoKey, annoValue string }{
{api.ResourceNamePrefix + common.Pod2kl,
strings.Join(podDev.KltDevice, common.CommaSepDev)},
{api.PodAnnotationAscendReal, allUsedDev},
}
// 4. 非虚拟设备:检查并校正注解
annotation := make(map[string]string)
if !common.IsVirtualDev(deviceType) {
for _, checker := range annoChecker {
// 动态场景不校正 huawei.com/npu-core
if deviceType == common.AiCoreResourceName &&
checker.annoKey == fmt.Sprintf("%s%s", api.ResourceNamePrefix, deviceType) {
continue
}
if podDev.Pod.Annotations[checker.annoKey] != checker.annoValue {
// 发现不一致,记录待校正
annotation[checker.annoKey] = checker.annoValue
}
}
}
// 5. 910/300IDuo场景:校验配置注解(含ranktable信息)
if tool.name == api.NPULowerCase || tool.name == api.Ascend910 || common.IsContainAll300IDuo() {
config, err := tool.getConfigAnno(podDev, deviceType, hostIp, allDevices)
if err == nil {
key := api.Pod910DeviceAnno // "ascend-910-configuration"
if tool.name == api.NPULowerCase {
key = api.PodNPUDeviceAnno // "ascend-npu-configuration"
}
if podDev.Pod.Annotations[key] != config {
annotation[key] = config
}
}
}
// 6. 如有变化,通过customname替换后更新Pod注解
if len(annotation) == 0 { return nil }
newAnnotation := customname.ReplacePodAnnotation(tool.name, annotation)
return tool.client.TryUpdatePodAnnotation(&podDev.Pod, newAnnotation)
}
3.1.7 核心流程:故障事件写入K8s Event
限流设计:
// faultEventLimiter: 每1/WriteEventRateLimit秒允许1个事件,突发WriteEventRateLimit个
faultEventLimiter = rate.NewLimiter(
rate.Every(time.Minute/common.WriteEventRateLimit), // 每分钟N个事件
common.WriteEventRateLimit) // 突发容量N
3.1.8 核心流程:手动隔离NPU处理
3.1.9 核心流程:LoadDeviceInfoCm — 启动时加载设备信息CM
3.1.10 核心流程:故障丢失事件补偿机制
设计意图:故障订阅接口可能丢失事件(订阅失败、设备重置后短暂中断等),这三个方法作为补偿机制,在以下场景主动补查故障状态:
- 首次刷新 (
isFirstFlushFault):启动时全量补查 - 设备刚重置 (
initLogicIDs):重置后重新建立故障基线 - 订阅失败 (
SubscribeFailed):降级为轮询模式 - 故障超时未恢复 (
moreThanFiveMin):长时间不健康时主动补查
3.1.11 网络状态缓存与限流
func getNetworkStatusCache(phyId int32) string {
// 1. 获取或初始化限流器
// 每个物理设备独立限流,避免单设备查询阻塞其他设备
networkLimiter, ok := networkLimiterMap[phyId]
if !ok {
networkLimiter = rate.NewLimiter(
rate.Every(common.EveryNetworkQueryDuration*time.Minute/common.NetworkQueryRateLimit),
common.NetworkQueryRateLimit)
networkLimiterMap[phyId] = networkLimiter
}
// 2. 限流检查:如果被限流且有缓存,返回缓存值
linkStatusCache, ok := networkStatusCache[phyId]
if !networkLimiter.Allow() && ok {
return linkStatusCache // 返回缓存,避免频繁查询硬件
}
// 3. 实际查询hccn接口
linkStatus, err := hccn.GetNPULinkStatus(phyId)
if err != nil {
// 查询失败时缓存为LinkDown(保守策略)
networkStatusCache[phyId] = npuCommon.NPUNetworkLinkDownStatus
return npuCommon.NPUNetworkLinkDownStatus
}
networkStatusCache[phyId] = linkStatus
return linkStatus
}
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐

所有评论(0)