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

docs: Update docs for recommendation framework #576

Merged
merged 1 commit into from
Oct 10, 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
2 changes: 1 addition & 1 deletion site/content/zh/docs/Getting started/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Crane Dashboard **在线 Demo**: http://dashboard.gocrane.io/

**推荐框架**

提供了一个可扩展的推荐框架以支持多种云资源的分析,内置了多种推荐器:资源推荐,副本推荐,闲置资源推荐。
提供了一个可扩展的推荐框架以支持多种云资源的分析,内置了多种推荐器:资源推荐,副本推荐,闲置资源推荐。[了解更多](/zh-cn/docs/tutorials/recommendation)。

**基于预测的水平弹性器**

Expand Down
7 changes: 7 additions & 0 deletions site/content/zh/docs/Tutorials/Recommendation/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

---
title: "智能推荐"
weight: 10
description: >
智能推荐能力介绍.
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: "如何开发 Recommender"
description: "介绍 Recommender 框架以及如何进行开发和扩展"
weight: 100
---

Recommendation Framework 提供了一套可扩展的 Recommender 框架并支持了内置的 Recommender,用户可以实现一个自定义的 Recommender,或者修改一个已有的 Recommender。

## Recommender Interface

```go
type Recommender interface {
Name() string
framework.Filter
framework.PrePrepare
framework.Prepare
framework.PostPrepare
framework.PreRecommend
framework.Recommend
framework.PostRecommend
framework.Observe
}

// Phase: Filter

// Filter interface
type Filter interface {
// The Filter will filter resource can`t be recommended via target recommender.
Filter(ctx *RecommendationContext) error
}

// Phase: Prepare

// PrePrepare interface
type PrePrepare interface {
CheckDataProviders(ctx *RecommendationContext) error
}

// Prepare interface
type Prepare interface {
CollectData(ctx *RecommendationContext) error
}

type PostPrepare interface {
PostProcessing(ctx *RecommendationContext) error
}

// PreRecommend interface
type PreRecommend interface {
PreRecommend(ctx *RecommendationContext) error
}

// Phase: Recommend

// Recommend interface
type Recommend interface {
Recommend(ctx *RecommendationContext) error
}

// PostRecommend interface
type PostRecommend interface {
Policy(ctx *RecommendationContext) error
}

// Phase: Observe

// Observe interface
type Observe interface {
Observe(ctx *RecommendationContext) error
}

```

Recommender 接口定义了一次推荐需要实现的四个阶段和八个扩展点。这些扩展点会在推荐过程中按顺序被调用。这些扩展点中的的一些可以改变调度决策,而另一些仅用来提供信息。

## 架构

![](/images/recommendation-framework.png)

## 阶段

整个推荐过程分成了四个阶段:Filter,Prepare,Recommend,Observe。阶段的输入是需要分析的 Kubernetes 资源,输出是推荐的优化建议。 下面开始介绍每个阶段的输入、输出和能力。

`RecommendationContext` 保存了一次推荐过程中的上下文,包括推荐目标,RecommendationConfiguration 等,用户可以按需增加更多的内容。

### Filter

Filter 阶段用于预处理推荐数据。通常,在预处理时需判断推荐目标是否和 Recommender 匹配,比如,Resource Recommender 只支持处理 Workload(Deployment,StatefulSet)。除此之外,还可以判断推荐目标状态是否适合推荐,比如是否删除中,是否刚创建等。当返回 error 会终止此次推荐。BaseRecommender 实现了基本的预处理功能,用户可以调用它继承相关功能。

### Prepare

Prepare 阶段用于数据准备,请求外部监控系统并将时序数据保存在上下文中。PrePrepare 扩展点用于检测监控系统的链接情况。Prepare 扩展点用于查询时序数据。PostPrepare 扩展点用于对时序数据的数据处理,比如:应用冷启动的异常数据,部分数据的缺失,数据聚合,异常数据清理等。

### Recommend

Recommend 阶段用于基于时序数据和资源配置进行优化建议。优化建议的类型取决于推荐的类型。比如,如果是资源推荐,那么输出就是 kubernetes workload 的资源配置。Recommend 扩展点用于采用 Crane 的算法模块对数据进行分析计算,PostRecommend 阶段对分析结果进行最后处理。用户可以自定义 Recommend 阶段实现自定义的推荐结果。

### Observe

Observe 阶段用于推荐结果的可观测。比如,在资源推荐时,将优化建议的信息通过 Metric 保存到监控系统,再通过 Dashboard 观测优化建议带来的收益。
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
title: "推荐框架"
description: "介绍智能推荐框架的原理和用法"
weight: 10
---

**推荐框架**是指自动分析集群的各种资源的运行情况并给出优化建议。

## 推荐概览

Crane 的推荐模块定期的检测发现集群资源配置的问题,并给出优化建议。智能推荐提供了多种 Recommender 来实现面向不同资源的优化推荐。
如何你想了解 Crane 如何做智能推荐的,或者你想要尝试实现一个自定义的 Recommender,或者修改一个已有的 Recommender 的推荐规则,这篇文章将帮助你了解智能推荐。

## 用例

以下是智能推荐的典型用例:

- 创建 RecommendationRule 配置。RecommendationRule Controller 会根据配置定期运行推荐任务,给出优化建议 Recommendation。
- 根据优化建议 Recommendation 调整资源配置。

## 创建 RecommendationRule 配置

下面是一个 RecommendationRule 示例: workload-rule.yaml。

```yaml
apiVersion: analysis.crane.io/v1alpha1
kind: RecommendationRule
metadata:
name: workloads-rule
spec:
runInterval: 24h # 每24h运行一次
resourceSelectors: # 资源的信息
- kind: Deployment
apiVersion: apps/v1
- kind: StatefulSet
apiVersion: apps/v1
namespaceSelector:
any: true # 扫描所有namespace
recommenders: # 使用 Workload 的副本和资源推荐器
- name: Replicas
- name: Resource
```

在该示例中:

- 每隔24小时运行一次分析推荐,`runInterval`格式为时间间隔,比如: 1h,1m,设置为空表示只运行一次。
- 待分析的资源通过配置 `resourceSelectors` 数组设置,每个 `resourceSelector` 通过 kind,apiVersion,name 选择 k8s 中的资源,当不指定 name 时表示在 `namespaceSelector` 基础上的所有资源
- `namespaceSelector` 定义了待分析资源的 namespace,`any: true` 表示选择所有 namespace
- `recommenders` 定义了待分析的资源需要通过哪些 Recommender 进行分析。目前支持的类型:[recommenders](/zh-cn/docs/tutorials/recommendation/recommendation-framework#recommender)
- 资源类型和 `recommenders` 需要可以匹配,比如 Resource 推荐默认只支持 Deployments 和 StatefulSets,每种 Recommender 支持哪些资源类型请参考 recommender 的文档

1. 通过以下命令创建 RecommendationRule,刚创建时会立刻开始一次推荐。

```shell
kubectl apply -f workload-rules.yaml
```

这个例子会对所有 namespace 中的 Deployments 和 StatefulSets 做资源推荐和副本数推荐。

2. 检查 RecommendationRule 的推荐进度。通过 Status.recommendations 观察推荐任务的进度,推荐任务是顺序执行,如果所有任务的 lastStartTime 为最近时间且 message 有值,则表示这一次推荐完成

```shell
kubectl get rr workloads-rule
```

```yaml
status:
lastUpdateTime: "2022-09-28T10:36:02Z"
recommendations:
- apiVersion: analysis.crane.io/v1alpha1
kind: Recommendation
lastStartTime: "2022-09-28T10:36:02Z"
message: Success
name: workloads-rule-replicas-rckvb
namespace: default
recommenderRef:
name: Replicas
targetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
namespace: default
uid: b15cbcd7-6fe2-4ace-9ae8-11cc0a6e69c2
- apiVersion: analysis.crane.io/v1alpha1
kind: Recommendation
lastStartTime: "2022-09-28T10:36:02Z"
message: Success
name: workloads-rule-resource-pnnxn
namespace: default
recommenderRef:
name: Resource
targetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
namespace: default
uid: 8472013a-bda2-4025-b0df-3fdc69c1c910
```

3. 查看优化建议 `Recommendation`

可通过以下 label 筛选 `Recommendation`,比如 `kubectl get recommend -l analysis.crane.io/recommendation-rule-name=workloads-rule`

- RecommendationRule 名称:analysis.crane.io/recommendation-rule-name
- RecommendationRule UID:analysis.crane.io/recommendation-rule-uid
- RecommendationRule 的 recommender:analysis.crane.io/recommendation-rule-recommender
- 推荐资源的 kind:analysis.crane.io/recommendation-target-kind
- 推荐资源的 apiversion:analysis.crane.io/recommendation-target-apiversion
- 推荐资源的 name:analysis.crane.io/recommendation-target-apiversion

通常, `Recommendation` 的 namespace 等于推荐资源的 namespace。闲置节点推荐的 `Recommendation` 除外,它们在 Crane 的 root namespace 中,默认是 crane-system。

## 根据优化建议 Recommendation 调整资源配置

对于资源推荐和副本数推荐建议,用户可以 PATCH status.recommendedInfo 到 workload 更新资源配置,例如:

```shell
patchData=`kubectl get recommend workloads-rule-replicas-rckvb -n default -o jsonpath='{.status.recommendedInfo}'`;kubectl patch Deployment php-apache -n default --patch "${patchData}"
```

对于闲置节点推荐,由于节点的下线在不同平台上的步骤不同,用户可以根据自身需求进行节点的下线或者缩容。

## Recommender

目前 Crane 支持了以下 Recommender:

- [**资源推荐**](/zh-cn/docs/tutorials/recommendation/resource-recommendation): 通过 VPA 算法分析应用的真实用量推荐更合适的资源配置
- [**副本数推荐**](/zh-cn/docs/tutorials/recommendation/replicas-recommendation): 通过 HPA 算法分析应用的真实用量推荐更合适的副本数量

### Recommender 框架

Recommender 框架定义了一套工作流程,Recommender 按流程顺序执行,流程分为四个阶段:Filter,Prepare,Recommend,Observe,Recommender 通过实现这四个阶段完成推荐功能。

开发或者扩展 Recommender 请参考:[如何开发 Recommender](/zh-cn/docs/tutorials/recommendation/how-to-develop-recommender)

## RecommendationConfiguration

RecommendationConfiguration 定义了 recommender 的配置。部署时会在 crane root namespace创建一个 ConfigMap:recommendation-configuration,数据包括了一个 yaml 格式的 RecommendationConfiguration.

下面是一个 RecommendationConfiguration 示例。

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: recommendation-configuration
namespace: crane-system
data:
config.yaml: |-
apiVersion: analysis.crane.io/v1alpha1
kind: RecommendationConfiguration
recommenders:
- name: Replicas
acceptedResources: # 接受的资源类型
- kind: Deployment
apiVersion: apps/v1
- kind: StatefulSet
apiVersion: apps/v1
config: # 设置 recommender 的参数
workload-min-replicas: "1"
- name: Resource
acceptedResources: # 接受的资源类型
- kind: Deployment
apiVersion: apps/v1
- kind: StatefulSet
apiVersion: apps/v1
```

用户可以修改 ConfigMap 内容并重新发布 Crane,触发新的配置生效。

## 如何让推荐结果更准确

应用在监控系统(比如 Prometheus)中的历史数据越久,推荐结果就越准确,建议生产上超过两周时间。对新建应用的预测往往不准。
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: "副本数推荐"
description: "副本数推荐介绍"
weight: 13
---

Kubernetes 用户在创建应用资源时常常是基于经验值来设置副本数。通过副本数推荐的算法分析应用的真实用量推荐更合适的副本配置,您可以参考并采纳它提升集群的资源利用率。

## 实现原理

基于 Workload 历史 CPU 负载,找到过去七天内每小时负载最低的 CPU 用量,计算按50%(可配置)利用率和 Workload CPU Request 应配置的副本数

### Filter 阶段

1. 低副本数的工作负载: 过低的副本数可能弹性需求不高,关联配置: `workload-min-replicas`
2. 存在一定比例非 Running Pod 的工作负载: 如果工作负载的 Pod 大多不能正常运行,可能不适合弹性,关联配置: `pod-min-ready-seconds` | `pod-available-ratio`

### Prepare 阶段

查询过去一周的 CPU 使用量

### Recommend 阶段

1. 计算过去7天 workload 每小时使用量中位数的最低值(防止极小值影响): workload_cpu_usage_medium_min
2. 目标利用率对应的副本数:

```go
replicas := int32(math.Ceil(workloadCpu / (rr.TargetUtilization * float64(requestTotal) / 1000.)))
```

3. 为了防止 replicas 过小,replicas 需要大于等于 default-min-replicas

### Observe 阶段

将推荐 replicas 记录到 Metric:crane_analytics_replicas_recommendation

## 支持的资源类型

默认支持 StatefulSet 和 Deployment,但是支持所有实现了 Scale SubResource 的 Workload。

## 参数配置

| 配置项 | 默认值 | 描述 |
| ------------- |-----|-----------------|
| workload-min-replicas| 1 | 小于该值的工作负载不做弹性推荐 |
| pod-min-ready-seconds| 30 | 定义了 Pod 是否 Ready 的秒数 |
| pod-available-ratio| 0.5 | Ready Pod 比例小于该值的工作负载不做弹性推荐 |
| default-min-replicas| 1 | 最小 minReplicas |
| cpu-target-utilizationn| 0.5 | 按该值计算最小副本数 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: "资源推荐"
description: "资源推荐功能介绍"
weight: 14
---

Kubernetes 用户在创建应用资源时常常是基于经验值来设置 request 和 limit。通过资源推荐的算法分析应用的真实用量推荐更合适的资源配置,您可以参考并采纳它提升集群的资源利用率。

## 实现原理

算法模型采用了 VPA 的滑动窗口(Moving Window)算法进行推荐

1. 通过监控数据,获取 Workload 过去一周(可配置)的 CPU 和 Memory 历史用量。
2. 算法考虑数据的时效性,较新的数据采样点会拥有更高的权重。
3. CPU 推荐值基于用户设置的目标百分位值计算,Memory 推荐值基于历史数据的最大值

## 资源推荐计算模型

### Filter 阶段

没有 Pod 的工作负载: 如果工作负载没有 Pod,无法进行算法分析

### Recommend 推荐

采用 VPA 的滑动窗口(Moving Window)算法分别计算每个容器的 CPU 和 Memory 并给出对应的推荐值

### Observe 推荐

将推荐资源配置记录到 Metric:crane_analytics_replicas_recommendation

## 支持的资源类型

默认支持 StatefulSet 和 Deployment,但是支持所有实现了 Scale SubResource 的 Workload。

## 参数配置

| 配置项 | 默认值 | 描述 |
|-----------------------------|------|--------------------------------|
| cpu-sample-interval | 1m | 请求 CPU 监控数据的 Metric 采样点时间间隔 |
| cpu-request-percentile | 0.99 | CPU 百分位值 |
| cpu-request-margin-fraction | 0.15 | CPU 推荐值扩大系数,0.15指推荐值乘以 1.15 |
| cpu-target-utilization | 1 | CPU 目标利用率,0.8 指推荐值除以 0.8 |
| cpu-model-history-length | 168h | CPU 历史监控数据的时间 |
| mem-sample-interval | 1m | 请求 Memory 监控数据的 Metric 采样点时间间隔 |
| mem-request-percentile | 0.99 | Memory 百分位值 |
| mem-request-margin-fraction | 0.15 | Memory 推荐值扩大系数,0.15指推荐值乘以 1.15 |
| mem-target-utilization | 1 | Memory 目标利用率,0.8 指推荐值除以 0.8 |
| mem-model-history-length | 168h | Memory 历史监控数据的时间 |
Loading