代替 HeapSter 的原生资源指标
- metrics-server
原生指标只能收集如 CPU 、内存等,而在此之上收集更多维度数据的方式成为自定义指标,如 Prometheus, Prometheus 通过 k8s-prometheus-adapter 转换成指标格式
新一代监控架构
- 核心指标流水线: 由 kubelet metrics-server 以及由 API server 提供的 api 组成,目前来讲主要包含 CPU 累计使用率,内存的实时使用率以及 Pod 的资源占用率及容器的磁盘占用率
- 监控流水线: 用于从系统收集各种指标数据并提供终端用户、存储、系统以及 HPA,所以他们包含核心指标以及许多非核心指标,非核心指标并不能被 k8s 所解析,如 Prometheus 需要使用 k8s-prometheus-adaoter 来转换指标格式
metrics
它是一个 API server 仅服务资源指标,本身并不是 k8s 组件,为了让 metrics 可以让用户无感知,需要使用 kube-aggregator
聚合器来让多个 APIserver 合并在一起对外提供服务
部署方式,如果是生产环境注意替换 emptyDir: {}
[root@master-0 ~]# for i in auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml ; do wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/metrics-server/$i ; done
[root@master-0 metrics]# kubectl api-versions
... ...
metrics.k8s.io/v1beta1 # 聚合的新的 api 群组
修改 resource-reader.yaml
... ...
rules:
- apiGroups:
- ""
resources:
- pods
- nodes
- nodes/stats # 增加这一项
- namespaces
... ...
此时 kubectl top
命令可用了
Prometheus
Prometheus 自身就是一个 no-sql 的时序数据库且是一个有状态应用,server 段即 Prometheus,采集数据节点的 agent 为 node_exporter,但 node_exporter 只能采集节点的系统级数据,若是需要采集业务级数据则需要再部署业务级的 node_exporter,在此之上调用 Prometheus 的工具为 PromQL 是一种 restful 风格的语言,但不被 API server 兼容,需要先通过 kube-state-metrics 将 kubernetes 的结构化信息转换为 metrics,之后要在 API server 上嵌套一层 k8s-prometheus-adapter 来完成通过 PromQL 查询出数据再翻译到 kube-state-metrics 最后聚合到 API 上
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdyIOkRq-1624628012081)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20201006190749.png)]
Prometheus 提供了通用的数据模型和便捷的数据采集、存储和查询接口,其核心组件 Prometheus 服务器定期从静态配置的监控目标或者基于服务发现 service discovery 自动配置的目标中拉取数据,新拉取到的数据大于配置内存缓存区时,数据将持久化到存储设备中,Alertmanager 来发送报警
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CNrhz3fP-1624628012082)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20201006193017.png)]
部署展示
-
拉取实验环境修改后的代码
[root@master-0 metrics]# git clone https://github.com/iKubernetes/k8s-prom.git
-
创建 Prometheus 使用的名称空间
[root@master-0 metrics]# cd k8s-prom/ [root@master-0 k8s-prom]# ls k8s-prometheus-adapter kube-state-metrics namespace.yaml node_exporter podinfo prometheus README.md [root@master-0 k8s-prom]# kubectl apply -f namespace.yaml namespace/prom created
-
部署 node_exporter 组件,用来收集节点上系统级数据
[root@master-0 k8s-prom]# cd node_exporter/ [root@master-0 node_exporter]# kubectl apply -f . daemonset.apps/prometheus-node-exporter created service/prometheus-node-exporter created
-
部署 Prometheus
[root@master-0 node_exporter]# cd ../prometheus/ [root@master-0 prometheus]# kubectl apply -f . configmap/prometheus-config created deployment.apps/prometheus-server created clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created service/prometheus created
-
部署 state-metrics,负责将监控数据翻译成 k8s 的数据结构
[root@master-0 prometheus]# cd ../kube-state-metrics/ [root@master-0 kube-state-metrics]# kubectl apply -f . deployment.apps/kube-state-metrics created serviceaccount/kube-state-metrics created clusterrole.rbac.authorization.k8s.io/kube-state-metrics created clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics created service/kube-state-metrics created
-
制作 k8s-prometheus-adapter 的证书,k8s-prometheus-adapter 需要提供证书以运行为 https,这个证书必须是此 k8s 服务器认可的 CA 签署,所以需要自制,只要把这个证书制作成 secret 并以特定名称和 ns 运行即可自动加载
[root@master-0 k8s-prometheus-adapter]# cat custom-metrics-apiserver-deployment.yaml ... ... secret: secretName: cm-adapter-serving-certs # secret 的名称 [root@master-0 pki]# (umask 077; openssl genrsa -out serving.key 2048) Generating RSA private key, 2048 bit long modulus ..........+++ .....................................................+++ # 生成一个证书签署请求 [root@master-0 pki]# openssl req -new -key serving.key -out serving.csr -subj "/CN=serving" # 主体名必须为 serving # 签证 [root@master-0 pki]# openssl x509 -req -in serving.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out serving.crt -days 3650 Signature ok subject=/CN=serving Getting CA Private Key # 创建 secret [root@master-0 pki]# kubectl create secret generic cm-adapter-serving-certs --from-file=serving.crt=./serving.crt --from-file=serving.key=./serving.key -n prom secret/cm-adapter-serving-certs created
-
部署 k8s-prometheus-adapter,使 API 可用
[root@master-0 pki]# cd ~/metrics/k8s-prom/k8s-prometheus-adapter/ [root@master-0 k8s-prometheus-adapter]# kubectl apply -f . clusterrolebinding.rbac.authorization.k8s.io/custom-metrics:system:auth-delegator created rolebinding.rbac.authorization.k8s.io/custom-metrics-auth-reader created deployment.apps/custom-metrics-apiserver created clusterrolebinding.rbac.authorization.k8s.io/custom-metrics-resource-reader created serviceaccount/custom-metrics-apiserver created service/custom-metrics-apiserver created apiservice.apiregistration.k8s.io/v1beta1.custom.metrics.k8s.io created clusterrole.rbac.authorization.k8s.io/custom-metrics-server-resources created clusterrole.rbac.authorization.k8s.io/custom-metrics-resource-reader created clusterrolebinding.rbac.authorization.k8s.io/hpa-controller-custom-metrics created [root@master-0 metrics]# kubectl api-versions|grep custo custom.metrics.k8s.io/v1beta1 [root@master-0 metrics]# kubectl proxy --port 8080 & [1] 3966 [root@master-0 metrics]# Starting to serve on 127.0.0.1:8080 [root@master-0 metrics]# curl http://127.0.0.1:8080/api/custom.metrics.k8s.io/v1beta1 ... ...
HPA
支持应用规模的自动伸缩,根据某些资源指标达到某些临界点后,自动修改副本数量,并且拓展数量是根据算法得到的,这个算法会趋于接近用户对资源的限制,所以需要注意如果要使用 HPA 则必须要对 pod 进行资源限制.HPA 至今有两个版本 V1 和 V2,V1 只支持核心指标来定义,而内存作为不可压缩资源所以不能进行弹性缩放,所以 V1 版本只能根据 CPU 来进行弹性伸缩,可以通过查看 kubectl api-versions
中是否有 autoscaling/v1
和 autoscaling/v2beta1
来确认是否支持 V1 和 V2 版本
[root@master-0 ~]# kubectl explain hpa.spec
KIND: HorizontalPodAutoscaler
VERSION: autoscaling/v1
RESOURCE: spec <Object>
DESCRIPTION:
behaviour of autoscaler. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
specification of a horizontal pod autoscaler.
FIELDS:
maxReplicas <integer> -required- # 最大副本数
upper limit for the number of pods that can be set by the autoscaler;
cannot be smaller than MinReplicas.
minReplicas <integer> # 最小副本数
minReplicas is the lower limit for the number of replicas to which the
autoscaler can scale down. It defaults to 1 pod. minReplicas is allowed to
be 0 if the alpha feature gate HPAScaleToZero is enabled and at least one
Object or External metric is configured. Scaling is active as long as at
least one metric value is available.
scaleTargetRef <Object> -required- # 其他资源指标
reference to scaled resource; horizontal pod autoscaler will learn the
current resource consumption and will set the desired number of pods by
using its Scale subresource.
targetCPUUtilizationPercentage <integer> # 对 CPU 评估
target average CPU utilization (represented as a percentage of requested
CPU) over all the pods; if not specified the default autoscaling policy
V1 控制器
-
准备环境
[root@master-0 ~]# cat delopy.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: myapp name: myapp spec: replicas: 1 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - image: =ikubernetes/myapp:v1 name: myapp resources: requests: cpu: "50m" memory: "256Mi" limits: cpu: "50m" memory: "256Mi" [root@master-0 ~]# kubectl apply -f delopy.yaml deployment.apps/myapp created [root@master-0 ~]# kubectl autoscale deployment myapp --min=1 --max=8 --cpu-percent=60 horizontalpodautoscaler.autoscaling/myapp [root@master-0 ~]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE myapp Deployment/myapp <unknown>/60% 1 8 1 45s
-
开放端口并进行压测
[root@master-0 ~]# kubectl patch svc myapp -p '{"spec":{"type":"NodePort"}}' service/myapp patched [root@master-0 ~]# ab -c 100 -n 500000 http://10.211.55.36:31458/index.html
V2 控制器
HPA v2 控制器支持基于核心指标 CPU 和内存资源以及基于任意自定义指标资源占用状态实现应用规模的自动弹性伸缩,它从metrics-server中请求查看核心指标,从 k8s-prometheus-adapter 一类的自定义 API 中获取自定义指标数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rreRrVcG-1624628012083)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20201006225035.png)]
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa-v2
spec:
scaleTargetRef: # 对谁进行自动拓展
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 1 # 最少数量
maxReplicas: 10 # 最大数量
metrics: # 依据那些指标来评估
- type: Resource
resource:
name: cpu
targetAverageUtilization: 55
- type: Resource
resource:
name: memory
targetAverageValue: 50Mi
metrics 具体能用那些自定义指标则需要是 Prometheus 中能获取到那些资源,即为 pod 中那些指标可以上报来决定
- minReplicas: 自动伸缩可缩减至的Pod副本数下限.
- maxReplicas: 自动伸缩可扩展至的Pod副本数上限,其值不能低于min-Replicas属性值.
- scaleTargetRef: 要缩放的目标资源,以及应该收集指标数据并更改其副本数量的Pod对象,引用目标对象时,主要会用到三个嵌套属性—apiVersion、kind和name.
- metrics: 用于计算所需Pod副本数量的指标列表,每个指标单独计算其所需的副本数,将所有指标计算结果中的最大值作为最终采用的副本数量.计算时,以资源占用率为例,所有现有Pod对象的资源占用率之和除以目标占用率所得的结果即为目标Pod副本数,因此增加Pod副本数量必然地会降低各Pod对象的资源占用率.metrics字段值是对象列表,它由要引用的各指标的数据源及其类型构成的对象组成.
- external:用于引用非附属于任何对象的全局指标,甚至可以基于集群之外的组件的指标数据,如消息队列的长度等.
- object:引用描述集群中某单一对象的特定指标,如Ingress对象上的hits-per-second等.定义时,嵌套使用metricName、target和targetValue分别用于指定引用的指标名称、目标对象及指标的目标值.
- pods:引用当前被弹性伸缩的Pod对象的特定指标,如transactions-processed-per-second等,各Pod对象的指标数据取平均值后与目标值进行比较.定义时,嵌套使用metricName和targetAverageValue分别指定引用的指标名称和目标平均值.
- resource:引用资源指标,即当前被弹性伸缩的Pod对象中容器的requests和limits中定义的指标(CPU或内存资源).定义时,嵌套使用name、targetAverageUtilization和targe-tAverageValue分别用于指定资源的名称、目标平均利用率和目标平均值.
- type:表示指标源的类型,其值可为Objects、Pods或Resource.
基于自定义指标API中的指标配置HPA对象时,其指标的来源途径还包括pods、object和external等,这其中又以Pod或引用的特定object的指标调用居多