范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

腾讯开源云原生成本优化神器FinOpsCrane

  Crane  是一个基于 FinOps 的云资源分析与成本优化平台,它的愿景是在保证客户应用运行质量的前提下实现极致的降本。Crane 已经在腾讯内部自研业务实现了大规模落地,部署数百个 K8s 集群、管控 CPU 核数达百万,在降本增效方面取得了阶段性成果。以腾讯某部门集群优化为例,通过使用 FinOps Crane,该部门在保障业务稳定的情况下,资源利用率提升了 3 倍;腾讯另一自研业务落地 Crane 后,在一个月内实现了总 CPU 规模 40 万核的节省量,相当于成本节约超过 1000 万元/月。
  Crane  会通过下面 3 个方面来开启成本优化之旅: 成本展示: Kubernetes 资源( Deployments, StatefulSets )的多维度聚合与展示。  成本分析: 周期性的分析集群资源的状态并提供优化建议。  成本优化: 通过丰富的优化工具更新配置达成降本的目标。
  核心功能包括:成本可视化和优化评估;内置了多种推荐器 - 资源推荐、副本推荐、闲置资源推荐;基于预测的水平弹性器;负载感知的调度器;基于 QOS 的混部。下面我们来详细了解下 Crane 的各项功能。  安装
  我们这里使用 Helm 的方式来进行安装,首先需要安装 Prometheus 和 Grafana(如果您已经在环境中部署了 Prometheus 和 Grafana,可以跳过该步骤)。
  Crane  使用 Prometheus 获取集群工作负载对资源的使用情况,可以使用如下所示命令安装 Prometheus: $ helm repo add prometheus-community https://finops-helm.pkg.coding.net/gocrane/prometheus-community $ helm upgrade --install prometheus -n crane-system      --set pushgateway.enabled=false      --set alertmanager.enabled=false      --set server.persistentVolume.enabled=false      -f https://gitee.com/finops/helm-charts/raw/main/integration/prometheus/override_values.yaml      --create-namespace  prometheus-community/prometheus
  由于 Crane 的  Fadvisor  会使用 Grafana 来展示成本预估,所以我们也需要安装 Grafana: $ helm repo add grafana https://finops-helm.pkg.coding.net/gocrane/grafana $ helm upgrade --install grafana      -f https://gitee.com/finops/helm-charts/raw/main/integration/grafana/override_values.yaml      -n crane-system      --create-namespace grafana/grafana
  上面我们指定的 values 文件中配置了 Prometheus 数据源以及一些相关的 Dashboard,直接安装后即可使用。
  然后接下来安装 crane 与 fadvisor,同样直接使用 Helm Chart 安装即可,如下命令所示:  $ helm repo add crane https://finops-helm.pkg.coding.net/gocrane/gocrane $ helm upgrade --install crane -n crane-system --create-namespace crane/crane $ helm upgrade --install fadvisor -n crane-system --create-namespace crane/fadvisor
  安装后可以查看 Pod 列表了解应用状态:  $ kubectl get pods -n crane-system NAME                                             READY   STATUS             RESTARTS         AGE crane-agent-8jrs5                                0/1     CrashLoopBackOff   71 (2m26s ago)   3h23m crane-agent-t2rpz                                0/1     CrashLoopBackOff   71 (65s ago)     3h23m craned-776c7b6c75-gx8cp                          2/2     Running            0                3h28m fadvisor-56fcc547b6-zvf6r                        1/1     Running            0                158m grafana-5cd57f9f6b-d7nk5                         1/1     Running            0                3h32m metric-adapter-887f6548d-qcbb8                   1/1     Running            0                3h28m prometheus-kube-state-metrics-5f6f856ffb-4lrrr   1/1     Running            0                3h34m prometheus-node-exporter-97vmz                   1/1     Running            0                3h27m prometheus-node-exporter-m2gr9                   1/1     Running            0                3h27m prometheus-server-7744f66fb4-lw2sz               2/2     Running            0                3h34m
  需要注意我们这里 crane-agent 启动失败了,这是因为我的 K8s 集群使用的是 containerd 这种容器运行时,需要明确声明指定使用的运行时 endpoint:  $ kubectl edit ds crane-agent -n crane-system # ......     spec:       containers:       - args:         - --v=2         - --runtime-endpoint=/run/containerd/containerd.sock  # 指定有containerd的sock文件         command:         - /crane-agent # ......
  此外还需要更新 crane-agent 的 rbac 权限:  $ kubectl edit clusterrole crane-agent # ...... - apiGroups:   - ensurance.crane.io   resources:   - podqosensurancepolicies   - nodeqoss  # 增加 nodeqoss 和 podqoss 资源的权限   - podqoss # ......
  然后我们可以再创建一个 Ingress 对象来暴露 crane 的 dashboard 服务:  apiVersion: networking.k8s.io/v1 kind: Ingress metadata:   name: ingress-crane-dashboard   namespace: crane-system spec:   ingressClassName: nginx   rules:     - host: crane.k8s.local # change to your domain       http:         paths:           - path: /             pathType: Prefix             backend:               service:                 name: craned                 port:                   number: 9090
  直接应用该 ingress 资源对象即可,当然前提是你已经安装了 ingress-nginx:  $ kubectl get pods -n ingress-nginx NAME                                            READY   STATUS    RESTARTS      AGE ingress-nginx-controller-7647c44fb9-6gcsf       1/1     Running   8 (44m ago)   21d ingress-nginx-defaultbackend-7fc5bfd66c-gqmmj   1/1     Running   8 (44m ago)   21d $ kubectl get ingress -n crane-system NAME                      CLASS   HOSTS             ADDRESS        PORTS   AGE ingress-crane-dashboard   nginx   crane.k8s.local   192.168.0.52   80      11s
  将  crane.k8s.local  映射到 192.168.0.52  后就可以访问 crane 的 dashboard 了:
  第一次访问 dashboard 的时候需要添加一个 K8s 集群,添加 添加集群 按钮开始添加,填入正确的 CRNE Endpoint  地址即可。
  然后切换到 集群总览 可以查看到当前集群的一些成本相关数据,由于目前数据还不足,所以会有一些空的图表。
  在成本分布页面可以按照维度成本、集群成本和利用率指标以及命名空间成本来展示成本的分布情况。  智能推荐
  在 dasbhoard 中开箱后就可以看到相关的成本数据,是因为在添加集群的时候我们安装了推荐的规则。
  推荐框架会自动分析集群的各种资源的运行情况并给出优化建议。 Crane  的推荐模块会定期检测发现集群资源配置的问题,并给出优化建议。智能推荐提供了多种 Recommender 来实现面向不同资源的优化推荐。
  在 成本分析>推荐规则 页面可以看到我们安装的两个推荐规则。
  这些推荐规则实际上是安装在 K8s 集群上的  RecommendationRule CRD  对象:  $ kubectl get RecommendationRule NAME             RUNINTERVAL   AGE idlenodes-rule   24h           16m workloads-rule   24h           16m
  workloads-rule  这个推荐规则的资源对象如下所示: apiVersion: analysis.crane.io/v1alpha1 kind: RecommendationRule metadata:   name: workloads-rule   labels:     analysis.crane.io/recommendation-rule-preinstall: "true" spec:   resourceSelectors:     - kind: Deployment       apiVersion: apps/v1     - kind: StatefulSet       apiVersion: apps/v1   namespaceSelector:     any: true   runInterval: 24h   recommenders:     - name: Replicas     - name: Resource
  RecommendationRule  是一个全部范围内的对象,该推荐规则会对所有命名空间中的 Deployments 和 StatefulSets 做资源推荐和副本数推荐。相关规范属性如下所示: 每隔 24 小时运行一次分析推荐, runInterval  格式为时间间隔,比如: 1h,1m,设置为空表示只运行一次。 待分析的资源通过配置  resourceSelectors  数组设置,每个 resourceSelector  通过 kind 、apiVersion 、name  选择 K8s 中的资源,当不指定 name 时表示在 namespaceSelector  基础上的所有资源。 namespaceSelector  定义了待分析资源的命名空间,any: true  表示选择所有命名空间。 recommenders  定义了待分析的资源需要通过哪些 Recommender  进行分析。目前支持两种 Recommender : 资源推荐(Resource): 通过 VPA 算法分析应用的真实用量推荐更合适的资源配置  副本数推荐(Replicas): 通过 HPA 算法分析应用的真实用量推荐更合适的副本数量
  资源推荐
  Kubernetes 用户在创建应用资源时常常是基于经验值来设置 request 和 limit,通过资源推荐的算法分析应用的真实用量推荐更合适的资源配置,你可以参考并采纳它提升集群的资源利用率。该推荐算法模型采用了 VPA 的滑动窗口(Moving Window)算法进行推荐:  通过监控数据,获取 Workload 过去一周(可配置)的 CPU 和内存的历史用量。  算法考虑数据的时效性,较新的数据采样点会拥有更高的权重。  CPU 推荐值基于用户设置的目标百分位值计算,内存推荐值基于历史数据的最大值。
  副本数推荐
  Kubernetes 用户在创建应用资源时常常是基于经验值来设置副本数。通过副本数推荐的算法分析应用的真实用量推荐更合适的副本配置,同样可以参考并采纳它提升集群的资源利用率。其实现的基本算法是基于工作负载历史 CPU 负载,找到过去七天内每小时负载最低的 CPU 用量,计算按 50%(可配置)利用率和工作负载 CPU Request 应配置的副本数。
  当我们部署 crane 的时候会在同一个命名空间中创建一个名为  recommendation-configuration  的 ConfigMap 对象,包含一个 yaml 格式的 RecommendationConfiguration ,该配置订阅了 recommender  的配置,如下所示: $ kubectl get cm recommendation-configuration -n crane-system -oyaml apiVersion: v1 data:   config.yaml: |-     apiVersion: analysis.crane.io/v1alpha1     kind: RecommendationConfiguration     recommenders:       - name: Replicas  # 副本数推荐         acceptedResources:           - kind: Deployment             apiVersion: apps/v1           - kind: StatefulSet             apiVersion: apps/v1       - name: Resource  # 资源推荐         acceptedResources:           - kind: Deployment             apiVersion: apps/v1           - kind: StatefulSet             apiVersion: apps/v1 kind: ConfigMap metadata:   name: recommendation-configuration   namespace: crane-system
  需要注意的是资源类型和 recommenders 需要可以匹配,比如 Resource 推荐默认只支持 Deployments 和 StatefulSets。
  同样的也可以再查看一次闲置节点推荐规则的资源对象,如下所示:  $ kubectl get recommendationrule idlenodes-rule -oyaml apiVersion: analysis.crane.io/v1alpha1 kind: RecommendationRule metadata:   labels:     analysis.crane.io/recommendation-rule-preinstall: "true"   name: idlenodes-rule spec:   namespaceSelector:     any: true   recommenders:   - name: IdleNode   resourceSelectors:   - apiVersion: v1     kind: Node   runInterval: 24h
  创建  RecommendationRule  配置后,RecommendationRule 控制器会根据配置定期运行推荐任务,给出优化建议生成 Recommendation  对象,然后我们可以根据优化建议 Recommendation  调整资源配置。
  比如我们这里集群中已经生成了多个优化建议  Recommendation  对象。 $ kubectl get recommendations NAME                            TYPE       TARGETKIND    TARGETNAMESPACE   TARGETNAME       STRATEGY   PERIODSECONDS   ADOPTIONTYPE          AGE workloads-rule-resource-8whzs   Resource   StatefulSet   default           nacos            Once                       StatusAndAnnotation   34m workloads-rule-resource-hx4cp   Resource   StatefulSet   default           redis-replicas   Once                       StatusAndAnnotation   34m # ......
  可以随便查看任意一个优化建议对象。  $ kubectl get recommend workloads-rule-resource-g7nwp -n crane-system -oyaml apiVersion: analysis.crane.io/v1alpha1 kind: Recommendation metadata:   name: workloads-rule-resource-g7nwp   namespace: crane-system spec:   adoptionType: StatusAndAnnotation   completionStrategy:     completionStrategyType: Once   targetRef:     apiVersion: apps/v1     kind: Deployment     name: fadvisor     namespace: crane-system   type: Resource status:   action: Patch   conditions:   - lastTransitionTime: "2022-10-20T07:43:49Z"     message: Recommendation is ready     reason: RecommendationReady     status: "True"     type: Ready   currentInfo: "{"spec":{"template":{"spec":{"containers":[{"name":"fadvisor","resources":{"requests":{"cpu":"0","memory":"0"}}}]}}}}"   lastUpdateTime: "2022-10-20T07:43:49Z"   recommendedInfo: "{"spec":{"template":{"spec":{"containers":[{"name":"fadvisor","resources":{"requests":{"cpu":"114m","memory":"120586239"}}}]}}}}"   recommendedValue: |     resourceRequest:       containers:       - containerName: fadvisor         target:           cpu: 114m           memory: "120586239"   targetRef: {}
  在 dashboard 的 资源推荐 页面也能查看到优化建议列表。
  在页面中可以看到当前资源(容器/CPU/Memory)与推荐的资源数据,点击 采纳建议 即可获取优化的执行命令。
  执行命令即可完成优化,其实就是修改资源对象的  resources  资源数据。  patchData=`kubectl get recommend workloads-rule-resource-g7nwp -n crane-system -o jsonpath="{.status.recommendedInfo}"`;kubectl patch Deployment fadvisor -n crane-system --patch "${patchData}"
  对于闲置节点推荐,由于节点的下线在不同平台上的步骤不同,用户可以根据自身需求进行节点的下线或者缩容。
  应用在监控系统(比如 Prometheus)中的历史数据越久,推荐结果就越准确,建议生产上超过两周时间。对新建应用的预测往往不准。  自定义推荐
  Recommendation Framework 提供了一套可扩展的 Recommender 框架并支持了内置的 Recommender,用户可以实现一个自定义的 Recommender,或者修改一个已有的 Recommender。
  和 K8s 调度框架类似,Recommender 接口定义了一次推荐需要实现的 四个阶段和八个扩展点 ,这些扩展点会在推荐过程中按顺序被调用。这些扩展点中的一些可以改变推荐决策,而另一些仅用来提供信息。
  推荐框架架构
  Recommender 接口定义如下所示:  type Recommender interface {  Name() string  framework.Filter  framework.PrePrepare  framework.Prepare  framework.PostPrepare  framework.PreRecommend  framework.Recommend  framework.PostRecommend  framework.Observe }  // Phase: Filter type Filter interface {     // Filter 将过滤无法通过目标推荐器推荐的资源     Filter(ctx *RecommendationContext) error }  // Phase: Prepare type PrePrepare interface {     CheckDataProviders(ctx *RecommendationContext) error }  type Prepare interface {     CollectData(ctx *RecommendationContext) error }  type PostPrepare interface {     PostProcessing(ctx *RecommendationContext) error }  type PreRecommend interface {     PreRecommend(ctx *RecommendationContext) error }  // Phase: Recommend type Recommend interface {     Recommend(ctx *RecommendationContext) error }  type PostRecommend interface {     Policy(ctx *RecommendationContext) error }  // Phase: Observe type Observe interface {     Observe(ctx *RecommendationContext) error }
  整个推荐过程分成了四个阶段: Filter 、Prepare 、Recommend 、Observe ,阶段的输入是需要分析的 Kubernetes 资源,输出是推荐的优化建议。接口中的 RecommendationContext  保存了一次推荐过程中的上下文,包括推荐目标、RecommendationConfiguration 等信息,我们可以根据自身需求增加更多的内容。
  比如资源推荐就实现了 Recommender 接口,主要做了下面 3 个阶段的处理:  Filter 阶段:过滤没有 Pod 的工作负载  Recommend 推荐:采用 VPA 的滑动窗口算法分别计算每个容器的 CPU 和内存并给出对应的推荐值  Observe 推荐:将推荐资源配置记录到  crane_analytics_replicas_recommendation  指标
  除了核心的智能推荐功能之外,Crane 还有很多高级特性,比如可以根据实际的节点利用率的动态调度器、基于流量预测的弹性 HPA 等等。  智能调度器
  Crane  除了提供了智能推荐功能之外,还提供了一个调度器插件 Crane-scheduler  可以实现智能调度和完成拓扑感知调度与资源分配的工作。 动态调度器
  K8s 的原生调度器只能通过资源的 requests 值来调度 pod,这很容易造成一系列负载不均的问题:  对于某些节点,实际负载与资源请求相差不大,这会导致很大概率出现稳定性问题。  对于其他节点来说,实际负载远小于资源请求,这将导致资源的巨大浪费。
  为了解决这些问题,动态调度器根据实际的节点利用率构建了一个简单但高效的模型,并过滤掉那些负载高的节点来平衡集群。
  动态调度器依赖于 prometheus 和 node-exporter 收集汇总指标数据,它由两个组件组成:  Node-annotator  定期从 Prometheus 拉取数据,并以 annotations 的形式在节点上用时间戳标记它们。 Dynamic plugin  直接从节点的 annotations 中读取负载数据,过滤并基于简单的算法对候选节点进行评分。
  动态调度器提供了一个默认值调度策略,配置文件如下所示:  # policy.yaml apiVersion: scheduler.policy.crane.io/v1alpha1  kind: DynamicSchedulerPolicy  spec:    syncPolicy:      ##cpu usage      - name: cpu_usage_avg_5m        period: 3m      - name: cpu_usage_max_avg_1h        period: 15m      - name: cpu_usage_max_avg_1d        period: 3h      ##memory usage      - name: mem_usage_avg_5m        period: 3m      - name: mem_usage_max_avg_1h        period: 15m      - name: mem_usage_max_avg_1d        period: 3h     predicate:      ##cpu usage      - name: cpu_usage_avg_5m        maxLimitPecent: 0.65      - name: cpu_usage_max_avg_1h        maxLimitPecent: 0.75      ##memory usage      - name: mem_usage_avg_5m        maxLimitPecent: 0.65      - name: mem_usage_max_avg_1h        maxLimitPecent: 0.75     priority:      ##cpu usage      - name: cpu_usage_avg_5m        weight: 0.2      - name: cpu_usage_max_avg_1h        weight: 0.3      - name: cpu_usage_max_avg_1d        weight: 0.5      ##memory usage      - name: mem_usage_avg_5m        weight: 0.2      - name: mem_usage_max_avg_1h        weight: 0.3      - name: mem_usage_max_avg_1d        weight: 0.5     hotValue:      - timeRange: 5m        count: 5      - timeRange: 1m        count: 2
  我们可以根据实际需求自定义该策略配置,默认策略依赖于以下指标:  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
  这几个指标我们这里是通过记录规则创建的,可以查看 Prometheus 的配置文件来了解详细信息:  $ kubectl get cm -n crane-system prometheus-server -oyaml apiVersion: v1 data:   alerting_rules.yml: |     {}   alerts: |     {}   allow-snippet-annotations: "false"   prometheus.yml: |     global:       evaluation_interval: 1m       scrape_interval: 1m       scrape_timeout: 10s     rule_files:     - /etc/config/recording_rules.yml     - /etc/config/alerting_rules.yml     - /etc/config/rules     - /etc/config/alerts     scrape_configs:     - job_name: prometheus       static_configs:       - targets:         - localhost:9090     # ......   recording_rules.yml: |     groups:     - interval: 3600s       name: costs.rules       rules:     #   ......     - interval: 30s       name: scheduler.rules.30s       rules:       - expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[90s]))           * 100)         record: cpu_usage_active       - expr: 100*(1-node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes)         record: mem_usage_active     - interval: 1m       name: scheduler.rules.1m       rules:       - expr: avg_over_time(cpu_usage_active[5m])         record: cpu_usage_avg_5m       - expr: avg_over_time(mem_usage_active[5m])         record: mem_usage_avg_5m     - interval: 5m       name: scheduler.rules.5m       rules:       - expr: max_over_time(cpu_usage_avg_5m[1h])         record: cpu_usage_max_avg_1h       - expr: max_over_time(cpu_usage_avg_5m[1d])         record: cpu_usage_max_avg_1d       - expr: max_over_time(mem_usage_avg_5m[1h])         record: mem_usage_max_avg_1h       - expr: max_over_time(mem_usage_avg_5m[1d])         record: mem_usage_max_avg_1d   rules: |     {} kind: ConfigMap metadata:   name: prometheus-server   namespace: crane-system
  在调度的 Filter 阶段,如果该节点的实际使用率大于上述任一指标的阈值,则该节点将被过滤。而在 Score 阶段,最终得分是这些指标值的加权和。
  在生产集群中,可能会频繁出现调度热点,因为创建 Pod 后节点的负载不能立即增加。因此,我们定义了一个额外的指标,名为  hotValue ,表示节点最近几次的调度频率,并且节点的最终优先级是最终得分减去 hotValue。
  我们可以在 K8s 集群中安装  Crane-scheduler  作为第二个调度器来进行验证: $ helm repo add crane https://finops-helm.pkg.coding.net/gocrane/gocrane $ helm upgrade --install scheduler -n crane-system --create-namespace --set global.prometheusAddr="http://prometheus-server.crane-system.svc.cluster.local:8080" crane/scheduler
  安装后会创建一个名为  scheduler-config  的 ConfigMap 对象,里面包含的就是调度器的配置文件,我们会在配置中启用 Dynamic 动态调度插件: $ kubectl get cm -n crane-system scheduler-config -oyaml apiVersion: v1 data:   scheduler-config.yaml: |     apiVersion: kubescheduler.config.k8s.io/v1beta2     kind: KubeSchedulerConfiguration     leaderElection:       leaderElect: false     profiles:     - schedulerName: crane-scheduler       plugins:         filter:           enabled:           - name: Dynamic         score:           enabled:           - name: Dynamic             weight: 3       pluginConfig:       - name: Dynamic         args:           policyConfigPath: /etc/kubernetes/policy.yaml kind: ConfigMap metadata:   name: scheduler-config   namespace: crane-system
  安装完成后我们可以任意创建一个 Pod,并通过设置  schedulerName: crane-scheduler  属性明确指定使用该调度器进行调度,如下所示: apiVersion: apps/v1 kind: Deployment metadata:   name: cpu-stress spec:   selector:     matchLabels:       app: cpu-stress   replicas: 1   template:     metadata:       labels:         app: cpu-stress     spec:       schedulerName: crane-scheduler       hostNetwork: true       tolerations:         - key: node.kubernetes.io/network-unavailable           operator: Exists           effect: NoSchedule       containers:         - name: stress           image: docker.io/gocrane/stress:latest           command: ["stress", "-c", "1"]           resources:             requests:               memory: "1Gi"               cpu: "1"             limits:               memory: "1Gi"               cpu: "1"
  直接创建上面的资源对象,正常创建的 Pod 就会通过  Crane Scheduler  调度器进行调度了: Events:   Type    Reason     Age   From             Message   ----    ------     ----  ----             -------   Normal  Scheduled  22s   crane-scheduler  Successfully assigned default/cpu-stress-cc8656b6c-hsqdg to node2   Normal  Pulling    22s   kubelet          Pulling image "docker.io/gocrane/stress:latest"
  如果想默认使用该动态调度器,则可以使用该调度器去替换掉默认的调度器即可。  拓扑感知调度
  Crane-Scheduler 和 Crane-Agent 配合工作可以完成拓扑感知调度与资源分配的工作。Crane-Agent 从节点采集资源拓扑,包括 NUMA、Socket、设备等信息,汇总到  NodeResourceTopology  这个自定义资源对象中。
  CPU 拓扑感知
  Crane-Scheduler 在调度时会参考节点的  NodeResourceTopology  对象获取到节点详细的资源拓扑结构,在调度到节点的同时还会为 Pod 分配拓扑资源,并将结果写到 Pod 的 annotations 中。Crane-Agent 在节点上 Watch 到 Pod 被调度后,从 Pod 的 annotations 中获取到拓扑分配结果,并按照用户给定的 CPU 绑定策略进行 CPUSet 的细粒度分配。
  Crane 中提供了四种 CPU 分配策略,分别如下:  none :该策略不进行特别的 CPUSet 分配,Pod 会使用节点 CPU 共享池。exclusive :该策略对应 kubelet 的 static 策略,Pod 会独占 CPU 核心,其他任何 Pod 都无法使用。numa :该策略会指定 NUMA Node,Pod 会使用该 NUMA Node 上的 CPU 共享池。immovable :该策略会将 Pod 固定在某些 CPU 核心上,但这些核心属于共享池,其他 Pod 仍可使用。
  首先需要在 Crane-Agent 启动参数中添加  --feature-gates=NodeResourceTopology=true,CraneCPUManager=true  开启拓扑感知调度特性。
  然后修改 kube-scheduler 的配置文件( scheduler-config.yaml  ) 启用动态调度插件并配置插件参数: apiVersion: kubescheduler.config.k8s.io/v1beta2 kind: KubeSchedulerConfiguration leaderElection:   leaderElect: true clientConnection:   kubeconfig: "REPLACE_ME_WITH_KUBE_CONFIG_PATH" profiles:   - schedulerName: default-scheduler # 可以改成自己的调度器名称     plugins:       preFilter:         enabled:           - name: NodeResourceTopologyMatch       filter:         enabled:           - name: NodeResourceTopologyMatch       score:         enabled:           - name: NodeResourceTopologyMatch             weight: 2       reserve:         enabled:           - name: NodeResourceTopologyMatch       preBind:         enabled:           - name: NodeResourceTopologyMatch
  正确安装组件后,每个节点均会生成  NodeResourceTopology  对象。 $ kubectl get nrt NAME    CRANE CPU MANAGER POLICY   CRANE TOPOLOGY MANAGER POLICY   AGE node1   Static                     SingleNUMANodePodLevel          35d
  可以看出集群中节点  node1  已生成对应的 NRT 对象,此时 Crane 的 CPU Manager Policy 为 Static ,节点默认的 Topology Manager Policy 为 SingleNUMANodePodLevel ,代表节点不允许跨 NUMA 分配资源。
  使用以下实例进行调度测试:  apiVersion: apps/v1 kind: Deployment metadata:   name: nginx-deployment   labels:     app: nginx spec:   selector:     matchLabels:       app: nginx   template:     metadata:       annotations:         topology.crane.io/topology-awareness: "true" # 添加注解,表示Pod需要感知CPU拓扑,资源分配不允许跨NUMA。若不指定,则拓扑策略默认继承节点上的topology.crane.io/topology-awareness标签         topology.crane.io/cpu-policy: "exclusive" # 添加注解,表示Pod的CPU分配策略为exclusive策略。       labels:         app: nginx     spec:       containers:         - image: nginx           name: nginx           resources:             limits:               cpu: "2" # 需要limits.cpu值,如果要开启绑核,则该值必须等于requests.cpu。               memory: 2Gi
  应用后可以从 annotations 中查看 Pod 的拓扑分配结果,发现 Pod 在 NUMA Node0 上被分配了 2 个 CPU 核心。  $ kubectl get pod -o custom-columns=name:metadata.name,topology-result:metadata.annotations."topology.crane.io/topology-result" name                                topology-result nginx-deployment-754d99dcdf-mtcdp   [{"name":"node0","type":"Node","resources":{"capacity":{"cpu":"2"}}}] 实现基于流量预测的弹性
  Kubernetes HPA 支持了丰富的弹性扩展能力,Kubernetes 平台开发者部署服务实现自定义 Metric 的服务,Kubernetes 用户配置多项内置的资源指标或者自定义 Metric 指标实现自定义水平弹性。
  EffectiveHorizontalPodAutoscaler (简称 EHPA )是 Crane 提供的弹性伸缩产品,它基于社区 HPA 做底层的弹性控制,支持更丰富的弹性触发策略(预测,观测,周期),让弹性更加高效,并保障了服务的质量。 提前扩容,保证服务质量:通过算法预测未来的流量洪峰提前扩容,避免扩容不及时导致的雪崩和服务稳定性故障。  减少无效缩容:通过预测未来可减少不必要的缩容,稳定工作负载的资源使用率,消除突刺误判。  支持 Cron 配置:支持 Cron-based 弹性配置,应对大促等异常流量洪峰。  兼容社区:使用社区 HPA 作为弹性控制的执行层,能力完全兼容社区。
  Effective HPA 兼容社区的 Kubernetes HPA 的能力,提供了更智能的弹性策略,比如基于预测的弹性和基于 Cron 周期的弹性等。在了解如何使用 EHPA 之前,我们有必要来详细了解下 K8s 中的 HPA 对象。通过此伸缩组件,Kubernetes 集群可以利用监控指标(CPU 使用率等)自动扩容或者缩容服务中的 Pod 数量,当业务需求增加时,HPA 将自动增加服务的 Pod 数量,提高系统稳定性,而当业务需求下降时,HPA 将自动减少服务的 Pod 数量,减少对集群资源的请求量,甚至还可以配合 Cluster Autoscaler 实现集群规模的自动伸缩,节省 IT 成本。
  不过目前默认的 HPA 对象只能支持根据 CPU 和内存的阈值检测扩缩容,但也可以通过 custom metric api 来调用 Prometheus 实现自定义 metric,这样就可以实现更加灵活的监控指标实现弹性伸缩了。
  默认情况下,HPA 会通过  metrics.k8s.io  这个接口服务来获取 Pod 的 CPU、内存指标,CPU 和内存这两者属于核心指标,metrics.k8s.io  服务对应的后端服务一般是 metrics-server,所以在使用 HPA 的时候需要安装该应用。
  如果 HPA 要通过非 CPU、内存的其他指标来伸缩容器,我们则需要部署一套监控系统如 Prometheus,让 Prometheus 采集各种指标,但是 Prometheus 采集到的 metrics 指标并不能直接给 K8s 使用,因为两者数据格式是不兼容的,因此需要使用到另外一个组件  prometheus-adapter ,该组件可以将 Prometheus 的 metrics 指标数据格式转换成 K8s API 接口能识别的格式,另外我们还需要在 K8s 注册一个服务(即 custom.metrics.k8s.io ),以便 HPA 能通过 /apis/  进行访问。
  需要注意的是 Crane 提供了一个  metric-adapter  组件,该组件和 prometheus-adapter  都基于 custom-metric-apiserver  实现了 Custom Metric 和 External Metric 的 ApiService ,在安装 Crane 时会将对应的 ApiService  安装为 Crane 的 metric-adapter ,所以它会和 prometheus-adapter  冲突,因为 Prometheus 是当下最流行的开源监控系统,所以我们更愿意使用它来获取用户的自定义指标,那么我们就需要去安装 prometheus-adapter ,但是在安装之前需要删除 Crane 提供的 ApiService 。 # 查看当前集群 ApiService $ kubectl get apiservice |grep crane-system v1beta1.custom.metrics.k8s.io          crane-system/metric-adapter                    True                      3h51m v1beta1.external.metrics.k8s.io        crane-system/metric-adapter                    True                      3h51m  # 删除 crane 安装的 ApiService $ kubectl delete apiservice v1beta1.custom.metrics.k8s.io $ kubectl delete apiservice v1beta1.external.metrics.k8s.io
  然后通过 Helm Chart 来安装 Prometheus Adapter:  $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts $ helm repo update # 指定有 prometheus 地址 $ helm upgrade --install prometheus-adapter -n crane-system prometheus-community/prometheus-adapter --set image.repository=cnych/prometheus-adapter,prometheus.url=http://prometheus-server.crane-system.svc,prometheus.port=8080
  当  prometheus-adapter  安装成功后我们再将 ApiService 改回 Crane 的 metric-adapter ,应用下面的资源清单即可: apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata:   name: v1beta1.custom.metrics.k8s.io spec:   service:     name: metric-adapter     namespace: crane-system   group: custom.metrics.k8s.io   version: v1beta1   insecureSkipTLSVerify: true   groupPriorityMinimum: 100   versionPriority: 100 --- apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata:   name: v1beta1.external.metrics.k8s.io spec:   service:     name: metric-adapter     namespace: crane-system   group: external.metrics.k8s.io   version: v1beta1   insecureSkipTLSVerify: true   groupPriorityMinimum: 100   versionPriority: 100
  应用了上面的对象后,ApiService 改回了 Crane 的  metric-adapter ,那么就不能使用 prometheus-adapter  的自定义 Metrics 功能,我们可以通过 Crane 的 metric-adapter  提供的 RemoteAdapter  功能将请求转发给 prometheus-adapter 。
  修改  metric-adapter  的配置,将 prometheus-adapter  的 Service 配置成 Crane Metric Adapter 的 RemoteAdapter 。 $ kubectl edit deploy metric-adapter -n crane-system apiVersion: apps/v1 kind: Deployment metadata:   name: metric-adapter   namespace: crane-system spec:   template:     spec:       containers:       - args:         # 添加外部 Adapter 配置         - --remote-adapter=true         - --remote-adapter-service-namespace=crane-system         - --remote-adapter-service-name=prometheus-adapter         - --remote-adapter-service-port=443 # ......
  这是因为 Kubernetes  限制一个 ApiService 只能配置一个后端服务 ,为了在一个集群内使用 Crane 提供的 Metric 和 prometheus-adapter  提供的 Metric,Crane 支持了 RemoteAdapter  来解决该问题: Crane Metric-Adapter 支持配置一个 Kubernetes Service 作为一个远程 Adapter  Crane Metric-Adapter 处理请求时会先检查是否是 Crane 提供的 Local Metric,如果不是,则转发给远程 Adapter
  下面我们来部署一个示例应用,用来测试自定义指标的容器弹性伸缩。如下所示的应用暴露了 Metric 展示每秒收到的 http 请求数量。  # sample-app.yaml apiVersion: apps/v1 kind: Deployment metadata:   name: sample-app spec:   selector:     matchLabels:       app: sample-app   template:     metadata:       labels:         app: sample-app     spec:       containers:         - image: luxas/autoscale-demo:v0.1.2           name: metrics-provider           resources:             limits:               cpu: 500m             requests:               cpu: 200m           ports:             - containerPort: 8080 --- apiVersion: v1 kind: Service metadata:   name: sample-app spec:   ports:     - name: http       port: 80       targetPort: 8080   selector:     app: sample-app   type: NodePort
  当应用部署完成后,我们可以通过命令检查  http_requests_total  指标数据: $ curl http://$(kubectl get service sample-app -o jsonpath="{ .spec.clusterIP }")/metrics # HELP http_requests_total The amount of requests served by the server in total # TYPE http_requests_total counter http_requests_total 1
  然后我们需要在 Prometheus 中配置抓取  sample-app  的指标,我们这里使用如下所示命令添加抓取配置: $ kubectl edit cm -n crane-system prometheus-server # 添加抓取 sample-app 配置 - job_name: sample-app   kubernetes_sd_configs:   - role: pod   relabel_configs:   - action: keep     regex: default;sample-app-(.+)     source_labels:     - __meta_kubernetes_namespace     - __meta_kubernetes_pod_name   - action: labelmap     regex: __meta_kubernetes_pod_label_(.+)   - action: replace     source_labels:     - __meta_kubernetes_namespace     target_label: namespace   - source_labels: [__meta_kubernetes_pod_name]     action: replace     target_label: pod
  配置生效后我们可以在 Prometheus Dashboard 中查询对应的指标:
  为了让 HPA 能够用到 Prometheus 采集到的指标, prometheus-adapter  通过使用 promql 语句来获取指标,然后修改数据格式,并把重新组装的指标和值通过自己的接口暴露。而 HPA 会通过 /apis/custom.metrics.k8s.io/  代理到 prometheus-adapter  的 service 上来获取这些指标。
  如果把 Prometheus 的所有指标到获取一遍并重新组装,那 adapter 的效率必然十分低下,因此 adapter 将需要读取的指标设计成可配置,让用户通过 ConfigMap 来决定读取 Prometheus 的哪些监控指标。
  我们这里使用 Helm Chart 方式安装的  prometheus-adapter ,其默认的 Rule 配置如下所示: $ kubectl get cm -n crane-system prometheus-adapter -oyaml apiVersion: v1 data:   config.yaml: |     rules:     - seriesQuery: "{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}"       seriesFilters: []       resources:         overrides:           namespace:             resource: namespace           pod:             resource: pod       name:         matches: ^container_(.*)_seconds_total$         as: ""       metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[5m]))         by (<<.GroupBy>>)     # ...... 其他规则省略 kind: ConfigMap metadata:   name: prometheus-adapter   namespace: crane-system
  Prometheus adapter 的配置文件格式如上所示,它分为两个部分,第一个是  rules ,用于 custom metrics,另一个是 resourceRules ,用于 metrics,如果你只用 Prometheus adapter 做 HPA,那么 resourceRules  就可以省略。
  我们可以看到  rules  规则下面有很多的查询语句,这些查询语句的作用就是尽可能多的获取指标,从而让这些指标都可以用于 HPA。也就是说通过 prometheus-adapter  可以将 Prometheus 中的任何一个指标都用于 HPA,但是前提是你得通过查询语句将它拿到(包括指标名称和其对应的值)。也就是说,如果你只需要使用一个指标做 HPA,那么你完全就可以只写一条查询,而不像上面使用了好多个查询。整体上每个规则大致可以分为 4 个部分: Discovery :它指定 Adapter 应该如何找到该规则的所有 Prometheus 指标 Association :指定 Adapter 应该如何确定和特定的指标关联的 Kubernetes 资源 Naming :指定 Adapter 应该如何在自定义指标 API 中暴露指标 Querying :指定如何将对一个获多个 Kubernetes 对象上的特定指标的请求转换为对 Prometheus 的查询
  我们这里使用的 sample-app 应用的指标名叫  http_requests_total ,通过上面的规则后会将 http_requests_total  转换成 Pods 类型的 Custom Metric,可以获得类似于 pods/http_requests  这样的数据。
  执行以下命令,通过 Custom Metrics 指标查询方式,查看 HPA 可用指标详情。  $ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests" | jq . {   "kind": "MetricValueList",   "apiVersion": "custom.metrics.k8s.io/v1beta1",   "metadata": {     "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/http_requests"   },   "items": [     {       "describedObject": {         "kind": "Pod",         "namespace": "default",         "name": "sample-app-6876d5585b-wv8fl",         "apiVersion": "/v1"       },       "metricName": "http_requests",       "timestamp": "2022-10-27T11:19:05Z",       "value": "18m",       "selector": null     }   ] }
  接下来我们就可以来测试下基于流量预测的容器弹性伸缩,这就需要用到 Crane 的 EHPA 对象了,我们可以使用上面的  pods/http_requests  自定义指标来实现弹性功能。
  许多业务在时间序列上天然存在周期性的,尤其是对于那些直接或间接为"人"服务的业务。这种周期性是由人们日常活动的规律性决定的。例如,人们习惯于中午和晚上点外卖;早晚总有交通高峰;即使是搜索等模式不那么明显的服务,夜间的请求量也远低于白天时间。对于这类业务相关的应用来说,从过去几天的历史数据中推断出次日的指标,或者从上周一的数据中推断出下周一的访问量是很自然的想法。通过预测未来 24 小时内的指标或流量模式,我们可以更好地管理我们的应用程序实例,稳定我们的系统,同时降低成本。EHPA 对象可以使用 DSP 算法来预测应用未来的时间序列数据,DSP 是一种预测时间序列的算法,它基于 FFT(快速傅里叶变换),擅长预测一些具有季节性和周期的时间序列。
  创建一个如下所示的 EHPA 资源对象,并开启预测功能:  # sample-app-ehpa.yaml apiVersion: autoscaling.crane.io/v1alpha1 kind: EffectiveHorizontalPodAutoscaler metadata:   name: sample-app-ehpa   annotations:     # metric-query.autoscaling.crane.io 是固定的前缀,后面是 前缀.Metric名字,需跟 spec.metrics 中的 Metric.name 相同,前缀支持 pods、resource、external     metric-query.autoscaling.crane.io/pods.http_requests: "sum(rate(http_requests_total[5m])) by (pod)" spec:   # ScaleTargetRef 是对需要缩放的工作负载的引用   scaleTargetRef:     apiVersion: apps/v1     kind: Deployment     name: sample-app   # minReplicas 是可以缩小到的缩放目标的最小副本数   minReplicas: 1   # maxReplicas 是可以扩大到的缩放目标的最大副本数   maxReplicas: 10   # scaleStrategy 表示缩放目标的策略,值可以是 Auto 或 Manual   scaleStrategy: Auto   # metrics 包含用于计算所需副本数的规范。   metrics:     # 在使用预测算法预测时,你可能会担心预测数据不准带来一定的风险,EHPA 在计算副本数时,不仅会按预测数据计算,同时也会考虑实际监控数据来兜底,提升弹性的安全性,所以可以定义下面的 Resource 监控数据来兜底     # - type: Resource     - type: Pods       pods:         metric:           name: http_requests         target:           type: AverageValue           averageValue: 500m # 当出现了小数点,K8s 又需要高精度时,会使用单位 m 或k。例如1001m=1.001,1k=1000。   # prediction 定义了预测资源的配置,如果未指定,则默认不启用预测功能   prediction:     predictionWindowSeconds: 3600 # PredictionWindowSeconds 是预测未来指标的时间窗口     predictionAlgorithm:       algorithmType: dsp # 指定dsp为预测算法       dsp:         sampleInterval: "60s" # 监控数据的采样间隔为1分钟         historyLength: "7d" # 拉取过去7天的监控指标作为预测的依据
  在上面的资源对象中添加了一个  metric-query.autoscaling.crane.io/pods.http_requests: "sum(rate(http_requests_total[5m])) by (pod)"  的 注解,这样就可以开启自定义指标的预测功能了。
  相应的在规范中定义了  spec.prediction  属性,用来指定预测资源的配置,其中的 predictionWindowSeconds  属性用来指定预测未来指标的时间窗口,predictionAlgorithm  属性用来指定预测的算法,比如我们这里配置的 algorithmType: dsp  表示使用 DSP(Digital Signal Processing)算法进行预测,该算法使用在数字信号处理领域中常用的的离散傅里叶变换、自相关函数等手段来识别、预测周期性的时间序列,关于该算法的实现原理可以查看官方文档 https://gocrane.io/zh-cn/docs/tutorials/timeseriees-forecasting-by-dsp/  的相关介绍,或者查看源码以了解背后原理,相关代码位于 pkg/prediction/dsp  目录下。此外在 prediction.predictionAlgorithm.dsp  下面还可以配置 dsp 算法的相关参数,比如我们这里配置的 sampleInterval: "60s"  表示监控数据的采样间隔为 1 分钟,historyLength: "7d"  表示拉取过去 7 天的监控指标作为预测的依据,此外还可以配置预测方式等。
  然后核心的配置就是  spec.metrics  了,用来指定计算所需副本数的规范,我们这里指定了基于 Pods  指标的计算方式。 - type: Pods   pods:     metric:       name: http_requests     target:       type: AverageValue       averageValue: 500m
  上面的配置表示当  pods/http_requests  的自定义指标平均值达到 500m 后就可以触发 HPA 缩放,这里有一个点需要注意自定义指标的 pods.metric.name  的值必须和 annotations 注解 metric-query.autoscaling.crane.io/pods.  指标名保持一致。
  EHPA 对象水平弹性的执行流程如下所示:  EffectiveHPAController  创建 HorizontalPodAutoscaler  和 TimeSeriesPrediction  对象 PredictionCore  从 Prometheus 获取历史 metric 通过预测算法计算,将结果记录到 TimeSeriesPrediction  HPAController  通过 metric client 从 KubeApiServer 读取 metric 数据 KubeApiServer  将请求路由到 Crane 的 Metric-Adapter。 HPAController  计算所有的 Metric 返回的结果得到最终的弹性副本推荐。 HPAController  调用 scale API 对目标应用扩/缩容。
  整体流程如下所示:
  直接应用上面的 EPHA 对象即可:  $ kubectl apply -f sample-app-ehpa.yaml effectivehorizontalpodautoscaler.autoscaling.crane.io/sample-app-ehpa created $ kubectl get ehpa NAME              STRATEGY   MINPODS   MAXPODS   SPECIFICPODS   REPLICAS   AGE sample-app-ehpa   Auto       1         10                       1          17s
  由于我们开启了自动预测功能,所以 EPHA 对象创建后会创建一个对应的  TimeSeriesPrediction  对象: $ kubectl get tsp NAME                   TARGETREFNAME   TARGETREFKIND   PREDICTIONWINDOWSECONDS   AGE ehpa-sample-app-ehpa   sample-app      Deployment      3600                      3m50s $ kubectl get tsp ehpa-sample-app-ehpa -oyaml apiVersion: prediction.crane.io/v1alpha1 kind: TimeSeriesPrediction metadata:   name: ehpa-sample-app-ehpa   namespace: default spec:   predictionMetrics:   - algorithm:       algorithmType: dsp       dsp:         estimators: {}         historyLength: 7d         sampleInterval: 60s     expressionQuery:       expression: sum(http_requests{})     resourceIdentifier: pods.http_requests     type: ExpressionQuery   predictionWindowSeconds: 3600   targetRef:     apiVersion: apps/v1     kind: Deployment     name: sample-app     namespace: default status:   conditions:   - lastTransitionTime: "2022-10-27T13:01:14Z"     message: not all metric predicted     reason: PredictPartial     status: "False"     type: Ready   predictionMetrics:   - ready: false     resourceIdentifier: pods.http_requests
  在 status 中可以看到包含  not all metric predicted  这样的信息,这是因为应用运行时间较短,可能会出现无法预测的情况。同样也会自动创建一个对应的 HPA 对象: $ kubectl get hpa NAME                   REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE ehpa-sample-app-ehpa   Deployment/sample-app   16m/500m   1         10        1          69m
  然后我们可以使用  ab  命令对 sample-app 做一次压力测试,正常也可以触发该应用的弹性扩容。 $ kubectl get svc sample-app NAME         TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE sample-app   NodePort   10.104.163.144           80:31941/TCP   3h59m # 对 nodeport 服务做压力测试 $ ab -c 50 -n 2000 http://192.168.0.106:31941/ $ kubectl get hpa NAME                   REFERENCE               TARGETS      MINPODS   MAXPODS   REPLICAS   AGE ehpa-sample-app-ehpa   Deployment/sample-app   7291m/500m   1         10        10         71m $ kubectl describe hpa ehpa-sample-app-ehpa Name:                       ehpa-sample-app-ehpa # ...... Metrics:                    ( current / target )   "http_requests" on pods:  8350m / 500m Min replicas:               1 Max replicas:               10 Deployment pods:            10 current / 10 desired Conditions:   Type            Status  Reason            Message   ----            ------  ------            -------   AbleToScale     True    ReadyForNewScale  recommended size matches current size   ScalingActive   True    ValidMetricFound  the HPA was able to successfully calculate a replica count from pods metric http_requests   ScalingLimited  True    TooManyReplicas   the desired replica count is more than the maximum replica count Events:   Type    Reason             Age   From                       Message   ----    ------             ----  ----                       -------   Normal  SuccessfulRescale  57s   horizontal-pod-autoscaler  New size: 4; reason: pods metric http_requests above target   Normal  SuccessfulRescale  42s   horizontal-pod-autoscaler  New size: 8; reason: pods metric http_requests above target   Normal  SuccessfulRescale  27s   horizontal-pod-autoscaler  New size: 10; reason: pods metric http_requests above target
  我们可以使用如下所示命令来查看 EHPA 自动生成的 HPA 对象的资源清单:  $ kubectl get hpa.v2beta2.autoscaling ehpa-sample-app-ehpa -oyaml apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata:   name: ehpa-sample-app-ehpa   namespace: default spec:   maxReplicas: 10   metrics:   - pods:       metric:         name: http_requests       target:         averageValue: 500m         type: AverageValue     type: Pods   minReplicas: 1   scaleTargetRef:     apiVersion: apps/v1     kind: Deployment     name: sample-app # ...... 省略其他部分
  可以观测到已经创建出基于自定义指标预测的 Metric:  http_requests ,由于生产环境的复杂性,基于多指标的弹性(CPU/Memory/自定义指标)往往是生产应用的常见选择,因此 Effective HPA 通过预测算法覆盖了多指标的弹性,达到了帮助更多业务在生产环境落地水平弹性的成效。
  除此之外 EHPA 对象还支持基于 cron 的自动缩放,除了基于监控指标,有时节假日和工作日的工作负载流量存在差异,简单的预测算法可能效果不佳。然后可以通过设置周末 cron 来支持更大数量的副本来弥补预测的不足。对于一些非 web 流量的应用,比如一些应用不需要在周末使用,可以把工作负载的副本数减少到 1,也可以配置 cron 来降低你的服务成本。  QOS 增强与混部
  除了上面介绍的主要功能之外,crane 还具有很多 QoS 增强功能,QoS 相关能力保证了运行在 Kubernetes 上的 Pod 的稳定性。crane 具有 干扰检测和主动回避能力 ,当较高优先级的 Pod 受到资源竞争的影响时,Disable Schedule、Throttle 以及 Evict 将应用于低优先级的 Pod,以保证节点整体的稳定,目前已经支持节点的 cpu/内存 负载绝对值/百分比作为水位线,在发生干扰进行驱逐或压制时,会进行精确计算,将负载降低到略低于水位线即停止操作,防止误伤和过渡操作。
  同时,crane 还支持 自定义指标适配整个干扰检测框架 ,只需要完成排序定义等一些操作,即可复用包含精确操作在内的干扰检测和回避流程。
  此外 crane 还具有预测算法增强的 弹性资源超卖能力 ,将集群内的空闲资源复用起来,同时结合 crane 的预测能力,更好地复用闲置资源,当前已经支持 cpu 和内存的空闲资源回收。同时具有弹性资源限制功能,限制使用弹性资源的 workload 最大和最小资源使用量,避免对高优业务的影响和饥饿问题。
  同时具备 增强的旁路 cpuset 管理能力 ,在绑核的同时提升资源利用效率。 总结
  2022 年,腾讯云原生 FinOps Crane 项目组,结合行业及产业的发展趋势,联动中国产业互联网发展联盟、中国信通院、中国电子节能技术协会、FinOps 基金会及中国内外众多生态合作伙伴,开展及推动技术标准、国内联盟、国际开源、双碳升级等多维度的成果落地,输出了系列白皮书和标准指南,旨在助力企业和生态更良性发展和应用先进技术,达成降本增效,节能减排目标方向。
  Crane 能力全景图
  我们可以自己在 K8s 集群中安装 crane 来获取这些相关功能,此外这些能力也都会在腾讯云 TKE 的原生节点产品  Housekeeper  中提供,新推出的 TKE Housekeeper 是腾讯云推出的全新 K8s 运维范式,可以帮助企业像管理 Workload 一样声明式管理 Node 节点,高效解决节点维护、资源规划等各种各样的运维问题。
  毫无疑问,Crane 已经是 K8s 集群中用于云资源分析和经济的最佳 FinOps 平台了。目前,腾讯云 Crane 已进入 CNCF LandScape,这意味着 Crane 已成为云原生领域的重要项目。面向未来,腾讯云还将持续反馈开源社区、共建开源生态,帮助更多企业通过云原生全面释放生产力,加速实现数字化和绿色化双转型。
  最后,上周末举行的腾讯云 Techo Day 技术开放日活动也对 Crane 进行了深入解析,相关资料及课件被收录进了 《腾讯云云原生工具指南》 里,除此以外,里面还涵盖了遨驰分布式云操作系统、微服务等多款热门产品的技术原理解读,帮助开发者用专业方法解决业务痛点,还有多个云原生实践标杆案例分享,讲述云原生如何实现价值,非常推荐给感兴趣的朋友下载看看。

南京鬼市上个周,听到朋友聊起鬼市时,我再也按捺不住心里的冲动。毕竟我来南京这么久,还未能一睹传说中的鬼市风采。走啊,这次一定要找到它。南京的鬼市啊,就像它的名字一样,神出鬼没,它游离于光天抗日时期著名战役南京战役勿忘历史抗日战争从1931年9月181945年9月2日长达了14年的战争虽然现在抗日战争胜利77周年了,但是历史不能遗忘,那些国家的英雄也不能遗忘!勿忘历史吾辈自强!今天我们就来讲林郑最近现身内地!香港高官退休后竟然都在打工新一届香港政府上任快两个月了,大家全都斗志昂扬,忙得不可开交。而且你别说,这届港府有点东西,办事效率贼高!说到这,还有人记得已经退休的前特首林郑月娥吗?这边忙得风风火火,另一边的她生长在夹缝中的爱情我是一棵树你也是一棵树相距很近却在两个不同的夹缝中求生你辽望我我凝视你渐渐的我们长大了由于夹缝中的生存环境恶劣常常营养不良风飕日晒,雨水风霜我们相互安慰相互鼓励,共同面对同病相连中劣迹斑斑却捞金不断的十位男星,娱乐圈对他们的宽容,太悲哀这几年,关于男性和女性权利的话题被讨论得很多,以至于引发很多男女对立的争议,这是女性主义崛起的必经之路。尽管大家都高喊男女平等,但是男性和女性依旧无法被公平对待。娱乐圈对男明星和女土耳其芬兰瑞典官员就入约问题召开会议中新网8月26日电据法新社报道,当地时间26日,土耳其芬兰和瑞典的官员召开会议,表示同意在未来几个月继续召开会议讨论土耳其提出的安全问题,以推动北欧两国加入北约北约的进程。据报道,向战而行!火箭军某部生命卫士比武火热来袭近日,火箭军某部依托综合训练场,组织一线救治生命卫士比武,来自基层单位的11支代表队共42名卫生专业官兵同台竞技。据介绍,这次比武区分军医卫生员兼职卫生战士普通官兵4类人员,进行卫把病人当赚钱工具,湘雅二医院恶魔刘屠夫,足够颠覆你的认知湘雅二医院恶魔刘屠夫发声足够毁三观,颠覆你的认知,终于!湘雅恶医刘翔峰接受监察调查,广州举报又起,还有多少刘翔峰,把病人当赚钱工具,严查湘雅二院刘翔峰丑闻问题只是刘翔峰?这背后暴露不会化妆还强行化妆真尴尬,实在是太逗了,哈哈哈哈哈汪星人我不会游泳啊该怎么办呀汪星人看看我的披风,跑起来呼呼响汪星人这个袋子里面是什么呀,是不是吃的呀我怎么感觉这个不是耳环,像是一个钥匙怎么回事呀,是不是开车的时候分心了感觉这跳舞罚罪中的东北帮演员,个个演技精湛,李幼斌连皱纹都是戏在中国演艺圈,东北籍演员,一直都是一个特殊的存在。他们人数众多,从央视春晚的语言类节目,到影视剧制作的方方面面,到处都有着他们的影子,造成这种现象最根本的原因,是什么?有人说,是因结婚仅仅6年就糊了,霍建华的尴尬,是谁的过错?谁能想到,那场婚礼竟成了林心如霍建华事业的分水岭。结婚前,林心如是华语地区街知巷闻的紫薇格格,情深深雨濛濛男才女貌半生缘倾世皇妃等,叫好又叫座,口碑爆棚。而霍建华,长相帅气,尤其古
原子核放大到篮球场那么大,拿(工具)去刮凿挖,能挖到边角料吗?原子核放大到篮球场那么大,拿(工具)去刮凿挖,能挖到边角料吗?这是一个异想天开的问题。因为原子看不到摸不着,许多人就有这种幻想,就希望把它放大来看看到底是个啥模样。现在我们就来通过为什么承德人的性格和东北人的性格很像?承德和东北都是少数民族杂居地,满蒙回汉等,其中以满族居多。承德人多数是从东北迁移过来的,造就人物性格的多元化。承德人既有南方的谨慎智慧,又有东北的粗犷豪迈,大方中透着洒脱,厚道中藏移动宽带报停,不还猫行不行呢?我的移动宽带到期了,平日里因为质量对比电信的宽带,确实存在欠缺,打算把移动的号码携转电信,所以想去注销。第一次去移动营业厅,和我说这里没有权限,要去其他地方,乡镇上共有六个移动营业我已经初二了,对英语一窍不通,有什么英语的语法书推荐一下?你不需要什么语法书,把课文会背的就OK了。下来几个方面告诉你该怎么努力。Thereisnodoubtthatyoucanmakeit。初一的时候我英语也特别特别差,这可能是跟我来自热水器出热水之前总是先出冷水,有什么方法解决?由于热水龙头与热水器直接有一段距离,所以打开水龙头,势必要将水管中的冷水放出,才会有热水流出来。需要等待的时间短则几十秒,长则几分钟。我们住酒店时就会发现,一些酒店的水龙头打开就会ios系统怎么降级?很多朋友都在吐槽升级IOS新系统的BUG,要么手机发烫,耗电快,要么就是手机卡。那么苹果系统是否能够降级呢?目前不能降级的,自6月8日苹果正式关闭了iOS11。3。1系统的验证通道斐讯倒闭了,r1音响现在没有音乐库了,能不能刷成别的系统?k3刚出来就买了,然后存了10万块左右,送了个128m的ipadmini4和几个加速卡,路由器一个月下车,mini4半年后下车,钱存在活期吃每天9的利息。6。25号跟老婆在楼下遛弯孩子从小学开始一直上普通公办学校直到高中毕业不参加任何课外补习课程,保持在全班前十名有可能高考考取985211吗?全班前十名的孩子能不能考上985和211大学?知道吗,某村小学全校不到10个孩子,所有的孩子全是班级前三名,咋判断?班级前十名概念,能够涵盖的范围太广泛了。用全班名次来衡量全省高考乳腺增生不治会癌变,该注意什么?什么是乳腺增生?先说说乳腺组织吧,乳腺组织从乳头的一级导管到乳腺小叶各腺泡,很像是由很多串葡萄组合成的一个半球形器官,葡萄枝是各级导管,一个个葡萄就是小叶中的腺泡。乳腺增生就好比是离开广州300公里有什么好的旅游景点?离广州300公里而又在省界范围内的粤西北部连州,是整个岭南地区最早开化的地方。去年中国国家地理杂志社联合广东省旅游局启动的广东100个最美观景拍摄点活动,经过海选专家评审旅游局把关用什么软件,自驾游用,可以导航标注景点图片记录轨迹?1六只脚APP这个软件的优势,就是可以记录轨迹,可以寻迹别人的轨迹不怕迷路,可以一键导航到别人的出发地点,可以把照片同步到轨迹到坐标上,我出行基本上都会用这个软件。有时候出去玩,爬