调度框架

This commit is contained in:
huanqing.shao
2019-10-13 10:44:05 +08:00
parent b4a2a48480
commit f90a593a8a
21 changed files with 430 additions and 81 deletions

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="adsense-banner" @click="$sendGaEvent('AdSense', 'AdSenseBanner', 'AdSenseBanner')"> <div class="adsense-banner">
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- 正文-横幅 --> <!-- 正文-横幅 -->
<ins class="adsbygoogle" <ins class="adsbygoogle"

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="adsense-left-top" @click="$sendGaEvent('AdSense', 'AdSenseLeftTop', 'AdSenseLeftTop')"> <div class="adsense-left-top">
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- AdsenseLeftTop --> <!-- AdsenseLeftTop -->
<ins class="adsbygoogle" <ins class="adsbygoogle"

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="adsense-page-bottom" @click="$sendGaEvent('AdSense', 'AdSensePageBottom', 'AdSensePageBottom')"> <div class="adsense-page-bottom">
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- AdSensePageBottom --> <!-- AdSensePageBottom -->
<ins class="adsbygoogle" <ins class="adsbygoogle"

View File

@ -21,7 +21,7 @@ export default {
<style scoped> <style scoped>
.adsense-page-bottom-inline { .adsense-page-bottom-inline {
border: 1px solid #d7dae2; border: 1px solid #d7dae2;
height: 160px; max-height: 160px;
overflow: hidden; overflow: hidden;
} }
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="adsense-page-top" @click.capture="$sendGaEvent('AdSense', 'AdSensePageTop', 'AdSensePageTop')"> <div class="adsense-page-top">
<!-- <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle" <ins class="adsbygoogle"
style="display:block; text-align:center;" style="display:block; text-align:center;"

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="adsense-paragraph" @click="$sendGaEvent('AdSense', 'AdSenseParagraph', 'AdSenseParagraph')"> <div class="adsense-paragraph">
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle" <ins class="adsbygoogle"
style="display:block; text-align:center;" style="display:block; text-align:center;"

View File

@ -1,14 +1,13 @@
<template> <template>
<div class="adsense-right" @click="$sendGaEvent('AdSense', 'AdSenseRightSide', 'AdSenseRightSide')"> <div class="adsense-right">
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- 右侧垂直 --> <!-- AdSenseRightSide -->
<ins class="adsbygoogle" <ins class="adsbygoogle"
style="display:block; height: 40vh; max-width: calc(50vw - 720px); min-width: 200px;" style="display:block"
data-ad-client="ca-pub-3313149841665250" data-ad-client="ca-pub-3313149841665250"
data-ad-slot="2638666669" data-ad-slot="2638666669"
></ins> data-ad-format="auto"
<!-- data-ad-format="auto" data-full-width-responsive="true"></ins>
data-full-width-responsive="true" -->
<script> <script>
(adsbygoogle = window.adsbygoogle || []).push({}); (adsbygoogle = window.adsbygoogle || []).push({});
</script> </script>
@ -28,13 +27,13 @@ export default {
<style scoped> <style scoped>
.adsense-right { .adsense-right {
width: 500px; width: calc(50vw - 700px);
max-width: calc(50vw - 720px); max-width: 450px;
height: 40vh; height: 50vh;
position: fixed; position: fixed;
bottom: 80px; bottom: 80px;
right: 10px; right: 10px;
/* background-color: grey; */ background-color: grey;
} }
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div @click="$sendGaEvent('AdSense', 'AdSenseSquare', 'AdSenseSquare')"> <div>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- 正方形-正文 --> <!-- 正方形-正文 -->
<ins class="adsbygoogle" <ins class="adsbygoogle"

View File

@ -1,24 +1,31 @@
<template> <template>
<div class="adsense-under-title" @click="$sendGaEvent('AdSense', 'AdSensePageTopUnderTitle', 'AdSensePageTopUnderTitle')"> <div>
<!-- <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> --> <p>
<!-- PageTopUnderTitle --> <Qq></Qq> 群号: 808894550 <span style="color: red; font-weight: 500;">在线答疑</span>也可以扫描本文末尾的二维码加群
<!-- <ins class="adsbygoogle" </p>
style="display:inline-block;min-width:200px;max-width:1000px;width:100%;height:50px" <slot></slot>
data-ad-client="ca-pub-3313149841665250" <div class="adsense-page-top">
data-ad-slot="1677363818"></ins> <!-- <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script> <ins class="adsbygoogle"
(adsbygoogle = window.adsbygoogle || []).push({}); style="display:block; text-align:center;"
</script> --> data-ad-layout="in-article"
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> data-ad-format="fluid"
<ins class="adsbygoogle" data-ad-client="ca-pub-3313149841665250"
style="display:block" data-ad-slot="6968314981"></ins>
data-ad-format="fluid" <script>
data-ad-layout-key="-i0-3+1f-3d+2z" (adsbygoogle = window.adsbygoogle || []).push({});
data-ad-client="ca-pub-3313149841665250" </script> -->
data-ad-slot="3534684042"></ins> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script> <ins class="adsbygoogle"
(adsbygoogle = window.adsbygoogle || []).push({}); style="display:block"
</script> data-ad-format="fluid"
data-ad-layout-key="-h2+d+5c-9-3e"
data-ad-client="ca-pub-3313149841665250"
data-ad-slot="4299889232"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div> </div>
</template> </template>
@ -29,7 +36,12 @@ export default {
</script> </script>
<style scoped> <style scoped>
.adsense-under-title { .adsense-page-top {
/* background-color: green; */
cursor: pointer;
padding-right: 2px;
border: 1px solid #d7dae2; border: 1px solid #d7dae2;
height: 124px !important;
overflow: hidden;
} }
</style> </style>

View File

@ -0,0 +1,35 @@
<template>
<div class="adsense-under-title">
<!-- <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> -->
<!-- PageTopUnderTitle -->
<!-- <ins class="adsbygoogle"
style="display:inline-block;min-width:200px;max-width:1000px;width:100%;height:50px"
data-ad-client="ca-pub-3313149841665250"
data-ad-slot="1677363818"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script> -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout-key="-i0-3+1f-3d+2z"
data-ad-client="ca-pub-3313149841665250"
data-ad-slot="3534684042"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.adsense-under-title {
border: 1px solid #d7dae2;
}
</style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div @click="$sendGaEvent('AdSense', 'AdSenseVertical', 'AdSenseVertical')"> <div>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- 正文-垂直 --> <!-- 正文-垂直 -->
<ins class="adsbygoogle" <ins class="adsbygoogle"

View File

@ -443,6 +443,8 @@ module.exports = {
collapsable: true, collapsable: true,
children: [ children: [
'k8s-advanced/schedule/', 'k8s-advanced/schedule/',
'k8s-advanced/schedule/tuning',
'k8s-advanced/schedule/framework',
] ]
}, },
] ]

View File

@ -34,15 +34,8 @@
<div class="tip custom-block" style="padding: 10px 20px; margin-top: 0;"> <div class="tip custom-block" style="padding: 10px 20px; margin-top: 0;">
<div style="display: inline-block; vertical-align: top;"> <div style="display: inline-block; vertical-align: top;">
<li><span style="color: red; font-weight: 500;">免费</span> Kubernetes 教程绝不降低品质</li> <li><span style="color: red; font-weight: 500;">免费</span> Kubernetes 教程绝不降低品质</li>
<!-- <li><span style="color: red; font-weight: 500;">在线答疑</span> 扫第一个二维码完成打赏扫第二个进微信群聊</li> --> <!-- <li><Qq></Qq> <span style="color: red; font-weight: 500;">在线答疑</span>也可以扫描本文末尾的二维码加群</li> -->
<li><Qq></Qq> <span style="color: red; font-weight: 500;">在线答疑</span>也可以扫描本文末尾的二维码加群</li>
<!-- <li>根据答疑反馈<span style="color: red; font-weight: 500;">不断完善</span> 教程</li> -->
</div> </div>
<!-- <div style="display: inline-block; margin-left: 10px;">
<img src="/images/dz.png" style="width: 100px; margin-right: 100px;"></img>
<img src="/images/dz2.jpeg" style="width: 100px;"></img>
</div> -->
</div> </div>
</div> </div>
<div slot="page-bottom" class="bottom-description">Copyright © 2019-present 邵欢庆 <a href="http://www.eigpay.com" target="_blank">仁聚汇通</a> | 京ICP备19008693号-2 <div slot="page-bottom" class="bottom-description">Copyright © 2019-present 邵欢庆 <a href="http://www.eigpay.com" target="_blank">仁聚汇通</a> | 京ICP备19008693号-2

View File

@ -29,7 +29,7 @@ meta:
# 使用kubeadm安装kubernetes_v1.16.1 # 使用kubeadm安装kubernetes_v1.16.1
<AdSenseTitle/> <!-- <AdSenseTitle/> -->
<script> <script>
@ -158,29 +158,18 @@ export default {
* **Cent OS 7.6** * **Cent OS 7.6**
<grid :rwd="{compact: 'stack'}"> <grid :rwd="{compact: 'stack'}">
<grid-item size="1/2" :rwd="{tablet: '1/1', compact: '1/1'}" style="padding: 1rem 0 1rem 1rem;"> <grid-item size="2/3" :rwd="{tablet: '1/1', compact: '1/1'}" style="padding: 1rem 0 1rem 1rem;">
<div> <div>
[领取腾讯云最高2860元代金券](https://cloud.tencent.com/act/cps/redirect?redirect=1040&cps_key=2ee6baa049659f4713ddc55a51314372&from=console)
[腾讯云限时1折秒杀](https://cloud.tencent.com/act/cps/redirect?redirect=1044&cps_key=2ee6baa049659f4713ddc55a51314372&from=console)
[领取阿里云最高2000元红包](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=obezo3pg) [领取阿里云最高2000元红包](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=obezo3pg)
[阿里云服务器限时2折](https://www.aliyun.com/acts/limit-buy?userCode=obezo3pg) [阿里云服务器限时2折](https://www.aliyun.com/acts/limit-buy?userCode=obezo3pg)
</div>
</grid-item>
<grid-item size="1/2" :rwd="{tablet: '1/1', compact: '1/1'}" style="padding: 2rem 1rem 1rem 1rem;">
<a href="https://cloud.tencent.com/act/cps/redirect?redirect=1040&cps_key=2ee6baa049659f4713ddc55a51314372&from=console">
<img src="/images/pr/tencent-345x200-.jpg" alt="Kubernetes安装_服务器选择" style="width: 270px;">
</a>
</grid-item>
</grid>
<grid :rwd="{compact: 'stack'}">
<grid-item size="2/3" :rwd="{tablet: '1/1', compact: '1/1'}" style="padding: 1rem 0 1rem 1rem;">
<div>
**安装后的软件版本为** **安装后的软件版本为**
* Kubernetes v1.16.1 * Kubernetes v1.16.1

View File

@ -10,18 +10,21 @@ meta:
# Kubernetes免费中文教程 # Kubernetes免费中文教程
<AdSenseTitle/> <AdSenseTitle>
本教程的主要依据是Kubernetes 官网文档,以及使用 Kubernetes 落地 Spring Cloud 微服务并投产的实战经验。适用人群: 本教程的主要依据是Kubernetes 官网文档,以及使用 Kubernetes 落地 Spring Cloud 微服务并投产的实战经验。适用人群:
* Kubernetes 初学者 * Kubernetes 初学者
* 学习过 Kubernetes但在投产过程中仍有诸多疑虑和困惑的技术爱好者 * 学习过 Kubernetes但在投产过程中仍有诸多疑虑和困惑的技术爱好者
<div style="background-color: #0063dc;"> </AdSenseTitle>
<!-- <div style="background-color: #0063dc;">
<div style="max-width: 363px; margin: auto;"> <div style="max-width: 363px; margin: auto;">
<img src="/images/logo-main.png" style="background-color: #0063dc; max-width: 100%;" alt="Kubernetes管理界面Kuboard Logo"/> <img src="/images/logo-main.png" style="background-color: #0063dc; max-width: 100%;" alt="Kubernetes管理界面Kuboard Logo"/>
</div> </div>
</div> </div> -->
## **Kubernetes 介绍** ## **Kubernetes 介绍**
@ -88,10 +91,12 @@ meta:
## **Kubernetes 高级** ## **Kubernetes 高级**
* [Kubernetes 日志](/learning/k8s-advanced/logs/) * [问题诊断](/learning/k8s-advanced/ts/application.html)
* Kubernetes 监控 * [日志](/learning/k8s-advanced/logs/)
* Kubernetes 联邦 * [调度](/learning/k8s-advanced/schedule)
* 扩展 Kubernetes * 安全
* 监控
* 联邦
## **Kubernetes 实战** ## **Kubernetes 实战**

View File

@ -11,9 +11,8 @@ description: Kubernetes教程_高级篇_主要涉及日志采集_安全_监控_
Kubernetes教程的深入篇部分主要涉及的内容有如下几个方面 Kubernetes教程的深入篇部分主要涉及的内容有如下几个方面
* [问题诊断](./ts/application.html) * [问题诊断](./ts/application.html)
* [Kubernetes 日志](./logs/) * [日志](./logs/)
* Kubernetes 安全 * [调度](./schedule)
* Kubernetes 监控 * 安全
* Kubernetes 联邦 * 监控
* 联邦
将在 Kubernetes 教程进阶篇,以及 Kubernetes 教程的实战篇完成后开始编写。

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -0,0 +1,238 @@
---
vssueId: 131
layout: LearningLayout
description: Kubernete教程_Kubernetes v1.15 版本中引入了可插拔架构的调度框架,使得定制调度器这个任务变得更加的容易。调库框架向现有的调度器中添加了一组插件化的 API。
meta:
- name: keywords
content: Kubernetes 教程,Kubernetes 调度,Kubernetes Scheduling
---
# 框架
> 参考文档:[Scheduling Framework](https://kubernetes.io/docs/concepts/configuration/scheduling-framework/)
<AdSenseTitle/>
**FEATURE STATE** `Kubernetes v1.15` <Badge type="error">alpha</Badge>
Kubernetes v1.15 版本中引入了可插拔架构的调度框架,使得定制调度器这个任务变得更加的容易。调库框架向现有的调度器中添加了一组插件化的 API。该 API在保持调度程序“核心”保持简单且易于维护的同时使得大部分的调度功能以插件的形式存在。参考 [Design proposal of the scheduling framework](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20180409-scheduling-framework.md) 可了解调度框架更多的技术细节。
## 工作流
调度框架定义了一组扩展点。用户可以实现扩展点定义的接口以定义自己的调度逻辑(我们称之为扩展),并将扩展注册到扩展点上,调度框架在执行调度工作流时,遇到对应的扩展点时,将调用用户注册的扩展。调度框架在预留扩展点时,都是有特定的目的,有些扩展点上的扩展可以改变调度程序的决策方法,有些扩展点上的扩展只是发送一个通知。
## 调度过程/绑定过程
参考 [调度](./) 中所描述的,每一次调度一个 Pod 时,都按照两个过程来执行:调度过程和绑定过程。
调度过程为 Pod 选择一个合适的节点,绑定过程则将调度过程的决策应用到集群中(在被选定的节点上运行 Pod。调度过程和绑定过程合在一起称之为 **调度上下文scheduling context**
调度过程同步运行(同一时间点只为一个 Pod 进行调度),绑定过程可异步运行(同一时间点可并发为多个 Pod 执行绑定)。
调度过程和绑定过程在如下情况时,会中途退出:
* 调度程序认为当前没有该 Pod 的可选节点
* 内部错误
此时Pod 将被放回到 待调度队列,并等待下次重试。
## 扩展点 Extension Points
下图展示了调度框架中的调度上下文及其中的扩展点。该图中 “Filter过滤器”与“Soring评分”的解释请参考 [使用kube-scheduler调度](learning/k8s-advanced/schedule/#使用kube-scheduler调度)。
一个扩展可以注册多个扩展点,以便可以执行更复杂的有状态的任务。
<p style="max-width: 750px">
<img src="./framework.assets/scheduling-framework-extensions.png" style="padding: 5px;" alt="Kubernetes教程_调度框架及扩展点"/>
</p>
### Queue sort
Que sort 扩展用于对 Pod 的待调度队列进行排序,以决定先调度哪个 Pod。 Que sort扩展本质上只需要实现一个方法 `less(Pod1, Pod2)` 用于比较两个 Pod 谁更优先获得调度。同一时间点只能有一个 que sort 插件生效。
### Pre-filter
Pre-filter 扩展用于对 Pod 的信息进行预处理,或者检查一些集群或 Pod 必须满足的前提条件。如果 pre-filter 返回了 error则调度过程终止。
### Filter
Filter 扩展用于排除那些不能运行该 Pod 的节点。对于每一个节点,调度器将按顺序执行 filter 扩展;如果任何一个 filter 将节点标记为不可选,则余下的 filter 扩展将不会被执行。调度器可以同时对多个节点执行 filter 扩展。
### Post-filter
Post-filter 是一个通知类型的扩展点。调用该扩展的参数是 filter 阶段结束后被筛选为 ***可选节点*** 的节点列表。可以在扩展中使用这些信息更新内部状态,或者产生日志或度量信息。
::: tip
如果想要在 "Scoring" 评分工作之前执行一些逻辑,应该实现 post-filter 扩展点。
:::
### Scoring
Scoring 扩展用于为所有可选节点评分。调度器将针对每一个节点调用 Soring 扩展。评分结果是一个范围内的整数。在 `normalize scoring` 阶段,调度器将会把每个 scoring 扩展对具体某个个节点的评分结果和该扩展的权重合并起来,作为最终评分结果。
### Normalize scoring
Normalize scoring 扩展在调度器对节点进行最终排序之前修改每个节点的评分结果。注册到该扩展点的扩展时在被调用时,将获得同一个插件中的 scoring 扩展的评分结果作为参数。调度框架每执行一次调度,都将调用所有插件中的一个 normalize scoring 扩展一次。
::: tip 译者注
如前所述,一个插件中可以包括多个扩展,每个扩展可以注册到调度框架中的一个扩展点。可以认为
* 插件是扩展的打包
* 扩展是针对扩展点的实现
* 扩展点是调度框架预先定义的可插拔可客户化的接口,必须有实现该扩展点接口的扩展注册到调度框架
:::
例如,假设 `BlinkingLightScorer` 插件注册了 scoring 扩展点,该扩展根据节点拥有的 "blinking lights" 数量对节点评分。blinking light是假想的一个节点属性
``` go
func ScoreNode(_ *v1.pod, n *v1.Node) (int, error) {
return getBlinkingLightCount(n)
}
```
然而Scoring 扩展对节点计算出来的 `NodeScoreMax`(节点实际的 `blinking light` 最大数)可能比评分结果允许的 `blinking light` 最大数要大。为了修正此问题,`BlinkingLightScorer` 插件同样要注册 Normalize scoring 扩展点,逻辑如下所示:
``` go
func NormalizeScores(scores map[string]int) {
highest := 0
for _, score := range scores {
highest = max(highest, score)
}
for node, score := range scores {
scores[node] = score*NodeScoreMax/highest
}
}
```
如果任何一个 normalize-scoring 插件返回了错误,调度过程将终止。
::: tip
如果想要在 `Reserve` 之前执行某些逻辑,可以使用 `normalize-scoring` 扩展点。
:::
### Reserve
Reserve 是一个通知性质的扩展点。有状态的插件可以使用该扩展点获得如下通知:已在节点上为 Pod 预留资源。该事件发生在调度器将 Pod 绑定到节点之前,目的是避免调度器在等待 Pod 与节点绑定的过程中调度新的 Pod 到节点上时,发生实际使用资源超出可用资源的情况。(如前面所述,绑定 Pod 到节点上是异步发生的)
这是调度过程的最后一个步骤。Pod 进入 `reserved` 状态以后,要么在绑定失败时触发 [Unreserve](#unreserve) 扩展,要么在绑定成功时,由 [Post-bind](#post-bind) 扩展结束绑定过程。
### Permit
Permit 扩展用于阻止或者延迟 Pod 与节点的绑定。Permit 扩展可以做如下三项当中的一个选择:
* **approve**
当所有的 permit 扩展都 `approve`(批准)了 Pod 与节点的绑定,调度器将继续执行绑定过程
* **deny**
如果任何一个 permit 扩展 `deny`(拒绝)了 Pod 与节点的绑定Pod 将被放回到待调度队列,此时将触发 [Unreserve](#unreserve) 扩展
* **wait** (等待超时时间)
如果一个 permit 扩展返回了 `wait`(等待),则 Pod 将保持在 permit 阶段,直到被其他扩展 approve。如果超时事件发生`wait` 状态变成 `deny`Pod 将被放回到待调度队列,此时将触发 [Unreserve](#unreserve) 扩展
### Pre-bind
Pre-bind 扩展用于在 Pod 绑定之前执行某些逻辑。例如pre-bind 扩展可以将一个基于网络的数据卷挂载到节点上,以便 Pod 可以使用。
如果任何一个 pre-bind 扩展返回错误Pod 将被放回到待调度队列,此时将触发 [Unreserve](#unreserve) 扩展
### Bind
Bind 扩展用于将 Pod 绑定到节点上。
* 只有所有的 pre-bind 扩展都成功执行了bind 扩展才会执行
* 调度框架按照 bind 扩展注册的顺序逐个调用 bind 扩展
* 具体某个 bind 扩展可以选择处理或者不处理该 Pod
* 如果某个 bind 扩展处理了该 Pod 与节点的绑定,**余下的 bind 扩展将被忽略**
### Post-bind
Post-bind 是一个通知性质的扩展:
* Post-bind 扩展在 Pod 成功绑定到节点上之后被动调用
* Post-bind 扩展式绑定过程的最后一个步骤,可以用来执行资源清理的动作
### Unreserve
Unreserve 是一个通知性质的扩展。如果为 Pod 预留了资源Pod 有在被绑定过程中被拒绝绑定,则 unreserve 扩展将被调用。Unreserve 扩展应该释放已经为 Pod 预留的节点上的计算资源。
在一个插件中reserve 扩展和 unreserve 扩展应该成对出现。
## 插件接口
向调度框架提供扩展,必须完成两个步骤:
* 向调度框架注册插件并完成配置
* 插件必须实现扩展点接口
扩展点接口的格式如下所示:
``` go
type Plugin interface {
Name() string
}
type QueueSortPlugin interface {
Plugin
Less(*v1.pod, *v1.pod) bool
}
type PreFilterPlugin interface {
Plugin
PreFilter(PluginContext, *v1.pod) error
}
// ...
```
## 插件配置
可以通过配置启用或者禁用调度框架的插件。
调度框架的配置中,也可以包含插件自己所需要的配置。这些配置信息将在调度框架初始化插件的时候传递给插件。插件自己的配置信息可以是任何内容,由使用该配置的插件自己解析和使用该配置信息。
下面的例子中展示的配置启用了一个实现了 `reserve` 和 `preBind` 扩展点的插件,并且禁用了另外一个插件。同时为插件 `foo` 提供了一些配置信息
``` yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
...
plugins:
reserve:
enabled:
- name: foo
- name: bar
disabled:
- name: baz
preBind:
enabled:
- name: foo
disabled:
- name: baz
pluginConfig:
- name: foo
args: >
foo插件可以解析的任意内容
```
扩展的调用顺序如下:
* 如果某个扩展点没有配置对应的扩展,调度框架将使用默认插件中的扩展
* 如果为某个扩展点配置且激活了扩展,则调度框架将先调用默认插件的扩展,再调用配置中的扩展。
* 默认插件的扩展始终被最先调用,然后按照 `KubeSchedulerConfiguration` 中扩展的激活 `enabled` 顺序逐个调用扩展点的扩展。
* 可以先禁用默认插件的扩展,然后在 `enabled` 列表中的某个位置激活默认插件的扩展。这种做法可以改变默认插件的扩展被调用时的次序
假设默认插件 `foo` 实现了 `reserve` 扩展点,此时我们要添加一个插件 `bar`,想要在 `foo` 之前被调用,则应该先禁用 `foo` 在按照 `bar` `foo` 的顺序激活。示例配置如下所示:
``` yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
...
plugins:
reserve:
enabled:
- name: bar
- name: foo
disabled:
- name: foo
```

View File

@ -1,5 +1,5 @@
--- ---
# vssueId: 117 vssueId: 129
layout: LearningLayout layout: LearningLayout
description: Kubernete教程_在Kubernetes中调度Scheduling指的是为 Pod 找到一个合适的节点,并由该节点上的 kubelet 运行 Pod。 description: Kubernete教程_在Kubernetes中调度Scheduling指的是为 Pod 找到一个合适的节点,并由该节点上的 kubelet 运行 Pod。
meta: meta:

View File

@ -0,0 +1,79 @@
---
vssueId: 130
layout: LearningLayout
description: Kubernete教程_kube-scheduler是 Kubernetes 中的默认调度器。负责为 Pod 在集群中选择合适的节点。本文解释了在规模较大的 Kubernetes 集群中如何对 kube-scheduler 进行性能调优。
meta:
- name: keywords
content: Kubernetes 教程,Kubernetes 调度,Kubernetes Scheduling
---
# 调优
<AdSenseTitle/>
> 参考文档: [Scheduler Performance Tuning](https://kubernetes.io/docs/concepts/scheduling/scheduler-perf-tuning/)
**FEATURE STATE:** `Kubernetes v1.14` <Badge type="warning">beta</Badge>
[kube-scheduler](/learning/k8s-advanced/schedule/#kube-scheduler) 是 Kubernetes 中的默认调度器。负责为 Pod 在集群中选择合适的节点。
集群中能够满足某一个 Pod 的资源需求的节点,我们称其为 ***可选节点***feasible node。调度器在执行调度时执行的步骤如下
1. 找出该 Pod 的所有 ***可选节点***
2. 按照某种方式对每一个 ***可选节点*** 评分
3. 选择评分最高的 ***可选节点***
4. 将最终选择结果通知 API Server`这个过程我们称其为绑定binding`
本文解释了在规模较大的 Kubernetes 集群中如何对 kube-scheduler 进行性能调优。
## 参与评分的节点的比例
在 Kubernetes v1.12 版本之前kube-scheduler 检查集群中的所有节点是否对 Pod 可选,并对 ***可选节点*** 进行评分。在 Kubernetes v1.12 中,添加了一个新的特性,使得 kube-scheduler 在找到了一定数量的 ***可选节点*** 后,变停止继续寻找更多 ***可选节点***。 这个特性可以显著提高 kube-scheduler 在大规模 Kubernetes 集群中的性能。通过 `percentageOfNodesToScore` 这个配置参数,我们可以控制 kube-scheduler 在找到多少 ***可用节点*** 之后变停止继续寻找。该参数的可选值为 1 - 100 之间的数字,大于 100 的将被认为是 100%0 代表忽略该配置。
在 Kubernetes v1.14 中,如果不定义 `percentageOfNodesToScore`kube-scheduler 将按照一个线性公式来确定该餐朱的取值。按照该公式:
* 100节点集群`percentageOfNodesToScore` 为 50%
* 5000节点集群`percentageOfNodesToScore` 为 10%
* `percentageOfNodesToScore` 的最小值为 5%;(即,不论集群规模有多大,按照该公式,`percentageOfNodesToScore` 最终取值为 5%,除非集群管理员将该参数配置为小于 5% 的值)
下面的例子中,将 `percentageOfNodesToScore` 配置为 50%
``` yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
algorithmSource:
provider: DefaultProvider
...
percentageOfNodesToScore: 50
```
::: tip 例外
当集群中可选节点数量少于 50 时,调度器仍将继续检查剩余的节点。
:::
如果要禁用该特性,可将 `percentageOfNodesToScore` 设定为 100。
### 调优 percentageOfNodesToScore
`percentageOfNodesToScore` 的取值在 1 到 100 之间,默认值基于集群节点的数量计算得出。并且,将至少要找出 50 个可选节点,否则仍会检查集群中所有节点是否对 Pod 可用。这就意味着,当集群的节点数不超过 1000 时修改该参数并不会对实际结果产生多大的影响。Kubernetes 有意做了此设计因为在小规模集群中kube-scheduler 的性能差异不大。当集群节点数超过 1000 时,调整此参数将有可能显著提升 kube-scheduler 的性能。
关于 `percentageOfNodesToScore`,一个重要的考虑因素是,如果只检查了集群中一小部分节点对 Pod 是否可选,也就意味着更多的节点未能参与该 Pod 的评分。此时存在的可能性是未参与评分的节点数量可能实际得分会比最终选中的节点得分更高Pod 并没有找到集群中“最”适合其运行的节点。因此,`percentageOfNodesToScore` 不应该设置为一个过低的数值。通常,不要将其设置为低于 10 的数字。在如下情况都满足时,可以考虑更低的数字:
* kube-scheduler 的吞吐量(每秒钟执行调度的次数)非常重要
* 节点的评分是否为最高,没那么重要
当集群节点数量不超过 1000甚至更少时不推荐修改该参数的默认取值此时调整此参数对 kube-scheduler 性能的影响不大。
### 调度器遍历节点的方法
为了让集群中的每个节点都有公平的机会被 Pod 选中,调度器按照 round-robin轮询的方式遍历节点。您可以认为节点被放在一个数组中调度器从数组的第一个元素开始检查节点是否为 ***可选节点***,直到其找到足够多数量(由`percentageOfNodesToScore`指定)的 ***可选节点***。当调度器调度下一个 Pod 时,将继续从上一次停止的地方往后面便利节点的数组,到达数组的末尾时,又从数组的第一个元素继续遍历。
如果节点在多个高可用区,调度器将遍历多个高可用区终端额节点,以确保不同的可用区都有合适的机会。例如,假设 6 个节点分布于两个可用区:
```
Zone 1: Node 1, Node 2, Node 3, Node 4
Zone 2: Node 5, Node 6
```
调度器将按照下面的顺序评估节点是否为可选节点:
```
Node 1, Node 5, Node 2, Node 6, Node 3, Node 4
```
到达结尾 Node 4 后,又从 Node 1 继续遍历。

View File

@ -8,8 +8,6 @@ meta:
# Kuboard简介 # Kuboard简介
<AdSenseTitle/>
<div style="background-color: #0063dc;"> <div style="background-color: #0063dc;">
<div style="max-width: 363px; margin: auto;"> <div style="max-width: 363px; margin: auto;">
<img src="/images/logo-main.png" style="background-color: #0063dc; max-width: 100%; vertical-align: bottom;" alt="Kubernetes管理界面Kuboard Logo"/> <img src="/images/logo-main.png" style="background-color: #0063dc; max-width: 100%; vertical-align: bottom;" alt="Kubernetes管理界面Kuboard Logo"/>