一、项目背景

巨大的云浪费

据 Gartner 研究显示:

平均来说企业上云会节省 14% 的成本,但是到 2020 年,由于缺乏成本优化手段,80% 企业的云资源成本将会大幅超出预算;
同时,45% 的企业由于缺乏优化措施,在直接迁移上云的过程中会超买 55%  的资源,并且在上云的第一个 18 个月内会多花费 70%.

在云资源巨大的投入成本和浪费面前,那些当初对上云趋之若鹜的人,甚至开始谈“云”色变。

如何优化和管理不同的公有云成本?这已然成为迫在眉睫的难题。

那在这种情况下,为了减少云上资源的浪费,一种文化革命 FinOps (云成本优化)就应运而生了。

什么是 FinOps

我们先来看一下 FinOps 基金会对 FinOps 的定义:

FinOps 是将 DevOps、财务和业务整合在一起的变革,其目标在于优化一个组织在云计算上的支出的财务规范和技术解决方案,即根据支出的历史记录和来自预期负载的信息,FinOps 可以在需要时预分配资源或估算成本。
FinOps 可以称为“财务运营” ,或者更直白地称为“成本优化”,是将财务问责制引入云的 IT 支持,进行调整以优化质量和支出。

FinOps 可以简单理解为云成本优化,为了更好地规划和预测云消费的支出要求,如今越来越多的公司正在转向 FinOps。

而 Crane 则正是为了 FinOps 的而诞生的。

什么是 Crane

Crane 是一个云原生开源项目,为推进云原生用户在确保业务稳定性的基础上做到真正的极致降本,腾讯推出了国内第一个基于云原生技术的成本优化开源项目 Crane( Cloud Resource Analytics and Economics )

Crane 遵循 FinOps 标准,旨在为云原生用户提供云成本优化一站式解决方案。

Crane的目标是提供一个一站式项目,帮助Kubernetes 用户通过一系列丰富的功能来节省云资源的使用,这些功能包括:

  • 基于监测数据的时间序列预测
  • 使用和成本可见性
  • 使用和成本优化包括:

R2(资源重新分配)
R3(请求和副本推荐)
有效的pod自动缩放(有效的水平和垂直pod自动缩放)

  • 成本优化
  • 基于Pod PriorityClass的增强QoS
  • Load-aware调度

同时,因为 Crane 基于 Prometheus,以及 grafana,它也可以起到对云上资源监控的作用。

为了快速一键化部署 Crane,我们这里选择将 Crane 插件化,作为 Kubevela 的 addon 集成到集群中进行快速使用。

二、Crane作为插件的集成

# 1 项目目录结构

│ metadata.yaml
│ readme.md
│ template.yaml
│
├─image
│     crane-overview.png
│     crane.png
│     wechat.jpeg
│
└─resources├─config│     grafana-config.yaml│     namespace.yaml│     prometheus-config.yaml│├─release│     crane-release.yaml│     fadvisor-release.yaml│     grafana-release.yaml│     prometheus-release.yaml│└─repocrane-repo.yamlgrafana-repo.yamlprometheus-repo.yaml

其中 image 中图片为 readme 中所需的贴图;resource 中的每个 yaml 文件则是定义了一个 k8s resource。

这里将 crane 插件化主要是使用的 Helm 的方式(Kubevela Helm插件),分别将 Prometheus,Grafana,Crane 的 repo 链接引入,然后使用对应的 ConfigMap 中的配置部署对应的 Helm Release。

# 2 添加创建K8s原生资源

创建 crane-system 命名空间:

apiVersion: v1
kind: Namespace
metadata:name: crane-system

创建 Prometheus 配置的 ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:name: prometheusnamespace: crane-system
data:override_values: |## Prometheus server ConfigMap entries##serverFiles:## Records configuration## Ref: https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/recording_rules.yml:groups:- name: costs.rulesinterval: 3600srules:- expr: |sum(label_replace(irate(container_cpu_usage_seconds_total{container!="POD", container!="",image!=""}[1h]), "node", "$1", "instance",  "(.*)")) by (container, pod, node, namespace) * on (node) group_left() avg(avg_over_time(node_cpu_hourly_cost[1h])) by (node)record: namespace:container_cpu_usage_costs_hourly:sum_rate- expr: |sum(label_replace(avg_over_time(container_memory_working_set_bytes{container!="POD",container!="",image!=""}[1h]), "node", "$1", "instance",  "(.*)")) by (container, pod, node, namespace) / 1024.0 / 1024.0 / 1024.0 * on (node) group_left() avg(avg_over_time(node_ram_hourly_cost[1h])) by (node)record: namespace:container_memory_usage_costs_hourly:sum_rate- expr: |avg(avg_over_time(node_cpu_hourly_cost[1h])) by (node)record: node:node_cpu_hourly_cost:avg- expr: |avg(avg_over_time(node_ram_hourly_cost[1h])) by (node)record: node:node_ram_hourly_cost:avg- expr: |avg(avg_over_time(node_total_hourly_cost[1h])) by (node)record: node:node_total_hourly_cost:avg- name: scheduler.rules.30sinterval: 30srules:- record: cpu_usage_activeexpr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[90s])) * 100)- record: mem_usage_activeexpr: 100*(1-node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes)- name: scheduler.rules.1minterval: 1mrules:- record: cpu_usage_avg_5mexpr: avg_over_time(cpu_usage_active[5m])- record: mem_usage_avg_5mexpr: avg_over_time(mem_usage_active[5m])- name: scheduler.rules.5minterval: 5mrules:- record: cpu_usage_max_avg_1hexpr: max_over_time(cpu_usage_avg_5m[1h])- record: cpu_usage_max_avg_1dexpr: max_over_time(cpu_usage_avg_5m[1d])- record: mem_usage_max_avg_1hexpr: max_over_time(mem_usage_avg_5m[1h])- record: mem_usage_max_avg_1dexpr: max_over_time(mem_usage_avg_5m[1d])# adds additional scrape configs to prometheus.yml# must be a string so you have to add a | after extraScrapeConfigs:# example adds prometheus-blackbox-exporter scrape configextraScrapeConfigs: |-# this is used to scrape fadvisor- job_name: "fadvisor"honor_timestamps: truescheme: httpmetrics_path: /metricsstatic_configs:- targets: ['fadvisor.crane-system.svc.cluster.local:8081']server:service:persistentVolume:enabled: falseannotations: { }labels: { }clusterIP: ""## List of IP addresses at which the Prometheus server service is available## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips##externalIPs: [ ]loadBalancerIP: ""loadBalancerSourceRanges: [ ]servicePort: 8080sessionAffinity: Nonetype: ClusterIPnodeExporter:hostRootfs: falsealertmanager:enabled: falsepushgateway:enabled: falsekubeStateMetrics:## If false, kube-state-metrics sub-chart will not be installed##enabled: true## kube-state-metrics sub-chart configurable values## Please see https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics##kube-state-metrics:prometheus:monitor:honorLabels: trueimage:repository: ccr.ccs.tencentyun.com/tkeimages/kube-state-metricspullPolicy: IfNotPresenttag: "2.2.4"

创建 grafana 配置的 ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:labels:app.kubernetes.io/managed-by: Helmannotations:meta.helm.sh/release-name: grafanameta.helm.sh/release-namespace: crane-systemname: grafananamespace: crane-system
data:override_values: |service:enabled: truetype: ClusterIPport: 8082targetPort: 3000# targetPort: 4181 To be used with a proxy extraContainerannotations: {}labels: {}portName: service# Administrator credentials when not using an existing secret (see below)adminUser: adminadminPassword: admin//...//完整代码,关注公众号【神州数码云基地】后台回复【grafana-config.yaml】领取 

# 3 添加 repo

将Prometheus,granfana,crane的repo作为 HelmRepository 资源添加。

通过添加这个 3 个 repo 我们可以访问到远程的 Helm 仓库以此来使用 Helm 来安装。

创建 crane-system 命名空间:

apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:name: prometheusnamespace: crane-system
spec:interval: 10mtimeout: 5murl: https://prometheus-community.github.io/helm-charts

grafana-repo.yaml:

apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:name: grafananamespace: crane-system
spec:interval: 10mtimeout: 5murl: https://grafana.github.io/helm-charts

crane-repo.yaml:

apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:name: cranenamespace: crane-system
spec:interval: 10mtimeout: 5murl: https://gocrane.github.io/helm-charts

# 4 使用 Helm 部署 Helm release、

部署 Prometheus:

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:name: prometheusnamespace: crane-system
spec:timeoout: 10minterval: 5mchart:spec:chart: prometheusversion: 15.8.5sourceRef:kind: HelmRepositoryname: prometheusinterval: 5mtargetNamespace: crane-systemreleaseName: prometheusvaluesFrom: [{kind: ConfigMap,name: prometheus,valuesKey: override_values}] 

sourceRef为第 3 步中配置的 Helm Repo;

targetName为部署的目标命名空间;

releaseName为选择使用的 Release,因为相同的仓库中可能存在多个,所以这里需要指定特定的 release;

valuesFrom为读取配置文件,这里选择类型为 ConfigMap 同时指定在第一步中创建的 Prometheus 的 cm 名称,valuesKey 为指定的 configMap 中的数据的 key;

部署 grafana :

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:name: grafananamespace: crane-system
spec:timeoout: 10minterval: 5mchart:spec:chart: grafanaversion: 6.28.0sourceRef:kind: HelmRepositoryname: grafanainterval: 5mtargetNamespace: crane-systemreleaseName: grafanavaluesFrom: [{kind: ConfigMap,name: grafana,valuesKey: override_values}]

部署 fadvisor :

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:name: fadvisornamespace: crane-system
spec:timeoout: 10minterval: 5mchart:spec:chart: fadvisorversion: 0.2.0sourceRef:kind: HelmRepositoryname: craneinterval: 5mtargetNamespace: crane-systemreleaseName: fadvisor

这里的fadvisor 为 crane 官方开发的指标采集器。

部署 crane:

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:name: cranenamespace: crane-system
spec:timeoout: 10minterval: 5mchart:spec:chart: craneversion: 0.3.0sourceRef:kind: HelmRepositoryname: craneinterval: 5mtargetNamespace: crane-systemreleaseName: crane

PS:

以上的部署过程需要按顺序执行,但是在 kubevela的 addon 部署中,所有的资源是同时执行的所以有时可能会执行顺序错乱。

但是这部并不会导致整体执行失败,因为 k8s 会有定时的重调机制在重调机制触发时会将错误的资源重新创建。

# 5 enable组件

使用 vela cli 从本地 enable crane 组件;

先到 crane 的本地目录,然后

vela addon enable crane

即可看到每个组件都可以部署,并再 crane-system 的命名空间下可以看到结果类似如下:

# 6 将对应的crane service的访问方式改为NodePort

在部署的环境下使用kubectl get svc -n crane-system 命令查找对应的服务

使用 kubectl edit svc craned -n crane-system 并将type 修改为 NodePort。

这时 k8s 会自动分配一个端口。

使用kubectl get svc craned -n crane-system -o yaml 查看对应端口,即 dashboard-service 的端口

也可以使用以下命令暂时将端口转出:

kubectl port-forward -n crane-system svc/craned 9090

# 7 监控的指标

/ 节点服务器的cpu利用率,内存利用率

/ 命名空间的资源使用情况

同时集群中也添加了对应的 CRD 资源如 EHAP 等。

【云原生】一文讲透Kubevela addon如何添加腾讯Crane相关推荐

  1. js打印线程id_一文讲透“进程,线程和协程”

    一文讲透"进程,线程和协程" 本文从操作系统原理出发结合代码实践讲解了以下内容: 什么是进程,线程和协程? 它们之间的关系是什么? 为什么说Python中的多线程是伪多线程? 不同 ...

  2. 一文讲透『大神修炼心法』!35岁让自己过的越来越好!

    Cocos 的老铁,如果你这几天没有被麒麟子给卷到?那说明你还没有真正进入 Cocos 圈子里来.为什么这么说呢?看下面. 3月1号 23:57 | 2800+字 麒麟子全方位解读 Cocos Cyb ...

  3. 一文讲透植物内生菌研究怎么做 | 微生物专题

    内容导览 1. 隐秘而强大的植物内生菌 2. 难以区分的植物内生菌 3. 更好的植物内生细菌测序方法 3.1 LNA-16S测序鉴定内生细菌原理 3.2 LNA-16S测序鉴定内生细菌占比高达99% ...

  4. 10自带sftp服务器_一文讲透FTP和SFTP的区别

    阅读本文约需要10分钟,您可以先关注我们或收藏本文,避免下次无法找到. FTP和SFTP都是文件传输协议,我们知道FTP使用的是20和21端口,SFTP使用的是22端口.另外,SFTP前面的S应该是S ...

  5. 双线macd指标参数最佳设置_一文讲透双线MACD指标及其实战运用

    原标题:一文讲透双线MACD指标及其实战运用 船长的舍得交易体系技术理论模型中,我们要用到两大指标,分别是均线系统和双线MACD指标. 很多小伙伴都喜欢用双线MACD这个指标,但是90%的人都不知道其 ...

  6. 【敏捷开发】一文讲透敏捷管理中的DoR、DoD与AC

    文章目录 一.需求侧:DoR 案例: DoR是什么? 如何建立DoR的标准? DoR样例 1.需求 2.交互 3.架构 二.研发侧:DoD DoD是什么? 如何建立DoD的标准? DoD样例 三.用户 ...

  7. 阿里巴巴云原生实践 15 讲

    阿里巴巴从 2011 年开始通过容器实践云原生技术体系,在整个业界都还没有任何范例可供参考的大背境下,从最初独自摸索到拥抱开源回馈社区,阿里巴巴逐渐摸索出了一套比肩全球一线技术公司并且服务于整个阿里集 ...

  8. 【hadoop】一文讲透hdfs的delegation token

    1.概述 转载并且补充:一文讲透hdfs的delegation token 最近我也在研究这个,学习一下. 1.1 起因 我最近在做FLink kerberos认证.我在flink配置文件中配置正确的 ...

  9. 一文讲透 Serverless Kubernetes 容器服务

    作者 | 张维(贤维)  阿里云函数计算开发工程师 导读:Serverless Kubernetes 是以容器和 kubernetes 为基础的 Serverless 服务,它提供了一种简单易用.极致 ...

最新文章

  1. 【采用】反欺诈之血缘关系分析和犯罪传导监测 - 知识图谱
  2. 自己动手开发智能聊天机器人完全指南(附python完整源码)
  3. [转载] 人工智能:一种现代方法——第1章 绪论
  4. 镭速-文件传输系统,单机、负载均衡,使用外部AD域用户
  5. Mybatis 详解--- 一级缓存、二级缓存
  6. 字节跳动AI Lab 算法岗专属内推码!
  7. swift瀑布流实现_蘑菇街PC首页瀑布流实践
  8. 【springBoot】springBoot返回json的一个问题
  9. c#json对象转数组_C#中将json字符串转为List数组对象
  10. java opencv3轮廓_如何在OpenCV中获得单独的轮廓(并填充它们)?
  11. Java适配器模式(转接口)
  12. 高德地图缩放级别对应的比例尺
  13. java public aspect_spring aop的两种写法aspect和advisor
  14. OA实施成功的几个必备条件
  15. 微信APP支付demo
  16. idea右侧maven依赖飘红解决办法
  17. CSDN 空间:“迷你博客”很迷人(2)收藏
  18. 查看zookeeper的版本号
  19. android获取视频头一帧,music信息
  20. 快速阅读等三种读书方法

热门文章

  1. textarea显示字数
  2. Windows 10 自带appx
  3. SpriteAtlas 使用小结
  4. Power-law Distributions(幂律分布)
  5. html点击按钮没有反应
  6. ps怎么做计算机图标,【2人回答】PS怎么制作桌面图标?-3D溜溜网
  7. 如何在Unity测试时不自动启动SteamVR
  8. 电气论文实现:电力网络之 通过计算机得到电力网络节点导纳矩阵(matlab,python)
  9. 下载安卓源码都干了什么?
  10. 【iMessage苹果推群发】软件安装利用dropbox分享外链进行访问原始文件