YAOTU INSIGHTS

KubeEdge 边缘节点远程升级:NodeUpgradeJob CRD 与云边协同升级方案详解

KubeEdge 边缘节点远程升级:NodeUpgradeJob CRD 与云边协同升级方案详解
KubeEdge 边缘节点远程升级NodeUpgradeJob CRD 与云边协同升级方案详解【免费下载链接】kubeedgeKubernetes Native Edge Computing Framework (project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/ku/kubeedge导读在边缘计算场景中海量边缘节点分散部署在网络边缘若逐一登录节点手工升级 EdgeCore运维成本极高。KubeEdge 通过定义集群级自定义资源NodeUpgradeJoboperations.kubeedge.io/v1alpha1配合云端控制器与边缘侧 keadm 升级工具实现了从云端一键批量升级边缘节点、并自动同步升级结果状态的完整闭环。本文以官方提案 edge-node-upgrade.md 为骨架结合仓库内 CRD 类型定义、控制器实现、Admission Webhook 校验、CloudHub HTTP 接口与边缘侧 action 源码深入讲解其设计原理、CRD 字段语义、升级工作流与校验规则帮助读者掌握如何在真实集群中通过kubectl创建NodeUpgradeJob完成边缘节点升级与结果观测。背景与动机为什么需要边缘节点远程升级边缘节点通常位于用户侧网络无法直接暴露给运维人员远程登录。升级管理Edge Node Upgrade Management是边缘计算中从云端远程升级边缘节点这一关键能力所必需的。KubeEdge 的该提案主要解决两个核心问题如何从云端发起对边缘节点的升级——提供可被云端 API Server 暴露的 CRD 接口让用户以声明式方式描述升级诉求如何在云边之间同步升级结果状态——边缘节点完成升级或升级失败后把结果回传给云端并写入 CR 的status字段供用户随时查询。设计目标Goals提供从云端升级边缘节点的 API在云和边缘节点之间同步边缘节点升级结果。使用场景Use Cases描述升级属性用户可以描述升级属性以及与之交互/控制升级的访问机制目标版本、超时时间、选择节点的方式、使用的升级工具与镜像等从云端对升级执行 CRUD 操作通过 Kubernetes API Server 暴露的 CRD API用户可以在云端创建、更新、删除升级元数据上报升级属性值边缘节点可以向云端上报升级结果状态。NodeUpgradeJob 控制器设计Upstream / Downstream 双通道NodeUpgradeJob控制器启动两个独立的 goroutine分别命名为upstream控制器和downstream控制器它们并非独立控制器仅是为清晰描述而命名Downstream 控制器负责把NodeUpgradeJob的更新从云端同步到边缘节点下发升级指令Upstream 控制器职责相反负责把边缘节点的升级结果回传到云端并更新 CR 状态。从当前仓库源码看该控制器经历了从独立控制器旧版到 controller-runtime 标准 Reconcile 模式的演进控制器入口定义在 cloud/pkg/controllermanager/nodetask/nodeupgradejob.go通过controllerruntime.NewControllerManagedBy(mgr).For(operationsv1alpha2.NodeUpgradeJob{}).Complete(c)注册对NodeUpgradeJob的监听通用协调逻辑封装在 cloud/pkg/controllermanager/nodetask/reconcile_runner.go 的RunReconcile中统一处理添加 Finalizerkubeedge.io/nodeupgradejob-controller、删除清理、初始化节点状态、计算任务阶段、超时检测与状态更新失败重试 3 次、间隔 200ms具体业务实现见 cloud/pkg/controllermanager/nodetask/nodeupgradejob_handler.go包括InitNodesStatus根据nodeNames/labelSelector校验并初始化各节点任务状态、CheckTimeout基于最后 action 更新时间或 CR 创建时间判断是否超时超时则置为unknown阶段并记录The node task has timed out以及CalculateStatus按failureTolerate容错比例汇总任务阶段。同步流程从 kubectl 创建到升级结果回写下图描述了NodeUpgradeJob属性值在云/边两侧更新时的事件流转全貌原图见 docs/images/edge-node-upgrade/upgrade.png用户使用kubectl创建NodeUpgradeJobCR 以触发升级任务NodeUpgradeJob控制器通过 List-Watch 监听该资源向边缘节点发送升级消息边缘节点的 EdgeCore 使用keadm执行升级操作keadm将升级结果上报云端云端把升级结果写入NodeUpgradeJob的status字段。用户通过查看status字段即可判断升级是否成功。Downstream 控制器的职责监听 CRD 资源使用 List-Watch 机制监控NodeUpgradeJobCRD 资源收到 K8s APIServer 事件后存入本地缓存旧版使用 map 缓存当前版本基于 informer/controller-runtime cache见 cloud/pkg/taskmanager/downstream/node_upgrade.go 中GetKubeEdgeInformerFactory().Operations().V1alpha2().NodeUpgradeJobs().Informer()的注册方式。幂等性判断检查升级任务是否已完成全部或部分节点升级完成。若已完成则不再向边缘节点重复发送升级消息仅当升级未完成时才下发。该操作是为了防止 cloudcore 重启等场景下重复向边缘节点发送升级消息。节点过滤使用 K8s informer 根据 CR 中指定的NodeNames或LabelSelector获取节点列表并过滤掉不满足升级要求的节点边缘节点已经处于期望的目标升级版本非边缘节点缺少标签node-role.kubernetes.io/edge: 边缘节点正处于 Upgrading 或 NotReady 状态去除重复节点。下发升级消息对每个合规的边缘节点发送升级 beehive 消息调用 K8s API 将边缘节点标记为不可调度unschedulable避免在升级中的边缘节点上继续部署应用同时启动一个 Goroutine 处理超时——若未收到边缘节点升级响应则将NodeUpgradeJob状态更新为超时状态以应对无响应场景。CloudHub 与 EdgeHub 的云边通道CloudHub将升级请求发送给每个边缘节点的 EdgeHub。EdgeHub侧的处理逻辑增加一个升级子模块处理升级消息该子模块会对升级消息做一系列校验检查 UpgradeID 是否为空、edgecore 是否已处于目标版本等为提高适配性提供升级 Provider 接口默认使用KeadmUpgrade执行升级操作用户可通过设置UpgradeTool字段选择其他安装器完成升级任务从当前仓库看该字段已在 v1alpha1/v1alpha2 类型中移除默认固定使用 keadm详见 v1alpha1/type.goKeadmUpgrade会下载指定版本的 keadmEdgeCore 拉取kubeedge/installation-package镜像并把 keadm 二进制从容器复制到主机路径随后启动一个守护进程运行keadm upgrade相关命令完成升级操作而不是直接运行keadm命令——因为 keadm 在升级过程中会 kill 掉 edgecore 进程必须隔离执行。keadm 升级三阶段预处理、执行与回滚预处理preprocesskeadm 在开始升级边缘节点前会做预处理工作。使用/etc/kubeedge/idempotency_record文件保证同一时间只能执行一次升级备份edgecore.db、edgecore.yaml、edgecore到备份路径/etc/kubeedge/backup/{From_Version}拉取kubeedge/installation-package镜像并把新版本 edgecore 二进制从容器复制到主机升级路径/etc/kubeedge/upgrade/{To_Version}。执行process停止 edgecore把新版本 edgecore 复制到/usr/local/bin目录并启动新 edgecore。回滚rollback若升级失败keadm 执行回滚操作以启动原始 edgecore 进程停止 edgecore、回滚文件、把备份目录/etc/kubeedge/backup/{From_Version}中的文件复制回原路径然后启动原始 edgecore。无论升级成功还是失败keadm 都会把**升级结果及失败原因若失败**上报给 CloudHub 的 HTTP 服务。Upstream 控制器与结果落盘CloudHub其 HTTP 服务新增/nodeupgrade接口将升级响应消息转发给NodeUpgradeJob控制器 Upstream。该接口实现见 cloud/pkg/cloudhub/servers/httpserver/nodetask/upgrade.goUpgradeEdge解析请求体限制最大 1MB根据上报的Statusupgrade_success/upgrade_failed_rollback_success/upgrade_failed_rollback_failed构造对应Event/Action通过 beehive 消息发送给 TaskManager 模块处理。Upstream 控制器将节点标记为**可调度schedulable**并 patch 升级状态若升级成功调用 K8s API 在 Node 的 annotation 中记录升级历史例如nodeupgradejob.operations.kubeedge.io/history: v1.10.0-v1.11.0方便用户查看节点升级历史。CRD 设计详解API 分组与版本NodeUpgradeJobCRD 为**集群级cluster-scoped**资源分组、种类与 API 版本信息如下FieldDescriptionGroupoperations.kubeedge.ioAPIVersionv1alpha1KindNodeUpgradeJob当前仓库同时保留了v1alpha1与v1alpha2两个版本v1alpha2标记为存储版本kubebuilder:storageversion并引入Phase、NodeStatus、ActionFlow、Concurrency、CheckItems、FailureTolerate、RequireConfirmation、ImageDigestGetter等增强字段v1alpha1的State/Event/Action等字段被标记为 Deprecated计划在 v1.23 移除。完整的 CRD YAML 见 manifests/charts/cloudcore/crds/operations_v1alpha2_nodeupgradejob.yaml。NodeUpgradeJob就像可复用的模板使用它可以把边缘节点升级到指定版本并方便地从云端进行操作。NodeUpgradeJob 类型定义提案给出了完整的 Go 类型定义在仓库中实际落地于 staging/src/github.com/kubeedge/api/apis/operations/v1alpha1/type.go 与 v1alpha2/types_nodeupgrade.go// NodeUpgradeJob is used to upgrade edge node from cloud side. // k8s:openapi-gentrue // kubebuilder:subresource:status // kubebuilder:resource:scopeCluster type NodeUpgradeJob struct { metav1.TypeMeta json:,inline metav1.ObjectMeta json:metadata,omitempty // Specification of the desired behavior of NodeUpgradeJob. // optional Spec NodeUpgradeJobSpec json:spec,omitempty // Most recently observed status of the NodeUpgradeJob. // optional Status NodeUpgradeJobStatus json:status,omitempty } // k8s:deepcopy-gen:interfacesk8s.io/apimachinery/pkg/runtime.Object // NodeUpgradeJobList is a list of NodeUpgradeJob. type NodeUpgradeJobList struct { metav1.TypeMeta json:,inline metav1.ListMeta json:metadata,omitempty Items []NodeUpgradeJob json:items }NodeUpgradeJobSpec规格字段语义// NodeUpgradeJobSpec is the specification of the desired behavior of the NodeUpgradeJob. type NodeUpgradeJobSpec struct { // Required: Version is the EdgeCore version to upgrade. Version string json:version,omitempty // UpgradeTool is a request to decide use which upgrade tool. If it is empty, // the upgrade job simply use default upgrade tool keadm to do upgrade operation. // optional UpgradeTool string json:upgradeTool,omitempty // TimeoutSeconds limits the duration of the node upgrade job. // Default to 300. // If set to 0, well use the default value 300. // optional TimeoutSeconds *uint32 json:timeoutSeconds,omitempty // NodeNames is a request to select some specific nodes. If it is non-empty, // the upgrade job simply select these edge nodes to do upgrade operation. // Please note that sets of NodeNames and LabelSelector are ORed. // Users must set one and can only set one. // optional NodeNames []string json:nodeNames,omitempty // LabelSelector is a filter to select member clusters by labels. // It must match a nodes labels for the NodeUpgradeJob to be operated on that node. // Please note that sets of NodeNames and LabelSelector are ORed. // Users must set one and can only set one. // optional LabelSelector *metav1.LabelSelector json:labelSelector,omitempty // Image specifies a container image name, the image contains: keadm and edgecore. // keadm is used as upgradetool, to install the new version of edgecore. // The image name consists of registry hostname and repository name, but cannot includes the tag, // Version above will be used as the tag. // If the registry hostname is empty, docker.io will be used as default. // The default image name is: kubeedge/installation-package. // optional Image string json:image,omitempty }各字段核心语义字段类型必填说明versionstring是要升级到的 EdgeCore 版本如v1.10.0upgradeToolstring否使用的升级工具为空时默认使用keadmtimeoutSeconds*uint32否升级任务时长上限默认 300 秒设为 0 时也按 300 秒处理nodeNames[]string二者选一指定具体节点名执行升级labelSelector*metav1.LabelSelector二者选一按标签过滤节点执行升级与nodeNames为 OR 关系且必须且只能设置其中一个imagestring否包含 keadm 与 edgecore 的容器镜像名镜像名由 registry 主机名和仓库名组成不能包含 tagversion会被用作 tagregistry 主机名为空时默认docker.io默认镜像名为kubeedge/installation-package此外v1alpha2版本在 types_nodeupgrade.go 中扩展了以下字段concurrencyint32默认 1每个 CloudCore 实例可同时升级的最大边缘节点数checkItems[]string默认 nil任务执行前需要检查的项目failureToleratestring默认 0.1任务容忍的失败比例requireConfirmationbool默认 false是否需要在升级前进行确认imageDigestGatter镜像摘要校验配置可显式指定arm64/amd64平台的sha256摘要或通过registryAPIhosttoken自动从远端 registry 获取多平台摘要进行校验。升级结果与状态枚举// UpgradeResult describe the result status of upgrade operation on edge nodes. // kubebuilder:validation:Enumupgrade_success;upgrade_failed_rollback_success;upgrade_failed_rollback_failed type UpgradeResult string // upgrade operation status const ( UpgradeSuccess UpgradeResult upgrade_success UpgradeFailedRollbackSuccess UpgradeResult upgrade_failed_rollback_success UpgradeFailedRollbackFailed UpgradeResult upgrade_failed_rollback_failed ) // UpgradeState describe the UpgradeState of upgrade operation on edge nodes. // kubebuilder:validation:Enumupgrading;completed type UpgradeState string // Valid values of UpgradeState const ( InitialValue UpgradeState Upgrading UpgradeState upgrading Completed UpgradeState completed )UpgradeResult三种取值upgrade_success升级成功、upgrade_failed_rollback_success升级失败但回滚成功、upgrade_failed_rollback_failed升级失败且回滚也失败UpgradeState取值空字符串初始值、upgrading升级中、completed已完成。NodeUpgradeJobStatus 与节点级 UpgradeStatus// NodeUpgradeJobStatus stores the status of NodeUpgradeJob. // contains multiple edge nodes upgrade status. // kubebuilder:validation:Typeobject type NodeUpgradeJobStatus struct { // State represents for the state phase of the NodeUpgradeJob. // There are three possible state values: , upgrading and completed. State UpgradeState json:state,omitempty // Status contains upgrade Status for each edge node. Status []UpgradeStatus json:status,omitempty } // UpgradeStatus stores the status of Upgrade for each edge node. // kubebuilder:validation:Typeobject type UpgradeStatus struct { // NodeName is the name of edge node. NodeName string json:nodeName,omitempty // State represents for the upgrade state phase of the edge node. // There are three possible state values: , upgrading and completed. State UpgradeState json:state,omitempty // History is the last upgrade result of the edge node. History History json:history,omitempty } // History stores the information about upgrade history record. // kubebuilder:validation:Typeobject type History struct { // HistoryID is to uniquely identify an Upgrade Operation. HistoryID string json:historyID,omitempty // FromVersion is the version which the edge node is upgraded from. FromVersion string json:fromVersion,omitempty // ToVersion is the version which the edge node is upgraded to. ToVersion string json:toVersion,omitempty // Result represents the result of upgrade. Result UpgradeResult json:result,omitempty // Reason is the error reason of Upgrade failure. // If the upgrade is successful, this reason is an empty string. Reason string json:reason,omitempty // UpgradeTime is the time of this Upgrade. UpgradeTime string json:upgradeTime,omitempty }NodeUpgradeJobStatus保存整个任务级状态UpgradeStatus记录每个边缘节点的升级状态其中History记录了HistoryID升级操作唯一标识、FromVersion/ToVersion从哪个版本升到哪个版本、Result升级结果、Reason失败原因成功时为空字符串、UpgradeTime升级时间。注意每个节点的 status 中只保留最后一次升级历史记录。NodeUpgradeJob 示例以下示例展示了如何定义一个NodeUpgradeJob来升级边缘节点apiVersion: operations.kubeedge.io/v1alpha1 kind: NodeUpgradeJob metadata: name: upgrade-example labels: description: upgrade-label spec: version: v1.10.0 timeoutSeconds: 60 labelSelector: matchLabels: node-role.kubernetes.io/edge: node-role.kubernetes.io/agent: 示例中各属性的含义version描述要升级到的目标版本nodeNames请求选择某些特定节点非空时只对这些边缘节点执行升级。注意NodeNames与LabelSelector是OR关系必须且只能设置其中一个labelSelector按标签过滤节点节点标签必须匹配才能被该任务操作。与nodeNames同为二选一字段upgradeTool选择升级工具为空时默认使用keadmtimeoutSeconds限制升级任务时长默认 300不设置或设为 0 时使用默认值 300image指定包含 keadm 与 edgecore 的容器镜像名若包含 tag 或 digest会被version字段覆盖registry 主机名为空时默认docker.io默认镜像名为kubeedge/installation-package。校验规则Validation提案建议使用两类校验机制保障 CR 的合法性OpenAPI v3 Schema 校验基于 CRD 的 OpenAPI v3 Schema 拦截非法请求例如字段类型错误布尔字段传入字符串等。完整 schema 见 operations_v1alpha2_nodeupgradejob.yaml。校验 Admission Webhook用于实现 Schema 无法表达的自定义校验规则例如创建的 Upgrade 实例未指定任何节点这类跨字段约束。NodeUpgradeJob 校验规则清单若任何Required字段如version等缺失禁止创建NodeUpgradeJobnodeNames与labelSelector不能同时为空必须至少指定一个有效节点也不能同时设置二者只能选其一CR 一旦创建不允许更新 spec 字段升级失败后用户需要自行通过 K8sNodeUpgradeJobCR 的 status 字段排查失败原因并可能需要手动升级NodeUpgradeJob的 status 中每节点只保留最后一次升级历史记录同时使用 webhook 做格式校验例如检查version格式是否正确。这些规则在仓库中有完整落地实现见 cloud/pkg/admissioncontroller/admit_nodeupgradejob.go校验 WebhookvalidateNodeUpgradeJob调用validation.ValidateVersion校验版本格式、validation.ValidateImageRepo校验镜像仓库名并强制NodeNames与LabelSelector必须二选一的约束两者都为空或都不为空都会被拒绝admitNodeUpgradeJob在Update操作时通过reflect.DeepEqual(oldUpgrade.Spec, newUpgrade.Spec)拒绝一切 spec 修改与提案规则 3 完全对应变更 WebhookmutatingNodeUpgradeJob在创建时自动为.spec.concurrency补默认值 1、为.spec.timeoutSeconds补默认值 300让 CR 在不显式配置时也能按提案的默认语义运行。对应的单元测试见 cloud/pkg/admissioncontroller/admit_nodeupgradejob_test.go。实战要点总结升级前置条件目标节点必须是带node-role.kubernetes.io/edge标签的边缘节点且处于 Ready 状态集群中需已部署 CloudCore 与相应的NodeUpgradeJobCRDHelm 安装 CloudCore 时 CRD 位于 manifests/charts/cloudcore/crds 目录下。创建任务编写 YAML 并通过kubectl apply创建NodeUpgradeJob控制器会自动完成节点过滤、节点置为不可调度、下发升级消息的完整流程。观察结果通过kubectl get nodeupgradejob name -o yaml查看status字段任务级State 节点级Status/History确认每个节点是upgrade_success还是回滚成功/失败成功升级后还可通过节点 annotationnodeupgradejob.operations.kubeedge.io/history快速查看升级历史。失败处理升级失败时结合History.Reason、Reason字段与节点侧 keadm 日志定位原因必要时手工升级或重新发起任务。【免费下载链接】kubeedgeKubernetes Native Edge Computing Framework (project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/ku/kubeedge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考