ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Karmada karmadactl uncordon 命令详解:将集群重新标记为可调度

Karmada karmadactl uncordon 命令详解:将集群重新标记为可调度 Karmada karmadactl uncordon 命令详解将集群重新标记为可调度【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmadakarmadactl uncordon是 Karmada 多集群编排平台中用于解除集群封锁的命令它通过移除集群上的cluster.karmada.io/unschedulable污点taint将处于维护/封锁状态的成员集群重新标记为可调度schedulable从而让 Karmada 调度器可以再次向该集群分发工作负载。本文以 karmadactl uncordon 官方命令参考 为骨架结合 Karmada 仓库源码cordon 命令实现、污点常量定义、调度器 TaintToleration 插件深入讲解其用法、参数、底层原理与完整运维流程。读完本文你将掌握如何用一条命令安全地恢复一个被 cordon 的集群、--dry-run的预演用法、以及 uncordon 背后的污点-容忍调度机制。命令概述uncordon 与 cordon 的对称关系在 Karmada 中cordon与uncordon是一对互补的集群管理命令用于在不删除成员集群的前提下临时控制该集群是否接收新的调度任务命令作用默认调度行为karmadactl cordon CLUSTER将集群标记为不可调度unschedulable防止新资源被调度到该集群调度器不再向其分配新工作负载karmadactl uncordon CLUSTER将集群重新标记为可调度schedulable恢复其接收调度任务的能力调度器恢复向其分配工作负载从源码注释可以确认二者的语义定位cordon.gocordonLong templates.LongDesc( Mark cluster as unschedulable.) uncordonLong templates.LongDesc( Mark cluster as schedulable.)以及两个内部状态常量const ( // DesiredCordon a flag indicate karmadactl.RunCordonOrUncordon cordon a cluster, // cordon prevent new resource scheduler to cordoned cluster. DesiredCordon iota // DesiredUnCordon a flag indicate karmadactl.RunCordonOrUncordon uncordon a cluster. DesiredUnCordon )也就是说uncordon与cordon在实现上共享同一套核心逻辑RunCordonOrUncordon仅通过desired参数区分加污点与去污点两种动作。在 karmadactl 主命令注册处 中二者都被归入 Cluster Management Commands集群管理命令组与taint命令并列{ Message: Cluster Management Commands:, Commands: []*cobra.Command{ cordon.NewCmdCordon(f, parentCommand), cordon.NewCmdUncordon(f, parentCommand), taint.NewCmdTaint(f, parentCommand), }, },命令语法Synopsisuncordon命令的用法非常简洁只接收一个集群名作为位置参数karmadactl uncordon CLUSTER官方文档给出的标准示例是karmadactl_uncordon.md# Mark cluster foo as schedulable. karmadactl uncordon foo即执行karmadactl uncordon foo后名为foo的成员集群将被标记为可调度。参数约束从 cordon.go 的 Complete 方法 中可以明确看到func (o *CommandCordonOption) Complete(args []string) error { // Get cluster name from the command args. if len(args) 0 { return errors.New(cluster name is required) } if len(args) 1 { return errors.New(more than one cluster name is not supported) } o.ClusterName args[0] return nil }因此必须提供集群名缺省会直接报错cluster name is required一次只能操作一个集群传入多个名称会报错more than one cluster name is not supported集群名不支持通配符或批量操作需要逐个 uncordon。另外命令定义中通过ValidArgsFunction: utilcomp.SpecifiedResourceTypeAndNameCompletionFunc(f, []string{cluster})cordon.go为CLUSTER参数注册了基于集群资源的 shell 自动补全交互式终端下输入 Tab 可以提示当前已注册的集群名。选项Options详解uncordon自身的选项不含继承项如下表与 karmadactl_uncordon.md 完全一致选项类型说明--dry-runbool以 dry-run 模式运行命令不发起任何服务器请求仅模拟执行-h, --helpbool显示uncordon命令的帮助信息--karmada-context stringstring要使用的 kubeconfig 中的 context 名称--kubeconfig stringstringCLI 请求所使用的 kubeconfig 文件路径这些 flag 的来源可从源码确认NewCmdUncordon中通过options.AddKubeConfigFlags(flags)注册--kubeconfig与--karmada-context通过flags.BoolVar(opts.DryRun, dry-run, false, ...)注册--dry-runcordon.go。其中 kubeconfig 相关 flag 的具体实现在 pkg/karmadactl/options/global.go// AddKubeConfigFlags adds flags to the specified FlagSet. func AddKubeConfigFlags(flags *pflag.FlagSet) { flags.StringVar(DefaultConfigFlags.KubeConfig, kubeconfig, *DefaultConfigFlags.KubeConfig, Path to the kubeconfig file to use for CLI requests.) flags.StringVar(DefaultConfigFlags.Context, karmada-context, *DefaultConfigFlags.Context, The name of the kubeconfig context to use) }使用要点--kubeconfig默认取~/.kube/config即默认 kubeconfig 路径。uncordon操作的是 Karmada 控制面karmada-apiserver上的 Cluster 对象因此这里的 kubeconfig 必须指向包含 Karmada 控制面访问凭据的配置文件而不是成员集群的 kubeconfig--karmada-context当 kubeconfig 中包含多个 context例如同时有 Karmada 控制面与多个成员集群的 context时用它指定使用名为该值的 context 来发起请求--dry-run预演模式不真正修改集群状态适合在维护窗口前核对命令参数是否正确。关于 dry-run 的语义命令选项结构体注释 写得很清楚DryRun tells if run the command in dry-run mode, without making any server requests.dry-run 模式下完全不发起服务器请求。继承自父命令的选项Options inherited from parent commands与 Karmada 其他 CLI 命令一致uncordon还会继承一组来自 klog 的日志控制选项它们与命令本身的业务逻辑无关仅在排查 CLI 行为时需要关注选项说明--add-dir-header为日志消息头附加文件目录true 时生效--alsologtostderr同时将日志输出到 stderr 和文件当-logtostderrtrue时无效果--alsologtostderrthreshold severity当日志级别达到或超过该阈值时输出到 stderr--alsologtostderrtrue时生效--legacy-stderr-threshold-behavior为 true 时logtostderrtrue情况下忽略stderrthreshold默认 true--log-backtrace-at traceLocation当日志命中file:N时输出堆栈跟踪默认:0--log-dir string非空时日志文件写入该目录-logtostderrtrue时无效果--log-file string非空时使用该文件作为日志文件-logtostderrtrue时无效果--log-file-max-size uint日志文件最大大小MB0 表示不限制默认 1800--logtostderr将日志输出到 stderr 而非文件默认 true--one-output为 true 时只向日志自身的原生级别写入不再向更低级别写入-logtostderrtrue时无效果--skip-headers为 true 时日志消息不添加头部前缀--skip-log-headers为 true 时打开日志文件时不写头部-logtostderrtrue时无效果--stderrthreshold severity日志级别达到或超过该阈值时输出到 stderr默认 2-v, --v Level日志详细程度级别--vmodule moduleSpec以patternN逗号分隔列表形式按文件过滤日志级别这些继承选项与karmadactl主命令共享完整清单见 karmadactl_uncordon.md。实战用法完整运维流程示例典型场景集群维护与恢复Karmada 中 uncordon 最常见的应用场景是集群维护窗口管理# 1. 查看当前已加入 Karmada 的成员集群 karmadactl get clusters # 2. 进入维护前封锁目标集群停止接收新的调度任务 karmadactl cordon member-cluster-1 # 3. 确认封锁生效可观察到集群状态或结合 scheduler 日志确认 karmadactl get cluster member-cluster-1 -o yaml # 此时 member-cluster-1 的 spec.taints 中应包含: # - effect: NoSchedule # key: cluster.karmada.io/unschedulable # 4. 维护完成后解除封锁恢复调度能力 karmadactl uncordon member-cluster-1 # 5. 结果确认控制台输出 member-cluster-1 cluster uncordoned预演Dry-run用法在对生产集群执行 uncordon 前可以先预演一遍karmadactl uncordon member-cluster-1 --dry-rundry-run 模式下命令不会向 karmada-apiserver 发起任何写请求输出结果与真实执行一致member-cluster-1 cluster uncordoned可用于核对集群名、context 等参数是否配置正确。指定 kubeconfig 与 context当你的 kubeconfig 同时包含多个 Karmada 控制面如多套环境时# 使用指定 kubeconfig 文件 karmadactl uncordon foo --kubeconfig /path/to/karmada.config # 使用 kubeconfig 中的指定 context karmadactl uncordon foo --karmada-context karmada-prod底层原理污点Taint机制uncordon并不是直接修改集群的某个调度开关字段而是通过 Kubernetes 标准的污点Taint机制实现的。命令内部操作的关键对象是集群spec.taints中的一条不可调度污点。不可调度污点的定义污点的键名定义在 pkg/apis/cluster/v1alpha1/well_known_constants.goconst ( // TaintClusterUnscheduler will be added when cluster becomes unschedulable // and removed when cluster becomes schedulable. TaintClusterUnscheduler cluster.karmada.io/unschedulable // TaintClusterNotReady will be added when cluster is not ready // and removed when cluster becomes ready. TaintClusterNotReady cluster.karmada.io/not-ready // TaintClusterUnreachable will be added when cluster becomes unreachable // (corresponding to ClusterConditionReady status ConditionUnknown) // and removed when cluster becomes reachable (ClusterConditionReady status ConditionTrue). TaintClusterUnreachable cluster.karmada.io/unreachable )其中TaintClusterUnschedulercluster.karmada.io/unschedulable是 cordon/uncordon 命令专门操作的污点其 Effect 为NoSchedule由命令内部构造unschedulerTaint : corev1.Taint{ Key: clusterv1alpha1.TaintClusterUnscheduler, Effect: corev1.TaintEffectNoSchedule, }对应地TaintClusterNotReadycluster.karmada.io/not-ready与TaintClusterUnreachablecluster.karmada.io/unreachable是由集群控制器根据集群健康状态自动添加的污点与手动运维的 uncordon 命令无关。uncordon 的执行链路uncordon的完整执行链路在 cordon.go 的 RunCordonOrUncordon 中func RunCordonOrUncordon(desired int, f util.Factory, opts CommandCordonOption) error { cordonOrUncordon : cordon if desired DesiredUnCordon { cordonOrUncordon un cordonOrUncordon } karmadaClient, err : f.KarmadaClientSet() if err ! nil { return err } cluster, err : karmadaClient.ClusterV1alpha1().Clusters().Get(context.TODO(), opts.ClusterName, metav1.GetOptions{}) if err ! nil { return err } cordonHelper : newCordonHelper(cluster) if !cordonHelper.updateIfRequired(desired) { fmt.Printf(%s cluster %s\n, cluster.Name, alreadyStr(desired)) return nil } if !opts.DryRun { err : cordonHelper.patchOrReplace(karmadaClient) if err ! nil { return err } } fmt.Printf(%s cluster %sed\n, cluster.Name, cordonOrUncordon) return nil }流程可以拆解为四步获取集群对象通过KarmadaClientSet().ClusterV1alpha1().Clusters().Get()从 karmada-apiserver 读取目标 Cluster 的完整对象判断是否真的需要变更调用updateIfRequired检查目标状态。若集群本来就没有/本来就有不可调度污点则直接输出already uncordoned/already cordoned并返回不产生任何写操作非 dry-run 时写回通过patchOrReplace将变更后的污点列表写回 karmada-apiserver输出结果成功执行后输出xxx cluster uncordoned。幂等性判断逻辑updateIfRequiredcordon.go保证了命令的幂等性func (c *cordonHelper) updateIfRequired(desired int) bool { c.desired desired if desired DesiredCordon !c.hasUnschedulerTaint() { return true } if desired DesiredUnCordon c.hasUnschedulerTaint() { return true } return false } func (c *cordonHelper) hasUnschedulerTaint() bool { unschedulerTaint : corev1.Taint{ Key: clusterv1alpha1.TaintClusterUnscheduler, Effect: corev1.TaintEffectNoSchedule, } for _, taint : range c.cluster.Spec.Taints { if taint.MatchTaint(unschedulerTaint) { return true } } return false }执行 uncordon 时若集群存在cluster.karmada.io/unschedulableNoSchedule污点 → 执行移除若集群不存在该污点 → 输出cluster cluster already uncordoned直接结束。这意味着重复执行 uncordon 是安全的不会报错也不会产生多余的 API 请求。写回方式优先补丁回退更新patchOrReplacecordon.go采用优先 patch、失败则 update的策略patchBytes, err : strategicpatch.CreateTwoWayMergePatch(oldData, newData, c.cluster) if err nil { _, err client.Patch(context.TODO(), c.cluster.Name, types.MergePatchType, patchBytes, metav1.PatchOptions{}) } else { _, err client.Update(context.TODO(), c.cluster, metav1.UpdateOptions{}) }先将修改前后的 Cluster 对象分别序列化为 JSON尝试生成strategic merge patch生成成功则走PatchMergePatchType请求避免覆盖其他字段的并发修改若 patch 构造失败例如对象无法编码为 JSON则退化为整对象Update。对于 uncordonDesiredUnCordon移除污点的实现是典型的swap-and-truncate技巧从 taints 切片中定位匹配项后与最后一个元素交换再截断切片if c.desired DesiredUnCordon { for i, n : 0, len(c.cluster.Spec.Taints); i n; i { if c.cluster.Spec.Taints[i].MatchTaint(unschedulerTaint) { c.cluster.Spec.Taints[i] c.cluster.Spec.Taints[n-1] c.cluster.Spec.Taints c.cluster.Spec.Taints[:n-1] break } } }注意这里只移除第一个匹配的不可调度污点同时由于只匹配KeyEffectMatchTaint不校验Value即使污点带任意 Value 也会被匹配移除。调度器如何响应TaintToleration 插件了解 uncordon 如何生效还需要理解调度器侧对污点的处理。Karmada 调度器的TaintToleration过滤插件pkg/scheduler/framework/plugins/tainttoleration/taint_toleration.go会在调度每个 ResourceBinding 时检查目标集群的污点是否被传播策略的clusterTolerations容忍filterPredicate : func(t *corev1.Taint) bool { return t.Effect corev1.TaintEffectNoSchedule || t.Effect corev1.TaintEffectNoExecute } taint, isUntolerated : v1helper.FindMatchingUntoleratedTaint(klog.Background(), cluster.Spec.Taints, bindingSpec.Placement.ClusterTolerations, filterPredicate, false) if !isUntolerated { return framework.NewResult(framework.Success) } return framework.NewResult(framework.Unschedulable, fmt.Sprintf(cluster(s) had untolerated taint {%s}, taint.ToString()))核心结论当集群带有cluster.karmada.io/unschedulableEffectNoSchedule污点且对应传播策略的 Placement 中没有配置能容忍该污点的clusterTolerations时该集群在调度过滤阶段会被判定为Unschedulable调度器不会向它分发新的工作负载执行karmadactl uncordon移除该污点后集群重新通过 TaintToleration 过滤恢复接收新调度任务的能力。因此uncordon的完整生效链路是命令移除集群污点 → 调度器过滤插件重新评估 → 集群恢复可调度。相关字段Placement 中的 clusterTolerations与污点机制配套的ClusterTolerations字段定义在传播策略 API 中pkg/apis/policy/v1alpha1/propagation_types.go// ClusterTolerations represents the tolerations. // optional ClusterTolerations []corev1.Toleration json:clusterTolerations,omitempty它是一个corev1.Toleration切片语义与 Kubernetes Pod 的 tolerations 一致。运维上这意味着即使集群被 cordon带有 NoSchedule 污点只要某个 PropagationPolicy/ClusterPropagationPolicy 在 Placement 中显式配置了匹配该污点的容忍例如key: cluster.karmada.io/unschedulableeffect: NoSchedule调度器仍可能将特定工作负载调度到该集群——这是强制调度的合法通道与 uncordon 的全局恢复调度形成互补。测试验证行为由单元测试保障uncordon的行为有完整的单元测试覆盖见 pkg/karmadactl/cordon/cordon_test.go。TestRunCordonOrUncordon使用 fake clientset 覆盖了四种组合场景测试用例前置状态操作期望输出CordonUncordonedCluster_ClusterCordoned未封锁cordonname cluster cordonedCordonCordonedCluster_ClusterAlreadyCordoned已封锁cordonname cluster already cordonedUncordonCordonedCluster_ClusterUncordoned已封锁uncordonname cluster uncordonedUncordonUncordonedCluster_ClusterAlreadyUncordoned未封锁uncordonname cluster already uncordoned测试中的状态校验函数checkClusterCordonedCondition/checkClusterUncordonedCondition直接断言集群spec.taints中是否存在cluster.karmada.io/unschedulableNoSchedule组合var checkClusterUncordonedCondition func(cluster *clusterv1alpha1.Cluster) error { for _, taint : range cluster.Spec.Taints { if taint.Key clusterv1alpha1.TaintClusterUnscheduler taint.Effect corev1.TaintEffectNoSchedule { return fmt.Errorf(expected no noschedule taint for cluster %s, but got %v, cluster.GetName(), taint) } } return nil }这从测试层面再次印证uncordon 的本质就是确保集群 spec.taints 中不存在不可调度污点且对已处于可调度状态的集群重复执行会输出already uncordoned而不是报错。关联命令与进一步阅读karmadactl cordon与 uncordon 配套的封锁命令二者共享同一实现cordon.gokarmadactl taint手动为集群添加/移除任意污点比 cordon 更灵活适用于自定义调度约束karmadactl 命令总览查看全部 karmadactl 子命令调度器侧污点容忍过滤插件实现pkg/scheduler/framework/plugins/tainttoleration/taint_toleration.go污点常量定义pkg/apis/cluster/v1alpha1/well_known_constants.go。小结karmadactl uncordon是 Karmada 集群日常运维中恢复调度的标准动作核心要点可归纳为用法极简karmadactl uncordon CLUSTER一次只能操作一个集群本质是污点操作命令移除集群上的cluster.karmada.io/unschedulableNoSchedule污点而非修改其他调度字段幂等安全对已可调度的集群重复执行输出already uncordoned不会产生副作用预演友好--dry-run模式下不发起任何服务器请求可在维护窗口前安全验证与调度器联动污点移除后调度器的 TaintToleration 过滤插件才会允许新工作负载调度到该集群配合 Placement 的clusterTolerations可实现强制调度等高级策略。掌握cordon/uncordon/taint这三个命令的组合使用即可在不删除集群的前提下对多集群调度行为进行精细的维护控制。【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmada创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表