当前位置:网站首页>【云原生】一文讲透Kubevela addon如何添加腾讯Crane

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

2022-08-09 22:11:00 神州数码云基地

一、项目背景

巨大的云浪费

据 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
    │
    └─repo
            crane-repo.yaml
            grafana-repo.yaml
            prometheus-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: prometheus
  namespace: 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.rules
            interval: 3600s
            rules:
              - 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.30s
            interval: 30s
            rules:
              - record: cpu_usage_active
                expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[90s])) * 100)
              - record: mem_usage_active
                expr: 100*(1-node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes)
          - name: scheduler.rules.1m
            interval: 1m
            rules:
              - record: cpu_usage_avg_5m
                expr: avg_over_time(cpu_usage_active[5m])
              - record: mem_usage_avg_5m
                expr: avg_over_time(mem_usage_active[5m])
          - name: scheduler.rules.5m
            interval: 5m
            rules:
              - record: cpu_usage_max_avg_1h
                expr: max_over_time(cpu_usage_avg_5m[1h])
              - record: cpu_usage_max_avg_1d
                expr: max_over_time(cpu_usage_avg_5m[1d])
              - record: mem_usage_max_avg_1h
                expr: max_over_time(mem_usage_avg_5m[1h])
              - record: mem_usage_max_avg_1d
                expr: 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 config
    extraScrapeConfigs: |-
      # this is used to scrape fadvisor
      - job_name: "fadvisor"
        honor_timestamps: true
        scheme: http
        metrics_path: /metrics
        static_configs:
          - targets: ['fadvisor.crane-system.svc.cluster.local:8081']
     
     
    server:
      service:
        persistentVolume:
          enabled: false
        annotations: { }
        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: 8080
        sessionAffinity: None
        type: ClusterIP
     
    nodeExporter:
      hostRootfs: false
     
    alertmanager:
      enabled: false
     
    pushgateway:
      enabled: false
     
    kubeStateMetrics:
      ## 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: true
      image:
        repository: ccr.ccs.tencentyun.com/tkeimages/kube-state-metrics
        pullPolicy: IfNotPresent
        tag: "2.2.4"

创建 grafana 配置的 ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/managed-by: Helm
  annotations:
    meta.helm.sh/release-name: grafana
    meta.helm.sh/release-namespace: crane-system
  name: grafana
  namespace: crane-system
data:
  override_values: |
    service:
      enabled: true
      type: ClusterIP
      port: 8082
      targetPort: 3000
      # targetPort: 4181 To be used with a proxy extraContainer
      annotations: {}
      labels: {}
      portName: service
     
    # Administrator credentials when not using an existing secret (see below)
    adminUser: admin
    adminPassword: 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: prometheus
  namespace: crane-system
spec:
  interval: 10m
  timeout: 5m
  url: https://prometheus-community.github.io/helm-charts

grafana-repo.yaml:

apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
  name: grafana
  namespace: crane-system
spec:
  interval: 10m
  timeout: 5m
  url: https://grafana.github.io/helm-charts

crane-repo.yaml:

apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
  name: crane
  namespace: crane-system
spec:
  interval: 10m
  timeout: 5m
  url: https://gocrane.github.io/helm-charts

# 4 使用 Helm 部署 Helm release、

部署 Prometheus:

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: prometheus
  namespace: crane-system
spec:
  timeoout: 10m
  interval: 5m
  chart:
    spec:
      chart: prometheus
      version: 15.8.5
      sourceRef:
        kind: HelmRepository
        name: prometheus
      interval: 5m
  targetNamespace: crane-system
  releaseName: prometheus
  valuesFrom: [{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: grafana
  namespace: crane-system
spec:
  timeoout: 10m
  interval: 5m
  chart:
    spec:
      chart: grafana
      version: 6.28.0
      sourceRef:
        kind: HelmRepository
        name: grafana
      interval: 5m
  targetNamespace: crane-system
  releaseName: grafana
  valuesFrom: [{kind: ConfigMap,name: grafana,valuesKey: override_values}]

部署 fadvisor :

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: fadvisor
  namespace: crane-system
spec:
  timeoout: 10m
  interval: 5m
  chart:
    spec:
      chart: fadvisor
      version: 0.2.0
      sourceRef:
        kind: HelmRepository
        name: crane
      interval: 5m
  targetNamespace: crane-system
  releaseName: fadvisor

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

部署 crane:

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: crane
  namespace: crane-system
spec:
  timeoout: 10m
  interval: 5m
  chart:
    spec:
      chart: crane
      version: 0.3.0
      sourceRef:
        kind: HelmRepository
        name: crane
      interval: 5m
  targetNamespace: crane-system
  releaseName: 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 等。

原网站

版权声明
本文为[神州数码云基地]所创,转载请带上原文链接,感谢
https://blog.csdn.net/CBGCampus/article/details/126173155