Crane 是一个基于 FinOps 的云资源分析与成本优化平台。在保证客户应用运行质量的前提下实现极致的降本。

一、 前言🍐

云原生技术可以帮助企业实现降本增效,提高业务的灵活性和可扩展性。云原生技术的降本增效主要是由以下因素推动的:

  1. 成本压力:随着业务规模和数据量的不断增长,传统基础设施(如物理服务器和虚拟机)的成本和管理复杂度不断上升,对企业的成本压力越来越大。
  2. 业务需求:企业面对的业务需求越来越多样化和复杂化,需要快速、灵活地部署和管理应用程序,以满足市场需求,传统的基础设施无法满足这些需求。
  3. 技术发展:随着云计算、大数据、人工智能等新技术的发展,企业需要更加智能、高效的IT基础设施来支持业务创新和发展。

二、 Crane开源项目简介🍎

​ Crane是由腾讯云主导开源的国内第一个基于云原生技术的成本优化项目,遵循FinOps标准,已经获得FinOps基金会授予的全球首个认证降本增效开源方案。它为使用Kubernetes集群的企业提供了一种简单、可靠且强大的自动化部署工具。Crane的设计初衷是为了帮助企业更好地管理和扩展其 Kubernetes 集群,从而实现更高效的云原生应用管理。它易于使用、高度可定制和可扩展。它提供了一组简单易用的命令行工具,使得开发者和管理员都能轻松地将应用程序部署到 Kubernetes 集群中。Crane 还支持多种云平台,并且可以根据具体的业务需求进行定制。Crane并已经被腾讯、网易、思必驰、酷家乐、明源云、数数科技等公司部署在生产系统,其主要贡献者来自腾讯、小红书、谷歌、eBay、微软、特斯拉等知名公司。

2.1. Crane整体框架🍒

image-20230510170109581

Craned 是 Crane 的最核心组件,它管理了 CRDs 的生命周期以及API。Craned 通过 Deployment 方式部署且由两个容器组成:

  • Craned: 运行了 Operators 用来管理 CRDs,向 Dashboard 提供了 WebApi,Predictors 提供了 TimeSeries API
  • Dashboard: 基于 TDesign’s Starter 脚手架研发的前端项目,提供了易于上手的产品功能

Fadvisor

Fadvisor 提供一组 Exporter 计算集群云资源的计费和账单数据并存储到你的监控系统,比如 Prometheus。Fadvisor 通过 Cloud Provider 支持了多云计费的 API。


Metric Adapter

Metric Adapter 实现了一个 Custom Metric Apiserver. Metric Adapter 读取 CRDs 信息并提供基于 Custom/External Metric API 的 HPA Metric 的数据。


Crane Agent

Crane Agent 通过 DaemonSet 部署在集群的节点上。

2.2. Crane主要功能🍅

image-20230510170024247

🟩成本可视化和优化评估

  • 提供一组 Exporter 计算集群云资源的计费和账单数据并存储到你的监控系统,比如 Prometheus。
  • 多维度的成本洞察,优化评估。通过 Cloud Provider 支持多云计费。

🟥推荐框架

提供了一个可扩展的推荐框架以支持多种云资源的分析,内置了多种推荐器:资源推荐,副本推荐,HPA 推荐,闲置资源推荐。


🟪基于预测的水平弹性器

EffectiveHorizontalPodAutoscaler 支持了预测驱动的弹性。它基于社区 HPA 做底层的弹性控制,支持更丰富的弹性触发策略(预测,观测,周期),让弹性更加高效,并保障了服务的质量。


🟧负载感知的调度器

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


🟨拓扑感知的调度器

Crane Scheduler与Crane Agent配合工作,支持更为精细化的资源拓扑感知调度和多种绑核策略,可解决复杂场景下“吵闹的邻居问题",使得资源得到更合理高效的利用。


🟦基于 QOS 的混部

QOS相关能力保证了运行在 Kubernetes 上的 Pod 的稳定性。具有多维指标条件下的干扰检测和主动回避能力,支持精确操作和自定义指标接入;具有预测算法增强的弹性资源超卖能力,复用和限制集群内的空闲资源;具备增强的旁路cpuset管理能力,在绑核的同时提升资源利用效率。

三、Crane实验前期准备🍊

采用VMware Workstation虚拟化软件,基于Rocky Linux开源企业级系统安装部署单机版的集群系统即可完成Crane开源项目。

本实验环境配置说明⌛

系统版本内存大小磁盘大小网络模式IP地址
Rocky Linux release 8.7≥8GB(推荐)30GBNAT模式192.168.200.60

本实验软件版本说明👑

必要组件组件版本
dockerv23.0.5
kubectlv1.27.1
helmv3.11.3
kindv0.18.0

3.1. 系统初始化📖

1、修改主机名
hostnamectl set-hostname Crane

2、关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
systemctl status firewalld

3、关闭selinux
# 临时允许
setenforce 0
getenforce 

# 永久允许
sed  -i "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config 
cat /etc/selinux/config

4、关闭swap分区
# 查看swapoff的版本
swapoff --version

# 临时关闭❎
swapoff -a

# 永久关闭❎
sed  -ri 's/.*swap.*/#&/' /etc/fstab		# 重启生效

# 使用swapon检查
swapon -v									#输出为空,表示swap已关闭	

5、配置网卡信息
cat /etc/sysconfig/network-scripts/ifcfg-ens32
systemctl restart NetworkManager
nmcli connection up ens160

6、配置阿里云镜像
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
    -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
    -i.bak \
    /etc/yum.repos.d/Rocky-*.repo

dnf makecache

7、生成本地缓存
yum makecache fast

8、更新YUM源软件包
yum update -y	

9、重启系统
reboot

3.2. Docker安装📑

1、使用yum安装gcc相关环境
yum install -y gcc gcc-c++

2、安装需要的依赖包
yum install -y yum-utils

3、设置阿里云docker镜像
yum-config-manager \
    --add-repo \
     https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4、安装docker、docker-ce、ee企业版
yum install -y docker-ce docker-ce-cli containerd.io

5、启动Docker
systemctl start docker && systemctl enable docker && systemctl status docker

查看所安装的docker版本信息,此时docker服务没有启动。

[root@Crane ~]# docker version
Client: Docker Engine - Community
 Version:           23.0.6
 API version:       1.42
 Go version:        go1.19.9
 Git commit:        ef23cbc
 Built:             Fri May  5 21:19:08 2023
 OS/Arch:           linux/amd64
 Context:           default
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

启动docker服务并设置docker服务开机自启动,查看Docker服务状态。

systemctl start docker && systemctl enable docker && systemctl status docker

查看docker版本信息

[root@Crane ~]# docker version
Client: Docker Engine - Community
 Version:           23.0.6
 API version:       1.42
 Go version:        go1.19.9
 Git commit:        ef23cbc
 Built:             Fri May  5 21:19:08 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          23.0.6
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.9
  Git commit:       9dbdbd4
  Built:            Fri May  5 21:18:15 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

3.3. kubectl安装📚

🔗参考链接:在 Linux 系统中安装并设置 kubectl | Kubernetes

用 curl 在 Linux 系统中安装 kubectl

[root@Crane ~]# curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   138  100   138    0     0    276      0 --:--:-- --:--:-- --:--:--   276
100 46.9M  100 46.9M    0     0  5556k      0  0:00:08  0:00:08 --:--:-- 6553k


[root@crane ~]# ll
total 48096
-rw-------. 1 root root     1322 Mar 29  2022 anaconda-ks.cfg
-rw-r--r--  1 root root 49246208 May  7 11:21 kubectl

# 验证该可执行文件:
1️⃣下载 kubectl 校验和文件
[root@Crane ~]# curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   138  100   138    0     0    281      0 --:--:-- --:--:-- --:--:--   280
100    64  100    64    0     0     65      0 --:--:-- --:--:-- --:--:--    65

2️⃣基于校验和文件,验证 kubectl 的可执行文件
[root@Crane ~]# echo "$(cat kubectl.sha256)  kubectl" | sha256sum --check
kubectl: OK

安装 kubectl

# 安装kubectl
[root@crane ~]# sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# 查看kubectl的安装版本
[root@Crane ~]# kubectl version --client
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
Client Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.1", GitCommit:"4c9411232e10168d7b050c49a1b59f6df9d7ea4b", GitTreeState:"clean", BuildDate:"2023-04-14T13:21:19Z", GoVersion:"go1.20.3", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v5.0.1

# 查看kubectl版本的详细信息
[root@Crane ~]# kubectl version --client --output=yaml
clientVersion:
  buildDate: "2023-04-14T13:21:19Z"
  compiler: gc
  gitCommit: 4c9411232e10168d7b050c49a1b59f6df9d7ea4b
  gitTreeState: clean
  gitVersion: v1.27.1
  goVersion: go1.20.3
  major: "1"
  minor: "27"
  platform: linux/amd64
kustomizeVersion: v5.0.1

3.4. helm安装📕

⌛参考链接:Helm | 安装Helm

# 获取helm脚本,可能需要开启代理。
[root@Crane ~]# curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3

# 查看目录
[root@Crane ~]# ll
total 48112
-rw-------. 1 root root     1322 Mar 29  2022 anaconda-ks.cfg
-rw-r--r--. 1 root root    11345 May 10 11:53 get_helm.sh
-rw-r--r--. 1 root root 49246208 May 10 11:48 kubectl
-rw-r--r--. 1 root root       64 May 10 11:49 kubectl.sha256

# 赋予该脚本可执行的权限
[root@crane ~]# chmod 700 get_helm.sh

# 执行该脚本安装helm
[root@Crane ~]# ./get_helm.sh
Downloading https://get.helm.sh/helm-v3.11.3-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm

# 查看helm版本信息
[root@Crane ~]# helm version
version.BuildInfo{Version:"v3.11.3", GitCommit:"323249351482b3bbfc9f5004f65d400aa70f9ae7", GitTreeState:"clean", GoVersion:"go1.20.3"}

3.5. kind安装📙

🔗参考链接:kind – Quick Start

# 获取kind脚本
[root@Crane ~]# curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.18.0/kind-linux-amd64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    98  100    98    0     0     81      0  0:00:01  0:00:01 --:--:--    81
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0
100 6808k  100 6808k    0     0  1064k      0  0:00:06  0:00:06 --:--:-- 2552k

# 赋予该脚本可执行权限
[root@Crane ~]# chmod +x ./kind

# 转移目录
[root@Crane ~]# sudo mv ./kind /usr/local/bin/kind

# 查看kind版本信息
[root@Crane ~]# kind version
kind v0.18.0 go1.20.2 linux/amd64

四、单机版Crane部署流程🍑

4.1. Crane系统一键化安装⚒️

🎆 Plan A:执行此命令直接一键化安装部署

# 执行此命令,可以一键部署,但是需要访问外网。
curl -sf https://raw.githubusercontent.com/gocrane/crane/main/hack/local-env-setup.sh | sh -

安装过程演示:

[root@Crane ~]# curl -sf https://raw.githubusercontent.com/gocrane/crane/main/hack/local-env-setup.sh | sh -
Step1: Create local cluster:  /root/.kube/config_crane
Deleting cluster "crane" ...
Creating cluster "crane" ...
 ✓ Ensuring node image (kindest/node:v1.21.1) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-crane"
You can now use your cluster with:

kubectl cluster-info --context kind-crane --kubeconfig /root/.kube/config_crane

Thanks for using kind! 😊
Step1: Create local cluster finished.
Step2: Installing Prometheus
"prometheus-community" has been added to your repositories
NAME: prometheus
LAST DEPLOYED: Wed May 10 12:12:54 2023
NAMESPACE: crane-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The Prometheus server can be accessed via port 8080 on the following DNS name from within your cluster:
prometheus-server.crane-system.svc.cluster.local


Get the Prometheus server URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace crane-system -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace crane-system port-forward $POD_NAME 9090
#################################################################################
######   WARNING: Persistence is disabled!!! You will lose your data when   #####
######            the Server pod is terminated.                             #####
#################################################################################


#################################################################################
######   WARNING: Pod Security Policy has been disabled by default since    #####
######            it deprecated after k8s 1.25+. use                        #####
######            (index .Values "prometheus-node-exporter" "rbac"          #####
###### .          "pspEnabled") with (index .Values                         #####
######            "prometheus-node-exporter" "rbac" "pspAnnotations")       #####
######            in case you still need it.                                #####
#################################################################################

For more information on running Prometheus, visit:
https://prometheus.io/
Step2: Installing Prometheus finished.
Step3: Installing Grafana
NAME: grafana
LAST DEPLOYED: Wed May 10 12:13:00 2023
NAMESPACE: crane-system
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:

   kubectl get secret --namespace crane-system grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

2. The Grafana server can be accessed via port 8082 on the following DNS name from within your cluster:

   grafana.crane-system.svc.cluster.local

   Get the Grafana URL to visit by running these commands in the same shell:

     export POD_NAME=$(kubectl get pods --namespace crane-system -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana" -o jsonpath="{.items[0].metadata.name}")
     kubectl --namespace crane-system port-forward $POD_NAME 3000

3. Login with the password from step 1 and the username: admin
#################################################################################
######   WARNING: Persistence is disabled!!! You will lose your data when   #####
######            the Grafana pod is terminated.                            #####
#################################################################################
Step3: Installing Grafana finished.
Step4: Installing Crane
"crane" has been added to your repositories
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "crane" chart repository
...Successfully got an update from the "grafana" chart repository
...Successfully got an update from the "prometheus-community" chart repository
Update Complete. ⎈Happy Helming!⎈
NAME: crane
LAST DEPLOYED: Wed May 10 12:13:06 2023
NAMESPACE: crane-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NAME: fadvisor
LAST DEPLOYED: Wed May 10 12:13:10 2023
NAMESPACE: crane-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
Step4: Installing Crane finished.
NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
craned                          0/1     1            0           3s
fadvisor                        0/1     1            0           0s
grafana                         0/1     1            0           10s
metric-adapter                  0/1     1            0           3s
prometheus-kube-state-metrics   0/1     1            0           16s
prometheus-server               0/1     1            0           16s
Please wait for all pods ready
After all pods ready, Get the Crane Dashboard URL to visit by running these commands in the same shell:
    export KUBECONFIG=/root/.kube/config_crane
    kubectl -n crane-system port-forward service/craned 9090:9090

⏭️Plan B:如果访问网络发生错误,可以使用本地安装包执行安装操作,具体执行命令如下:

# 上传Crane安装包到系统中
[root@Crane training]# pwd
/root/training
[root@Crane training]# ll
total 4
drwxr-xr-x. 7 root root 4096 May 10 13:50 installation

# 进入training目录,查看文件内容
[root@Crane installation]# ll
total 228
-rw-r--r--. 1 root root   4206 May 10 13:50 components.yaml
drwxr-xr-x. 5 root root    120 May 10 13:50 crane
-rw-r--r--. 1 root root   1232 May 10 13:50 effective-hpa.yaml
drwxr-xr-x. 3 root root     77 May 10 13:50 fadvisor
drwxr-xr-x. 5 root root    124 May 10 13:50 grafana
-rw-r--r--. 1 root root 199848 May 10 13:50 grafana_override_values.yaml
drwxr-xr-x. 3 root root     96 May 10 13:50 kube-state-metrics
-rw-r--r--. 1 root root   3777 May 10 13:50 local-env-setup.sh
-rw-r--r--. 1 root root    522 May 10 13:50 nginx-deployment.yaml
-rw-r--r--. 1 root root    615 May 10 13:50 php-apache.yaml
drwxr-xr-x. 3 root root    140 May 10 13:50 prometheus
-rw-r--r--. 1 root root   4915 May 10 13:50 prometheus_override_values.yaml

# 💥必须在 installation 的上级目录执行下面这一操作(即不能修改这条命令🚫),否则安装失败。💢
bash installation/local-env-setup.sh

等待片刻时间, 查看所有的Pod 是否都正常启动运行,如下所示。再进行下一步相关操作。

[root@Crane ~]# kubectl get pods -n crane-system
NAME                                             READY   STATUS    RESTARTS   AGE
craned-75d5fcff49-2ppnn                          2/2     Running   0          121m
fadvisor-6c6867dcb9-tscxm                        1/1     Running   0          121m
grafana-8fb6974cc-kzgzf                          1/1     Running   0          121m
metric-adapter-789b5b8bc5-hnt9g                  1/1     Running   0          121m
prometheus-kube-state-metrics-69c44479cb-jlzmh   1/1     Running   0          121m
prometheus-prometheus-node-exporter-4xmrg        1/1     Running   0          121m
prometheus-server-6cb8bc86c4-wxdsz               2/2     Running   0          121m

4.2. 访问Crane Dashboard💨

重新打开一个新的终端,执行如下命令:

# 🌈每打开一个终端进行操作时,都需要执行配置环境变量这一条命令(不然会出现8080端口被拒绝的提示),如下图所示。
export KUBECONFIG=/root/.kube/config_crane

image-20230510142022054

# 执行此命令,访问Crane Dashboard。如下图所示。
kubectl -n crane-system port-forward service/craned 9090:9090

image-20230510142253843


💢重点💢:本实验使用虚拟机进行安装部署,直接执行127.0.0.1:9090或者192.168.200.60:9090,均无法访问到DashBoard。此时,系统需要将本地的端口做下反向代理,将9090端口转发给80,在浏览器中直接输入主机IP地址192.168.200.60即可访问。具体执行操作如下所示。

# 安装nginx服务
yum install -y nginx

# 修改nginx.conf配置文件,修改内容如下:
server_name  192.168.200.60;

location / {
proxy_pass         http://127.0.0.1:9090;
proxy_http_version 1.1;
proxy_set_header   Upgrade $http_upgrade;
proxy_set_header   Connection keep-alive;
proxy_set_header   Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header   X-Forwarded-Proto $scheme;
}
# 按:wq报错退出。

# 检查nginx配置文件是否正确,执行结果如下所示。
[root@Crane ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# 启动nginx服务并设置开机自启动
systemctl start && systemctl enable nginx && systemctl status nginx

如果还访问不了Dashboard,请自行检查pods是否都已经正常启动系统环境设置是否做了限制(如防火墙是否关闭或开启对应端口)。

image-20230507143652926

4.3. 添加集群🛠️

添加集群。
image-20230507144118069
image-20230510144641966
添加完成。
image-20230510144721945
image-20230510144816954


五、集群功能演示🛠️

5.1. 使用智能弹性EffectiveHPA🥒

Crane提供了一种名为EffectiveHorizontalPodAutoscaler(EHPA)的弹性伸缩产品,它基于社区HPA技术实现了弹性控制功能,并支持更多的弹性触发策略,包括预测、观测和周期等,从而实现更高效的弹性控制,并确保了服务质量。简而言之,EHPA是一种高效的弹性伸缩方案,可以为服务提供更好的保障。

5.1.1 安装Metrics Server
# 执行命令安装Metrics Server。需要在installation上一级目录下执行此命令。💥
[root@Crane training]# kubectl apply -f installation/components.yaml
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created

查看该pod是否正常启动。

[root@Crane ~]# kubectl get pod -n kube-system | grep metrics-server
metrics-server-79c88ff4f-mz96g                1/1     Running   0          16m
5.1.2 创建测试应用

使用以下命令启动一个 Deployment 用 hpa-example 镜像运行一个容器, 然后将其暴露为一个 服务(Service)

[root@Crane training]# kubectl apply -f installation/php-apache.yaml
deployment.apps/php-apache created
service/php-apache created

[root@Crane training]# kubectl apply -f installation/nginx-deployment.yaml
deployment.apps/nginx-deployment created

[root@Crane training]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-758fd5cc9f-27bpz   1/1     Running   0          108s
nginx-deployment-758fd5cc9f-mxxx9   1/1     Running   0          108s
nginx-deployment-758fd5cc9f-np46c   1/1     Running   0          108s
nginx-deployment-758fd5cc9f-p8s9q   1/1     Running   0          108s
nginx-deployment-758fd5cc9f-tc2mj   1/1     Running   0          108s
php-apache-7d59cc57d4-8tnph         1/1     Running   0          2m5s
5.1.3 创建 EffectiveHPA
[root@Crane training]# kubectl apply -f installation/effective-hpa.yaml
effectivehorizontalpodautoscaler.autoscaling.crane.io/php-apache created
# 查看 EffectiveHPA 的状态信息
[root@Crane training]# kubectl get ehpa
NAME         STRATEGY   MINPODS   MAXPODS   SPECIFICPODS   REPLICAS   AGE
php-apache   Auto       1         10                       0          10s
5.1.4 增加负载测试
# 打开新的终端窗口,配置环境变量 
export KUBECONFIG=${HOME}/.kube/config_crane

kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"

image-20230510151748903
可以按CTRL+C终止上述请求。随着请求增多,CPU利用率会不断提升,可以看到 EffectiveHPA 会自动扩容实例。如下所示。

增加负载后,相关信息参数如下所示。

[root@crane training]# kubectl get hpa ehpa-php-apache --watch
NAME              REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
ehpa-php-apache   Deployment/php-apache   29%/50%   1         10        1          107s
ehpa-php-apache   Deployment/php-apache   250%/50%   1         10        1          2m1s
ehpa-php-apache   Deployment/php-apache   240%/50%   1         10        4          2m16s
ehpa-php-apache   Deployment/php-apache   109%/50%   1         10        5          2m31s
ehpa-php-apache   Deployment/php-apache   70%/50%    1         10        5          2m46s
image-20230510152203493
[root@Crane training]# kubectl get ehpa
NAME         STRATEGY   MINPODS   MAXPODS   SPECIFICPODS   REPLICAS   AGE
php-apache   Auto       1         10                       6          7m1s

[root@Crane training]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-758fd5cc9f-27bpz   1/1     Running   0          5m22s
nginx-deployment-758fd5cc9f-mxxx9   1/1     Running   0          5m22s
nginx-deployment-758fd5cc9f-np46c   1/1     Running   0          5m22s
nginx-deployment-758fd5cc9f-p8s9q   1/1     Running   0          5m22s
nginx-deployment-758fd5cc9f-tc2mj   1/1     Running   0          5m22s
php-apache-7d59cc57d4-4zf6j         1/1     Running   0          57s
php-apache-7d59cc57d4-6b5h8         1/1     Running   0          72s
php-apache-7d59cc57d4-8tnph         1/1     Running   0          5m39s
php-apache-7d59cc57d4-kjkff         1/1     Running   0          27s
php-apache-7d59cc57d4-lwnpp         1/1     Running   0          72s
php-apache-7d59cc57d4-zhdfk         1/1     Running   0          57s

通过下面截图对比可知,创建的应用在增加负载压力测试过程中,发生了自动扩缩容。

image-20230510154642213

5.2. 成本展示 🍆

集群总览
image-20230510155038174
image-20230510155115207
通过登录Grafana数据可视化展示平台进行查验。本实验的输入的地址是:http://192.168.200.60/grafana

默认账号/密码:admin/admin

export KUBECONFIG=${HOME}/.kube/config_crane

kubectl -n crane-system port-forward service/grafana 8082:8082

image-20230510155416045
image-20230510155501291

5.3. 应用资源优化🥕

在 dashboard 中看到相关的成本数据,是因为在添加集群的时候安装了推荐的规则。


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


Crane 的推荐模块会定期检测发现集群资源配置的问题,并给出优化建议。


智能推荐提供了多种 Recommender 来实现面向不同资源的优化推荐。

成本分析>推荐规则页面可以看到安装的两个推荐规则。

image-20230510160256742
这些推荐规则实际上在将 K8s 集群接入Dashboard时安装上的 RecommendationRule CRD 对象:

[root@Crane ~]# kubectl get RecommendationRule
NAME             RUNINTERVAL   AGE
idlenodes-rule   24h           5h8m
workloads-rule   24h           5h8m

RecommendationRule 是一个集群维度的对象,该推荐规则会对所有命名空间中的 Deployments 和 StatefulSets 做资源推荐和副本数推荐。

需要注意的是资源类型和 recommenders 需要可以匹配,比如 Resource 推荐默认只支持 Deployments 和 StatefulSets。

👀 查看闲置节点推荐规则的资源对象👀

[root@Crane ~]# kubectl get recommendationrule idlenodes-rule -oyaml
apiVersion: analysis.crane.io/v1alpha1
kind: RecommendationRule
metadata:
  creationTimestamp: "2023-05-10T04:27:24Z"
  generation: 2
  labels:
    analysis.crane.io/recommendation-rule-preinstall: "true"
  name: idlenodes-rule
  resourceVersion: "3494"
  uid: 034152a2-e4ae-4d3b-8223-624f2315e067
spec:
  namespaceSelector:
    any: true
  recommenders:
  - name: IdleNode
  resourceSelectors:
  - apiVersion: v1
    kind: Node
  runInterval: 24h
status:
  lastUpdateTime: "2023-05-10T04:27:24Z"
  recommendations:
  - lastStartTime: "2023-05-10T04:27:24Z"
    message: 'Failed to run recommendation flow in recommender IdleNode: Node crane-control-plane
      is not a idle node '
    recommenderRef:
      name: IdleNode
    targetRef:
      apiVersion: v1
      kind: Node
      name: crane-control-plane
  runNumber: 1

👀 查看集群生成的多个优化建议 Recommendation 对象👀

[root@Crane ~]# kubectl get recommendations -A
NAMESPACE            NAME                            TYPE       TARGETKIND   TARGETNAMESPACE      TARGETNAME                      STRATEGY   PERIODSECONDS   ADOPTIONTYPE          AGE
crane-system         workloads-rule-resource-254v6   Resource   Deployment   crane-system         metric-adapter                  Once                       StatusAndAnnotation   5h12m
crane-system         workloads-rule-resource-7c4jg   Resource   Deployment   crane-system         prometheus-kube-state-metrics   Once                       StatusAndAnnotation   5h12m
crane-system         workloads-rule-resource-hwr7p   Resource   Deployment   crane-system         prometheus-server               Once                       StatusAndAnnotation   5h12m
crane-system         workloads-rule-resource-m5ws6   Resource   Deployment   crane-system         grafana                         Once                       StatusAndAnnotation   5h12m

👀查看任意优化建议对象👀

kubectl get recommend workloads-rule-resource-254v6 -n crane-system -oyaml
apiVersion: analysis.crane.io/v1alpha1
kind: Recommendation
metadata:
  annotations:
    analysis.crane.io/run-number: "1"
  creationTimestamp: "2023-05-10T04:27:24Z"
  generateName: workloads-rule-resource-
  generation: 2
  labels:
    analysis.crane.io/recommendation-rule-name: workloads-rule
    analysis.crane.io/recommendation-rule-recommender: Resource
    analysis.crane.io/recommendation-rule-uid: ae95350e-5bfb-4fa7-955c-a69907d17b70
    analysis.crane.io/recommendation-target-kind: Deployment
    analysis.crane.io/recommendation-target-name: metric-adapter
    analysis.crane.io/recommendation-target-version: v1
    app: metric-adapter
    app.kubernetes.io/instance: crane
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: crane
    app.kubernetes.io/version: v0.10.0
    helm.sh/chart: crane-0.10.0
  name: workloads-rule-resource-254v6
  namespace: crane-system
  ownerReferences:
  - apiVersion: analysis.crane.io/v1alpha1
    blockOwnerDeletion: false
    controller: false
    kind: RecommendationRule
    name: workloads-rule
    uid: ae95350e-5bfb-4fa7-955c-a69907d17b70
  resourceVersion: "3515"
  uid: b00b3e5d-400d-455d-a338-7526c5d7d6c1
spec:
  adoptionType: StatusAndAnnotation
  completionStrategy:
    completionStrategyType: Once
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: metric-adapter
    namespace: crane-system
  type: Resource
status:
  action: Patch
  conditions:
  - lastTransitionTime: "2023-05-10T04:27:24Z"
    message: Recommendation is ready
    reason: RecommendationReady
    status: "True"
    type: Ready
  currentInfo: '{"spec":{"template":{"spec":{"containers":[{"name":"metric-adapter","resources":{"requests":{"cpu":"0","memory":"0"}}}]}}}}'
  lastUpdateTime: "2023-05-10T04:27:24Z"
  recommendedInfo: '{"spec":{"template":{"spec":{"containers":[{"name":"metric-adapter","resources":{"requests":{"cpu":"114m","memory":"120586239"}}}]}}}}'
  recommendedValue: |
    resourceRequest:
      containers:
      - containerName: metric-adapter
        target:
          cpu: 114m
          memory: "120586239"
  targetRef: {}
[root@Crane ~]#

通过Web控制面板也可以查看上述信息。
image-20230510174909269

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


应用在监控系统(比如 Prometheus)中的历史数据越久,推荐结果就越准确,建议生产上超过两周时间。


对新建应用的预测往往不准。

六、清理实验环境数据🍇

[root@Crane ~]# kind delete cluster --name=crane
Deleting cluster "crane" ...
Deleted nodes: ["crane-control-plane"]

七、常见问题及注意事项🍓

💥报错一:执行安装部署命令时报错,发生中断,原因是执行命令位置不对。应该在installation上一级目录中执行

[root@crane installation]# bash local-env-setup.sh 
Step1: Create local cluster:  /root/.kube/config_crane
Deleting cluster "crane" ...
Deleted nodes: ["crane-control-plane"]
Creating cluster "crane" ...
 ✓ Ensuring node image (kindest/node:v1.21.1) 🖼
 ✓ Preparing nodes 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-crane"
You can now use your cluster with:

kubectl cluster-info --context kind-crane --kubeconfig /root/.kube/config_crane

Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
Step1: Create local cluster finished.
Step2: Installing Prometheus 
Error: INSTALLATION FAILED: repo installation not found

🚫报错二:针对此报错,需要先执行export KUBECONFIG=${HOME}/.kube/config_crane命令,赋予环境变量再执行。

image-20230510161038257
⁉️报错三:查看pod详细信息,报错,需要指定namespace命名空间

[root@crane ~]# kubectl describe pods/fadvisor-6c6867dcb9-5zfxg
Error from server (NotFound): pods "fadvisor-6c6867dcb9-5zfxg" not found
[root@crane ~]# kubectl describe pods/fadvisor-6c6867dcb9-5zfxg --namespace crane-system

报错四:pod状态发生异常,一直停留在ImagePullBackOff状态,因为需要访问外网,或者重启docker服务再次尝试。也可以查看该容器详细信息。

[root@crane ~]# kubectl get pods -n crane-system
NAME                                 READY   STATUS             RESTARTS   AGE
craned-75d5fcff49-d4xmj              2/2     Running            9          21h
fadvisor-6c6867dcb9-5zfxg            0/1     ImagePullBackOff   1          21h
grafana-84b5cdc55b-svb2f             1/1     Running            2          21h
kube-state-metrics-b5fdc98b5-jbsv8   1/1     Running            3          21h
metric-adapter-789b5b8bc5-9hznv      1/1     Running            3          21h
prometheus-server-67cb89fc9b-6g9l9   2/2     Running            4          21h

[root@crane ~]# kubectl get pods -n crane-system
NAME                                 READY   STATUS         RESTARTS   AGE
craned-75d5fcff49-d4xmj              2/2     Running        9          21h
fadvisor-6c6867dcb9-5zfxg            0/1     ErrImagePull   1          21h
grafana-84b5cdc55b-svb2f             0/1     Unknown        2          21h
kube-state-metrics-b5fdc98b5-jbsv8   0/1     Running        4          21h
metric-adapter-789b5b8bc5-9hznv      1/1     Running        3          21h
prometheus-server-67cb89fc9b-6g9l9   2/2     Running        4          21h

八、总结 🍋

​ ​ ​ ​ ​ ​ ​ ​ 当前计算机工程方向已经进入云原生时代,容器和容器编排(K8s)成为计算机工程方向热门技术。而Crane开源项目就是针对云原生成本进行的多维度多角度的优化分析,给客户带来了降本增效、可持续发展的价值。

​ ​ ​ ​ ​ ​ ​ ​ 在参加完两次Finops Crane开源项的目直播活动,感觉收获颇多。直播大咖带领我们学习并了解了开源项目的理论知识,为我们进行了详细的讲解与技术框架结构的剖析与关联,通过前期理论知识的学习与掌握,之后,指导我们亲自动手搭建场景化解决方案。通过实际动手操作,对Crane整个项目又有了进一步的认识与理解,最大限度地锻炼开发人员地技术能力。

​ ​ ​ ​ ​ ​ ​ ​ 从移动互联网时代步入云时代,上云用云似乎变得不可或缺,无论是企业、政府、还是最终用户都在积极拥抱云服务。一方面在最大化的降低运维开销成本,实现数字化转型升级的同时,另一方面也希望对云中资源的投入与使用达到最佳合理化。与此同时,云中资源的监控与管理将变得尤为重要,Crane开源项目就此诞生出来。

针对Finops Crane开源项目的建议方向:(个人观点)

  • 可以增加AlterManager监控告警功能模块,配合Prometheus+Grafana进行组合使用。当云中某项资源或指标触发到设定的阈值,立刻发送消息通知至客户终端,如发生异常信息,能够做到及时响应,及时处理。

九、参考链接🍉

🟡https://gocrane.io/

🔴腾讯云 Finops Crane 开发者集训营

🔵https://github.com/gocrane/crane

关于腾讯云 Finops Crane 集训营:
Finops Crane集训营主要面向广大开发者,旨在提升开发者在容器部署、K8s层面的动手实践能力,同时吸纳Crane开源项目贡献者,鼓励开发者提交issue、bug反馈等,并搭载线上直播、动手实验组队、有奖征文等系列技术活动。既能让开发者通过活动对 Finops Crane 开源项目有深入了解,同时也能帮助广大开发者在云原生技能上有实质性收获。
为奖励开发者,我们特别设立了积分获取任务和对应的积分兑换礼品。

活动介绍送门:https://marketing.csdn.net/p/038ae30af2357473fc5431b63e4e1a78

开源项目: https://github.com/gocrane/crane

“THE END”动画

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐