Scheduler-Framework中的Permit使用和注意事项

解释

Scheduler-Framework的介绍现在也比较多了,这篇文章假设您已经了解Scheduler-Framework的框架和每个扩展点的作用。
如果想全面了解,可以参阅:
《浅谈 Kubernetes Scheduling-Framework 插件的实现》
《自定义 Kubernetes 调度器》
《kube-scheduler》
接下来,我们就重点说说Permit
Permit
Permit用户阻止或者延迟与Node绑定,属于Binding Cycle阶段,就是说,此时Permit已经经过了预选、优选和打分,确定了将要binding到那个node上。Permit主要有三个作用:

  • allow(批准):当所有的 permit 扩展都 allow 了 Pod 与节点的绑定,调度器将继续执行绑定过程
  • deny(拒绝):如果任何一个 permit 扩展 deny 了 Pod 与节点的绑定,Pod 将被放回到待调度队列,此时将触发 Unreserve 扩展
  • wait(等待):如果一个 permit 扩展返回了 wait,则 Pod 将保持在 permit 阶段,直到被其他扩展 allow,如果超时事件发生,wait 状态变成 deny,Pod 将被放回到待调度队列,此时将触发 Unreserve 扩展

理解完Permit作用之后,解释一下:

  1. 如果allow之后,pod将会被移除waitingPod的队列,进入pre-bind、bind、post-bind扩展。
  2. 如果返回wait,并且带有超时设定时间,则会进入waitingPod队列,进行等待。如果在超时时间满足后,仍然没有被批准,就会触发unreserve,并且会重新调度。

使用

写个简单的例子:

func (s *Sample) Permit(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (*framework.Status, time.Duration) {
	s.Handle.IterateOverWaitingPods(func(waitingPod framework.WaitingPod) {
		if _, ok := waitingPod.GetPod().Annotations["test-label"]; ok {
			waitingPod.Allow(po.Name())
		}
	})
	
	if _, ok := pod.Annotations["test-label"]; !ok {
		return framework.NewStatus(framework.Wait, "wait label add"), 20 * time.Minute
	}

	return nil, 0
}

当执行到permit时,会检查pod是否有test-label的注解,如果没有。则等待20分钟。在IterateOverWaitingPods会遍历waitingPod
检测到存在test-label的注解则允许其创建。

注意事项

  1. 上面代码有一个使用误区:
return framework.NewStatus(framework.Wait, "wait label add"), 20 * time.Minute

看下官方的解释

源码:k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1/framework.go +759
	if status.Code() == Wait {
		// Not allowed to be greater than maxTimeout.
		if timeout > maxTimeout {
			timeout = maxTimeout
		}
		pluginsWaitTime[pl.Name()] = timeout
		statusCode = Wait
	} else {
		msg := fmt.Sprintf("error while running %q permit plugin for pod %q: %v", pl.Name(), pod.Name, status.Message())
		klog.Error(msg)
		return NewStatus(Error, msg)
	}

看看 maxTimeout 是什么?

	// Specifies the maximum timeout a permit plugin can return.
	maxTimeout                  time.Duration = 15 * time.Minute

也就是说,permit 超时的最长时间是15分钟。

  1. permit的执行是单例执行的,也就是在wait期间其他的扩展不会被执行,社区也在提这个问题,现在的建议是使用goroutine。
  2. 不要在permit尝试修改pod的信息,否则会引发,scheduler cache AssumePod failed 错误。
  3. waitingPod的最好在permit阶段批准
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,您想了解关于Java的Scheduler以及如何使用它,以下是我为您搜集到的相关信息: Scheduler是Java的一个工具,它用于在指定的时间间隔内执行任务。Java提供了两种类型的Scheduler:Timer和ScheduledExecutorService。 Timer是Java提供的最简单的Scheduler,它允许您安排以固定速率重复执行任务,或者在指定时间内执行任务一次。但是,Timer有一些缺点,例如不能处理多个任务、不能很好地处理异常等。 相比之下,ScheduledExecutorService是Java提供的更高级的Scheduler,它提供了更多的灵活性和控制。ScheduledExecutorService可以安排一个或多个任务在指定时间内执行,也可以安排任务重复执行。此外,它还提供了更好的异常处理和更高的性能。 下面是使用ScheduledExecutorService的示例代码: ``` import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class SchedulerDemo { public static void main(String[] args) { ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); // 安排任务在5秒后执行 scheduler.schedule(new Task(), 5, TimeUnit.SECONDS); // 安排任务在每秒钟执行一次 scheduler.scheduleAtFixedRate(new Task(), 0, 1, TimeUnit.SECONDS); // 关闭scheduler scheduler.shutdown(); } static class Task implements Runnable { @Override public void run() { // 执行任务的代码 } } } ``` 在上面的代码,我们创建了一个ScheduledExecutorService,然后安排了两个任务。第一个任务会在5秒后执行一次,第二个任务会每秒钟执行一次。最后,我们关闭了scheduler。 希望这些信息能够帮助到您,如果您有任何问题或需要进一步了解,请随时告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xf491698144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值