Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docs): Add Chinese translations to docs #328

Merged
merged 4 commits into from
May 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/assets/util.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.md-nav__title {
display: none;
}
}

.arithmatex {
font-size: 0.85rem;
}

foreignObject > div {
font-size: 0.85rem;
}
39 changes: 39 additions & 0 deletions docs/tutorials/dynamic-scheduler-plugin.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Dynamic Scheduler:负载感知调度器插件

## 介绍
kubernetes 的原生调度器只能通过资源请求来调度 pod,这很容易造成一系列负载不均的问题:

- 对于某些节点,实际负载与资源请求相差不大,这会导致很大概率出现稳定性问题。
- 对于其他节点来说,实际负载远小于资源请求,这将导致资源的巨大浪费。

为了解决这些问题,动态调度器根据实际的节点利用率构建了一个简单但高效的模型,并过滤掉那些负载高的节点来平衡集群。

## 设计细节

### 架构
![](./../images/dynamic-scheduler-plugin.png)


如上图,动态调度器依赖于`Prometheus`和`Node-exporter`收集和汇总指标数据,它由两个组件组成:

!!! note "Note"
zsnmwy marked this conversation as resolved.
Show resolved Hide resolved
`Node-annotator` 目前是 `Crane-scheduler-controller`的一个模块.

- `Node-annotator`定期从 Prometheus 拉取数据,并以注释的形式在节点上用时间戳标记它们。
- `Dynamic plugin`直接从节点的注释中读取负载数据,过滤并基于简单的算法对候选节点进行评分。

### 调度策略
动态调度器提供了一个默认值[调度策略](../deploy/manifests/policy.yaml)并支持用户自定义策略。默认策略依赖于以下指标:

- `cpu_usage_avg_5m`
- `cpu_usage_max_avg_1h`
- `cpu_usage_max_avg_1d`
- `mem_usage_avg_5m`
- `mem_usage_max_avg_1h`
- `mem_usage_max_avg_1d`

在调度的`Filter`阶段,如果该节点的实际使用率大于上述任一指标的阈值,则该节点将被过滤。而在`Score`阶段,最终得分是这些指标值的加权和。

### Hot Value

在生产集群中,可能会频繁出现调度热点,因为创建 Pod 后节点的负载不能立即增加。因此,我们定义了一个额外的指标,名为`Hot Value`,表示节点最近几次的调度频率。并且节点的最终优先级是最终得分减去`Hot Value`。
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ spec:
scaleStrategy: Auto # ScaleStrategy indicate the strategy to scaling target, value can be "Auto" and "Manual".
# Better to setting cron to fill the one complete time period such as one day, one week
# Below is one day cron scheduling, it
#(targetReplicas)
#80 -------- --------- ----------
# | | | | | |
#10 ------------ ----- -------- ----------
Expand Down Expand Up @@ -293,6 +294,7 @@ spec:
```

CronSpec has following fields.

* **name** defines the name of the cron, cron name must be unique in the same ehpa
* **description** defines the details description of the cron. it can be empty.
* **timezone** defines the timezone of the cron which the crane to schedule in. If unspecified, default use `UTC` timezone. you can set it to `Local` which means you use timezone of the container of crane service running in. Also, `America/Los_Angeles` is ok.
Expand All @@ -314,15 +316,16 @@ Remember **not to set start time is after end**. For example, when you set follo
- name: "cron2"
timezone: "Local"
description: "scale up"
start: "0 6 ? * *"
end: "0 9 ? * *"
start: "0 9 ? * *"
end: "0 6 ? * *"
targetReplicas: 80
```
Above is not valid because the start will be always later than end. The hpa controller will always get the workload's desired replica to scale, which means keep the original replicas.


#### Horizontal scaling process
There are six steps of cron-driven and scaling process:

1. EffectiveHPAController creates HorizontalPodAutoscaler which is injected to external cron metrics in spec.
2. HPAController reads cron external metrics from KubeApiServer
3. KubeApiServer forwards requests to MetricAdapter and MetricServer
Expand Down Expand Up @@ -351,6 +354,15 @@ This is a powerful feature. Because HPA always pick the largest replicas calcula
#### Mechanism
When metrics adapter deal with the external cron metric requests, metrics adapter will do following steps.

``` mermaid
graph LR
A[Start] --> B{Active Cron?};
B -->|Yes| C(largest targetReplicas) --> F;
B -->|No| D{Work together with other metrics?};
D -->|Yes| G(minimum replicas) --> F;
D -->|No| H(current replicas) --> F;
F[Result workload replicas];
```

1. No active cron now, there are two cases:

Expand Down Expand Up @@ -426,4 +438,4 @@ reason: Not all workload's cpu metric are predictable, if predict your workload

solution:
- Just waiting. the Prediction algorithm need more time, you can see `DSP` section to know more about this algorithm.
- EffectiveHorizontalPodAutoscaler have a protection mechanism when prediction failed, it will use the actual cpu utilization to do autoscaling.
- EffectiveHorizontalPodAutoscaler have a protection mechanism when prediction failed, it will use the actual cpu utilization to do autoscaling.
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,248 @@ status:

```

### Cron-based autoscaling
EffectiveHorizontalPodAutoscaler 支持基于 cron 的自动缩放。

除了基于监控指标,有时节假日和工作日的工作负载流量存在差异,简单的预测算法可能效果不佳。然后可以通过设置周末 cron 来支持更大数量的副本来弥补预测的不足。

对于一些非 web 流量的应用,比如一些应用不需要在周末使用,可以把工作负载的副本数减少到 1,也可以配置 cron 来降低你的服务成本。

以下是 `EHPA Spec` 中的 cron 主要字段:

- `CronSpec`:可以设置多个 cron 自动伸缩配置,cron cycle 可以设置循环的开始时间和结束时间,并且工作负载的副本数可以在时间范围内持续保持为设定的目标值。
- `Name`:cron 标识符
- `TargetReplicas`:此 cron 时间范围内工作负载的目标副本数。
- `Start`:cron 的开始时间,标准 linux crontab 格式
- `End`:cron 的结束时间,标准 linux crontab 格式


一些云厂商和社区当前的 cron 自动缩放功能存在一些缺点。

1. cron 能力单独提供,没有在全局视图中进行自动缩放,与 HPA 兼容性差,与其他缩放触发器冲突。
2. cron 的语义和行为不是很匹配,使用时甚至很难理解,很容易误导用户,导致自动伸缩失败。

下图显示了当前 EHPA cron 自动伸缩实现与其他 cron 能力的对比。

![crane-keda-ali-compare-cron.png](../images/crane-keda-ali-compare-cron.png)


针对以上问题,EHPA 实现的 cron autoscaling 是在与 HPA 兼容的基础上设计的,cron 作为 HPA 的一个指标,与其他指标一起作用于工作负载。

另外,cron 的设置也很简单。单独配置 cron 时,不在活动时间范围内时,不会对工作负载执行缩放。


#### Cron working without other metrics
假设你没有配置其他指标,你只需配置 cron 本身即可工作。
```yaml
apiVersion: autoscaling.crane.io/v1alpha1
kind: EffectiveHorizontalPodAutoscaler
metadata:
name: php-apache-local
spec:
# ScaleTargetRef 关联到需扩缩容的工作负载
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1 # MinReplicas : autoscaler 缩放的最低副本数
maxReplicas: 100 # MaxReplicas : autoscaler 缩放的最大副本数
scaleStrategy: Auto # ScaleStrategy : 缩放工作负载时候,所采用的策略。可选值为 "Auto" "Manual"
# 最好将Cron Scheduling设置为一个完整的时间周期,例如: 一天,一周
# 下面是一天的Cron Scheduling
#(targetReplicas)
#80 -------- --------- ----------
# | | | | | |
#10 ------------ ----- -------- ----------
#(time) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#本地时区(timezone: "Local")意味着您使用运行Craned所在的服务器(或者可能是容器)的时区。例如,当Craned 是以UTC时区开始,那么它就是UTC。如果一开始是Asia/Shanghai,那么它就是Asia/Shanghai。
crons:
- name: "cron1"
timezone: "Local"
description: "scale down"
start: "0 0 ? * *"
end: "0 6 ? * *"
targetReplicas: 10
- name: "cron2"
timezone: "Local"
description: "scale up"
start: "0 6 ? * *"
end: "0 9 ? * *"
targetReplicas: 80
- name: "cron3"
timezone: "Local"
description: "scale down"
start: "00 9 ? * *"
end: "00 11 ? * *"
targetReplicas: 10
- name: "cron4"
timezone: "Local"
description: "scale up"
start: "00 11 ? * *"
end: "00 14 ? * *"
targetReplicas: 80
- name: "cron5"
timezone: "Local"
description: "scale down"
start: "00 14 ? * *"
end: "00 17 ? * *"
targetReplicas: 10
- name: "cron6"
timezone: "Local"
description: "scale up"
start: "00 17 ? * *"
end: "00 20 ? * *"
targetReplicas: 80
- name: "cron7"
timezone: "Local"
description: "scale down"
start: "00 20 ? * *"
end: "00 00 ? * *"
targetReplicas: 10
```

CronSpec 具有以下字段:

* **name** 定义了 cron 的名字,cron 名字在同一个 Ehpa 中必须是唯一的
* **description** 定义 cron 的详细描述。它可以是空的。
* **timezone** 定义Crane所要调度的 cron 时区。如果未指定,则默认使用`UTC`时区。你可以将它设置为`Local`,这将使用正在运行的Crane容器所在的时区。其实,你定义`America/Los_Angeles`也是可以的。
* **start** 定义 cron 开始调度的时间,是 crontab 格式。参考 [wiki-Cron](https://en.wikipedia.org/wiki/Cron)
* **end** 定义 cron 结束调度的时间,是 crontab 格式。参考 [wiki-Cron](https://en.wikipedia.org/wiki/Cron)
* **targetReplicas** 定义目标副本在 cron 处于活动状态时要扩展的工作负载,这意味着目标副本数介于开始时间和结束时间之间生效。

以上YAML定义,意味着一天当中,工作负载在每小时所需要保持的副本数。工作负载将会每天按照该规则执行。

```
#80 -------- --------- ----------
# | | | | | |
#1 ------------ ----- -------- ----------
#(time) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
```

记住**不要设置开始时间在结束时间之后**。

例如,当你设置以下内容时:
```
crons:
- name: "cron2"
timezone: "Local"
description: "scale up"
start: "0 9 ? * *"
end: "0 6 ? * *"
targetReplicas: 80
```
以上无效,因为开始总是晚于结束。

HPA 控制器始终根据工作负载所描述的副本数进行扩展,这意味着保留原有副本数不变。


#### Horizontal scaling process

cron 驱动和扩展过程有六个步骤:

1. `EffectiveHPAController` 创建 `HorizontalPodAutoscaler`,它被注入到`spec`中的`external cron metrics`中。
2. `HPAController` 从 `KubeApiServer` 读取 `external cron metrics`
3. `KubeApiServer` 将请求转发给 `MetricAdapter` 和 `MetricServer`
4. `MetricAdapter` 找到目标 hpa 的 `cron scaler`,并检测 `cron scaler` 是否处于活动状态。这意味着当前时间介于 cron 开始和结束计划时间之间。它将返回`TargetReplicas`中定义的`CronSpec`。
5. `HPAController` 计算所有 metrics 结果,并通过选择最大的一个为目标副本数。并由此创建一个新的`scale replicas`。
6. `HPAController` 使用 `Scale Api` 缩放目标


使用 EHPA 时,用户可以只配置 cron metric,让 EHPA 用作 cron hpa。

一个 EHPA 的多个 crons 将转换为一个`external metrics`。

HPA 将获取`external metrics`并在协调时计算目标副本。当存在多个指标的工作负载时,HPA 将选择最大的副本数来扩展。



#### Cron working with other metrics together

`EffectiveHorizontalPodAutoscaler` 兼容 `HorizontalPodAutoscaler`(内置在 kubernetes)。因此,如果你为 HPA 配置了指标,例如 cpu 或内存,那么 HPA 将根据它观察到的实时指标对副本数进行扩展。

通过 EHPA,用户可以同时配置 `CronMetric`、`PredictionMetric`、`OriginalMetric`。

**我们强烈建议你配置所有维度的指标。它们分别代表 cron 副本、先前预测的副本、后观察的副本。**

这是一个强大的功能。因为 HPA 总是选择由所有维度`metrics`计算的最大副本进行扩展。

这将保证你工作负载的 QoS,当你同时配置三种类型的自动缩放时,根据实际观察到的指标计算的副本最大,然后它将使用最大的一个。

尽管由于某些意想不到的原因,导致由`PredictionMetric`计算的副本更小。因此,你不必担心 QoS。


#### Mechanism
当`metrics adapter`处理`external cron metrics`请求时,`metrics adapter`将执行以下步骤。

``` mermaid
graph LR
A[Start] --> B{Active Cron?};
B -->|Yes| C(largest targetReplicas) --> F;
B -->|No| D{Work together with other metrics?};
D -->|Yes| G(minimum replicas) --> F;
D -->|No| H(current replicas) --> F;
F[Result workload replicas];
```


1. 没有活跃的cron,有两种情况:

- 没有其他 hpa 指标与 cron 一起使用,然后返回当前工作负载副本以保留原始所需的副本
- 当其他 hpa 指标与 cron 一起使用,将会返回最小值以消除cron对其他指标的影响。当 cron 与其他指标一起工作时,它不应该返回工作负载的原始副本数,因为可能有其他指标想要缩小工作负载的副本数。`HPA Controller`选择由所有指标计算的最大副本(这是硬代码中的 hpa 默认策略),cron 会影响 hpa。所以我们应该在 cron 不活动时移除 cron 效果,它应该返回最小值。


2. 有活跃的cron。我们使用`cron spec`中指定的最大目标副本。基本上,在同一时间段内不应有超过一个活跃的 cron,这不是最佳实践。

HPA 将获取`cron external metrics`,然后它会自行计算副本数。

#### Use Case

当你需要在午夜将工作负载副本数保持在最低限度,根据该需求配置了 cron。

你需要 HPA 来获取指标服务器观察到的真实指标,以根据实时观察到的指标进行扩展。

最后,你配置一个`prediction-driven metric`,通过预测方式提前扩大规模并在末期缩小规模。

```yaml
apiVersion: autoscaling.crane.io/v1alpha1
kind: EffectiveHorizontalPodAutoscaler
metadata:
name: php-apache-multi-dimensions
spec:
# ScaleTargetRef 关联到需扩缩容的工作负载
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1 # MinReplicas : 缩放的最小副本数
maxReplicas: 100 # MaxReplicas : 缩放的最大副本数
scaleStrategy: Auto # ScaleStrategy : 缩放工作负载时候,所采用的策略。可选值为 "Auto" "Manual"
# Metrics 包含了用于计算所需副本数的指标。
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
# Prediction 的配置定义了需要预测的资源
# 若不配置,则默认不启动 prediction
prediction:
predictionWindowSeconds: 3600 # PredictionWindowSeconds 是预测未来指标的时间窗口。
predictionAlgorithm:
algorithmType: dsp
dsp:
sampleInterval: "60s"
historyLength: "3d"
crons:
- name: "cron1"
description: "scale up"
start: "0 0 ? * 6"
end: "00 23 ? * 0"
targetReplicas: 100
```


## 常见问题

### 错误: unable to get metric crane_pod_cpu_usage
Expand All @@ -217,4 +459,4 @@ status:
解决方案:

- 等一段时间再看。预测算法 `DSP` 需要一定时间的数据才能进行预测。希望了解算法细节的可以查看算法的文档。
- EffectiveHorizontalPodAutoscaler 提供一种保护机制,当预测失效时依然能通过实际的 CPU 使用率工作。
- EffectiveHorizontalPodAutoscaler 提供一种保护机制,当预测失效时依然能通过实际的 CPU 使用率工作。
Loading