资讯动态

KubeEdge 边缘节点 Pod 离线运维:keadm ctl get/restart pod 的设计与实现

发布时间:2026/9/16 17:23:22 来源:尧图企业网站定制
KubeEdge 边缘节点 Pod 离线运维keadm ctl get/restart pod 的设计与实现【免费下载链接】kubeedgeKubernetes Native Edge Computing Framework (project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/ku/kubeedge在边缘计算场景中边缘节点大部分时间处于断网状态云端 kubectl 无法查询或操作其上的 Pod。本文基于 KubeEdge 的设计提案 edgepodgetandrestart.md讲解keadm ctl get pod与keadm ctl restart pod两个边缘侧运维命令的完整设计、实际运行效果以及断网时 Pod 状态如何通过podpatch补丁机制保持准确的底层实现。读完后你能够掌握边缘节点离线状态下查询 Pod 状态、重启 Pod 容器的具体方法并理解 MetaServer、SQLite 元数据库与 CRI 运行时服务在其中的协作关系。背景与挑战提案首先给出了引入这两个命令的动机当边缘节点离线时无法通过云端的 kubectl 查询边缘节点上 Pod 的状态也无法重启边缘节点上的 Pod。keadm ctl系列命令正是为解决这一边缘自治运维问题而设计的其目标是在边缘节点上执行keadm ctl get pod [flags]查询 Pod 状态在边缘节点上执行keadm ctl restart pod [flags]重启 Pod。提案同时指出了三个关键挑战直接决定了后续设计网络环境恶劣边缘计算场景下边缘节点大多时间离线而此前的 KubeEdge 不支持云边断连时查询 Pod 状态离线时 Pod 状态会过期边缘节点离线后向 apiserver patch Pod 状态的操作会失败如果不在边缘本地完成 patch边缘节点元数据库 SQLite 中保存的 Pod 状态就停留在断网前的旧值——即使已经提供 metaserver、强调边缘自治查到的也仍是过期状态。因此必须设计断网时 Pod 状态在本地完成 patch 更新的机制重启而非删除 Pod出于权限收敛的考虑边缘侧的 Pod 重启只停止 Pod 中的容器而不销毁 PodSandbox因此不采用删除 Pod 的方式。keadm ctl get pod边缘侧查询 Pod 状态命令定义与参数在 keadm 中新增ctl get pod子命令用于获取边缘节点上的 Podkeadm ctl get pod command get pods in edge node Usage: keadm ctl get pod [flags] Flags: -A, --all-namespaces If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace -h, --help help for pod -n, --namespace string Specify a namespace (default default) -o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file, custom-columns, custom-columns-file, wide) -l, --selector string Selector (label query) to filter on, supports , , and !.(e.g. -l key1value1,key2value2)对应的参数注册代码见 AddGetPodFlags四个 flag-n/-l/-o/-A与提案描述一致命令别名为pods、po入口为 NewEdgePodGet并注册在 keadm ctl 命令树 之下。查询流程设计提案给出的查询方案分为五步执行keadm ctl get pod [flags]后向MetaServer发起一次 RESTful 请求MetaServer 判断云边网络是否连通若云边网络连通MetaServer 通过代理将 RESTful 请求转发到apiserver再从 apiserver 取回查询结果若边缘节点离线MetaServer 直接从边缘元数据库 SQLite中取出 Pod 数据拿到结果后使用 kubectl 的打印格式渲染并输出到控制台。也就是说keadm 侧无论云边是否连通走的都是同一套 REST 语义“连云查 apiserver”还是“离线查 SQLite”的分流决策由 MetaServer 内部完成这是该命令在断网时依然可用的关键。源码实现印证结合当前仓库源码可以确认上述流程的落地细节节点身份识别getPods 会解析 edgecore 配置文件util.ParseEdgecoreConfig从Modules.Edged.HostnameOverride读取本节点名称随后仅展示/输出pod.Spec.NodeName nodeName的 Pod即结果天然限定在本边缘节点上跨节点的 Pod 会提示cant to query pod: ... for node: ...。请求 MetaServer单 Pod 查询走 PodRequest.GetPod列表查询走 PodRequest.GetPods二者都通过 metaclient 构造的 Kubernetes clientset 发起标准的GET pods请求——正是提案中“向 MetaServer 发起 Restful request”的体现。kubectl 风格打印默认/wide输出通过 k8s 的 printers 表格转换器 将v1.Pod转成 internalapi.Pod后生成 Table列READY、STATUS、RESTARTS、AGE、IP、NODE 等与 kubectl 完全一致-o json/yaml则走PrintToJSONYaml直接序列化满足提案“安装 kubectl 的打印格式”的要求。实际运行示例提案中给出了三类典型用法及输出[rootcentos-edgenode1 kubeedge]# keadm ctl get pod NAME READY STATUS RESTARTS AGE mysql-0 0/1 CrashLoopBackOff 47 (55s ago) 140m nginx-deployment-7b79f6fd7f-wpm62 1/1 Running 0 139m [rootcentos-edgenode1 kubeedge]# keadm ctl get pod -owide -A NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default mysql-0 0/1 CrashLoopBackOff 43 (2m55s ago) 138m 10.88.0.2 centos-edgenode1 none none default nginx-deployment-7b79f6fd7f-wpm62 1/1 Running 0 137m 10.88.0.3 centos-edgenode1 none none kube-system kube-proxy-lrhf2 1/1 Running 0 6h27m 192.168.52.100 centos-edgenode1 none none kubeedge edge-eclipse-mosquitto-4p96z 1/1 Running 0 6h42m 192.168.52.100 centos-edgenode1 none none kubeedge edgemesh-agent-rtwr2 1/1 Running 0 5h43m 192.168.52.100 centos-edgenode1 none none kubesphere-monitoring-system node-exporter-pwcfm 2/2 Running 0 128m 192.168.52.100 centos-edgenode1 none none [rootcentos-edgenode1 kubeedge]# keadm ctl get pod -n kubeedge -l k8s-appkubeedge,kubeedgeedgemesh-agent -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES edgemesh-agent-rtwr2 1/1 Running 0 5h59m 192.168.52.100 centos-edgenode1 none none可以看到不带参数时默认查询default命名空间-owide -A跨全部命名空间并展示 IP、NODE 等宽列-n加-l标签选择器可实现精确过滤。命令对 Pod 名也可作为位置参数直接传入见 getPods 的 args 处理。keadm ctl restart pod仅停容器、不删沙箱命令定义与参数keadm ctl restart pod command delete pods in edge node Usage: keadm ctl restart pod [flags] Flags: -h, --help help for pod -n, --namespace string Specify a namespace (default default)重启命令仅需要命名空间和位置参数中的 Pod 名若不指定任何 PodNewEdgePodRestart 会直接报no pod specified for reboot。重启流程设计提案给出的重启方案为执行keadm ctl restart pod [flags]后向MetaServer发起 RESTful API 请求获取 Pod 数据通过remote.NewRemoteRuntimeService创建internalapi.RuntimeService即直连容器运行时 CRI 的客户端使用io.kubernetes.pod.name与io.kubernetes.pod.namespace标签选择器在运行时接口中过滤出该 Pod 需要重启的容器拿到容器列表后调用remoteRuntimeService.StopContainer逐个停止容器。这一设计与前文提到的“权限收敛”原则呼应PodSandbox 保持不变只有容器被停止kubelet 侧的重启计数RESTARTS随容器重启而增长。源码实现印证当前仓库中该链路的落地情况keadm 侧podRestart 将 Pod 名列表序列化为 JSON向 MetaServer POSTpods/restart子资源响应体为 types.RestartResponse含LogMessages与ErrMessages命令逐条打印因此控制台输出的是每个被停止容器的容器 ID。MetaServer 侧Restart handler 解析请求体中的[]stringPod 名请求体限制 3MB组装common.RestartInfo{PodNames, Namespace}后交由存储层执行。存储层storage.Restart 内部通过 CRIRemoteRuntimeService完成容器定位与停止关键的停止调用为 StopContainer(ctx, containerID, 3)——为每个容器设置 3 秒的宽限期与提案“只停容器”的语义一致。实际运行示例[rootcentos-edgenode1 kubeedge]# keadm ctl restart pod -n kubeedge edge-eclipse-mosquitto-j2db9 4b9efa598c80ffc59705a1e49aeba0b5fec2db6513905c1cceb8aee7a2ae453d b63fa1d05f0163b5556663c33827e8df673d8c8c386da49c3b3ddf3ccd7efb84 [rootcentos-edgenode1 kubeedge]# keadm ctl get pod -n kubeedge edge-eclipse-mosquitto-j2db9 kubeedge edge-eclipse-mosquitto-j2db9 1/1 Running 2 (1m ago) 11d [rootcentos-edgenode1 kubeedge]# keadm ctl restart pod -n kubeedge edgemesh-agent-rtwr2 689c25f7ca270b539dd4ae9288ba101ab5ca341140d09ee6497385446bac6f30 [rootcentos-edgenode1 kubeedge]# keadm ctl get pod -l k8s-appkubeedge,kubeedgeedgemesh-agent -owide -A NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kubeedge edgemesh-agent-rtwr2 1/1 Running 1 (7s ago) 5h52m 192.168.52.100 centos-edgenode1 none none两个细节值得注意多容器 Podmosquitto 示例中的 2 个容器会返回多个容器 ID重启后立即get podRESTARTS列递增1 (7s ago)、2 (14s ago)证明容器经历了“停止—重新拉起”而 Pod 本身未被删除。相关测试用例见 restart/pod_test.go 与 extend_restart_pod_test.go。断网时 Pod 状态的 patch 机制前两个命令要“离线可用”前提之一是 SQLite 中的 Pod 状态必须是最新值。提案针对这一点的离线状态 patch 设计如下机制要点当边缘节点处于离线状态时查询 PodMetaServer 从 SQLite 中取出pod与podpatch两份数据将二者合并merge成最新的 Pod再返回给请求方因为podpatch保存的正是该 Pod 最新的状态数据podpatch是edged 中的 StatusManager上报的 Pod 状态——即断网后 Pod 状态仍在本地持续 patch、持续写入MetaManager 会无论边缘节点在线还是离线都把podpatch持久化到 SQLite。这就闭环解决了前文提出的第二个挑战即使 kubelet 对云端 apiserver 的状态上报因断网失败边缘本地 SQLite 中依然会随podpatch的持续写入而保持与运行时一致的状态因此keadm ctl get pod在离线时返回的 RESTARTS、STATUS 等字段不会停留在断网前。小结能力命令在线行为离线行为查询 Pod 状态keadm ctl get pod [-A] [-n ns] [-l selector] [-o json\|yaml\|wide] [pod...]MetaServer 代理转发至 apiserverMetaServer 读 SQLite 的podpodpatch合并结果重启 Podkeadm ctl restart pod -n ns pod-name...向 MetaServer POSTpods/restart经 CRI 停止容器同左不依赖云端PodSandbox 保留、容器被停止关键实现与参考路径提案原文edgepodgetandrestart.mdkeadm 查询命令get/pod.go、请求封装 client/pod.go、MetaServer 客户端 metaclient.gokeadm 重启命令restart/pod.go、命令注册 ctl.goMetaServer 重启 handlerextend_restart_pod.go、CRI 停止容器 storage.go需要说明的是提案中的流程图描述的是设计阶段的方案当前仓库源码在细节上有所演进例如重启请求经 MetaServer 的pods/restart扩展子资源统一收口但“离线读 SQLite、重启只停容器不删沙箱、状态由 podpatch 保持新鲜”三条核心设计原则与提案完全一致。【免费下载链接】kubeedgeKubernetes Native Edge Computing Framework (project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/ku/kubeedge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价