Crane 是一个基于 FinOps 的云资源分析与成本优化平台。在保证客户应用运行质量的前提下实现极致的降本。
一、 前言🍐
云原生技术可以帮助企业实现降本增效,提高业务的灵活性和可扩展性。云原生技术的降本增效主要是由以下因素推动的:
- 成本压力:随着业务规模和数据量的不断增长,传统基础设施(如物理服务器和虚拟机)的成本和管理复杂度不断上升,对企业的成本压力越来越大。
- 业务需求:企业面对的业务需求越来越多样化和复杂化,需要快速、灵活地部署和管理应用程序,以满足市场需求,传统的基础设施无法满足这些需求。
- 技术发展:随着云计算、大数据、人工智能等新技术的发展,企业需要更加智能、高效的IT基础设施来支持业务创新和发展。
二、 Crane开源项目简介🍎
Crane是由腾讯云主导开源的国内第一个基于云原生技术的成本优化项目,遵循FinOps标准,已经获得FinOps基金会授予的全球首个认证降本增效开源方案。它为使用Kubernetes集群的企业提供了一种简单、可靠且强大的自动化部署工具。Crane的设计初衷是为了帮助企业更好地管理和扩展其 Kubernetes 集群,从而实现更高效的云原生应用管理。它易于使用、高度可定制和可扩展。它提供了一组简单易用的命令行工具,使得开发者和管理员都能轻松地将应用程序部署到 Kubernetes 集群中。Crane 还支持多种云平台,并且可以根据具体的业务需求进行定制。Crane并已经被腾讯、网易、思必驰、酷家乐、明源云、数数科技等公司部署在生产系统,其主要贡献者来自腾讯、小红书、谷歌、eBay、微软、特斯拉等知名公司。
2.1. Crane整体框架🍒
Craned 是 Crane 的最核心组件,它管理了 CRDs 的生命周期以及API。Craned 通过 Deployment
方式部署且由两个容器组成:
Craned
: 运行了 Operators 用来管理 CRDs,向 Dashboard 提供了 WebApi,Predictors 提供了 TimeSeries APIDashboard
: 基于 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主要功能🍅
🟩成本可视化和优化评估
- 提供一组 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(推荐) | 30GB | NAT模式 | 192.168.200.60 |
本实验软件版本说明👑
必要组件 | 组件版本 |
---|---|
docker | v23.0.5 |
kubectl | v1.27.1 |
helm | v3.11.3 |
kind | v0.18.0 |
3.1. 系统初始化📖
1、修改主机名 hostnamectl set-hostname Crane
2、关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
systemctl status firewalld3、关闭selinux
临时允许
setenforce 0
getenforce永久允许
sed -i "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config
cat /etc/selinux/config4、关闭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 ens1606、配置阿里云镜像
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-*.repodnf makecache
7、生成本地缓存
yum makecache fast8、更新YUM源软件包
yum update -y
9、重启系统
reboot
3.2. Docker安装📑
1、使用yum安装gcc相关环境
yum install -y gcc gcc-c++2、安装需要的依赖包
yum install -y yum-utils3、设置阿里云docker镜像
yum-config-manager
--add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo4、安装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.localGet 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:
Get your 'admin' user password by running:
kubectl get secret --namespace crane-system grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
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 3000Login 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
# 执行此命令,访问Crane Dashboard。如下图所示。
kubectl -n crane-system port-forward service/craned 9090:9090
💢重点💢:本实验使用虚拟机进行安装部署,直接执行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
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是否都已经正常启动;系统环境设置是否做了限制(如防火墙是否关闭或开启对应端口)。
4.3. 添加集群🛠️
添加集群。
添加完成。
五、集群功能演示🛠️
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"
可以按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
[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
通过下面截图对比可知,创建的应用在增加负载压力测试过程中,发生了自动扩缩容。
5.2. 成本展示 🍆
集群总览
通过登录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
5.3. 应用资源优化🥕
在 dashboard 中看到相关的成本数据,是因为在添加集群的时候安装了推荐的规则。
推荐框架会自动分析集群的各种资源的运行情况并给出优化建议。
Crane 的推荐模块会定期检测发现集群资源配置的问题,并给出优化建议。
智能推荐提供了多种 Recommender 来实现面向不同资源的优化推荐。
在
成本分析>推荐规则
页面可以看到安装的两个推荐规则。
这些推荐规则实际上在将 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控制面板也可以查看上述信息。
对于闲置节点推荐,由于节点的下线在不同平台上的步骤不同,用户可以根据自身需求进行节点的下线或者缩容。
应用在监控系统(比如 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
命令,赋予环境变量再执行。
⁉️报错三:查看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进行组合使用。当云中某项资源或指标触发到设定的阈值,立刻发送消息通知至客户终端,如发生异常信息,能够做到及时响应,及时处理。
九、参考链接🍉
🔴腾讯云 Finops Crane 开发者集训营