k8s_day10_04
指标是什么东西?对于k8s 而言, 指标存在于各种角落:比如节点资源状态、节点资源自身的消耗,活动pod 数量、应用本身编排指标、比如各种控制器的指标,还包括容器自身的指标,除了容器自身资源的消耗外,还有业务级指标。在k8s上,需要监控的指标更多。
早期的k8s 在kublet 当中集成了kube advisor, 是为了更加便于监控 获取 各个节点kubelet 之上 各个节点支撑运行的容器级别的指标,当然也顺带包括了节点级别的指标
就算我们在每个节点 都添加了cadivser, 但是我们没有一个集中的位置 统一的去查看集群级别的指标。比如你知道一个节点运行了3个pod ,4 个容器,但是你不知道集群里面一共多少个pod 、容器。 但是k8s 一些工具 是依赖这些 集群级的指标的 例如 kubecl top
[root@node01 ~]# kubectl top node error: Metrics API not available
error 表示的是 虽然现在kublet内建了cadvisor, 但是 资源指标api 不能用 ,没有集群级能汇总 各个kublet 之上的 指标工具 程序。 并通过 兼容的 k8s api server 接口输出出来。 这个接口是存在的,但是没有对应的后端。 k8s 默认并不会自动收集 位于分散在各个节点资源指标实现, 而是靠一个后端来实现 ,为了 便于管理, k8s 早期提供了一个叫Heapster 的服务器。但是Heapster 因为各种原因 ,比如设计上的、实现上的缺陷 而被弃用了。而如今,今天k8s 上的指标又被分成了2类:
核心指标:k8s 本身自己就要用到,比如top 命令。 比如节点级别 计算资源使用情况,pod级别资源 汇总使用情况等等
自定义指标: 用户想定义什么,可以按需定义。叫做自定义指标 或者扩展指标
这些指标分别有不同的系统进行输出。
核心指标 用 metrics server 来进行输出。
metrics server 联系每一个kubelet 而后收集这个节点上的kubelet pod 级、内存 、存储的使用状况 统一汇总后,统一使用mtrics api 输出出来。这时后top 命令就可以用了。
自定义指标一般通过 监控服务器 来实现, 比如prometheus 去暴露收集。而自定义指标 也有它专用的api 接口 ,只不过叫 custom-api 之类的,只要我们部署之后就会在 资源群组当中加进去。’
如图: metrics server 需要从每一个kubelet 上 周期性的采集指标, 采取之后 通过 /api/metrics.k8s.io/v1beta1 进行暴露,之后就可以被kubectl top 命令、scheduler、hpa 所调用 使用
hpa 水平自动伸缩器
自定义指标采集 需要部署一个 监控系统,比如 heapster、prometheus 之类的。它们也可以从kubelet 上收集非核心资源指标,把它纳入到监控系统上去 并且非核心资源指标 也能暴露到api server 上, 以兼容 apiserver 指标格式 对外进行暴露, 也可以被 hpa 和scheduler 所使用。 只不过这时候用到的是 custom metrics api .
所以我们发现 指标不仅被监控系统所依赖, 而且 k8s 系统组件也要用到
部署 metrics server部署好 metrics server 之后, 可以通过 metrics.k8s.io 群组 进行访问, 不需要直接访问 ,可以通过kubectl top 或者 dashboard 来访问,它们在展示相关信息的时候 会用到这个api
metrics server 与metrics api 之间通过kube-aggregator 进行对接。用户对核心群组的访问 都由 kube-apiserver 进行解析。
对metrics 访问 都由 metrics server 进行解析。metrics server 从本质上来说 就是自定义服务器,自定义api server ,需要通过api Servcie 对接到metrics server 上。
部署 metrics servermetrics server 是k8s 自己维护的组件. 项目地址:https://github.com/kubernetes-sigs/metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
metrics server 服务和启动相关的参数:
–tls-cert-file和–tls-private-key-file:metrics-server服务进程使用的证书和私钥,未指定时将由程序自动生成自签证书,生产环境建议自行指定;–secure-port= 注意 metrics 只是抓取了指标存缓存在内存当中,并不保存指标 , 可认为是 实时抓取的, 无法持久存放。和promethus 不同. promethus 的指标格式 与k8s 的指标格式不兼容。 2个系统之间不兼容的时候需要添加中间层。 最终实现的效果就是 promethus 在k8s 上抓取指标后 输出到中间层 进行转换后 再让 HPA、scheduler 使用。 这个中间层叫k8s适配器. promethus 通过5种role 进行服务发现 抓取5种资源类型的指标,但是有些k8s 的指标 prothmeus 是抓取不到的,此时还需要额外部署一个exporter. 相当于就会有2个中间层。 kube-state-metrics:该组件用于根据Kubernetes API Server中的资源派生出多种资源指标,它们主要是资源类型相关的计数器和元数据信息,包括指定类型的对象总数、资源限额、容器状态(ready/restart/running/terminated/waiting)以及Pod资源的标签系列等。 比如prometheus监控 会自动部署一个 prom-kube-state-metrics-f554d9d6-zzqvd kubectl top 命令可以正常使用就行。 promethus 也可以监控这些核心指标,也能抓取非核心资源指标,但是同时核心与非核心的指标 它的指标格式 与k8s 不兼容。需要部署指标适配器,把promethus抓取的指标适配到k8s当中去。 目前来说,资源适配器 有2个解决方案: 第三方用户提供的, 在适配到k8s 时 会提供另外一个群组:custom.metrics.k8s.io或external.metrics.k8s.io (自定义指标 或 外部指标群组,说白了就不是metrics server提供 的, kube-metrics-adapter 也会生成这个群组) 查看值文件, 修改prometheus的位置 ,保证和 集群环境的一样 修改值文件 安装 安装完成之后发现有提示 kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 验证结果 等待 pod adapter-prometheus-adapter ready 时 就可以抓取到promethues 的数据了 eg: 查看所有指标名称 这些指标 无http_total、http_request 之类的指标 无法直接得出速率 指标 但是这些指标拿来 用于判断是否扩展pod 的并不多 ,用的比较多的是另外一个: 比如现在有一个deployment 内含有3个pod: 对外提供的是http 服务。扩展pod需要判断的依据有: http 请求速率、 cpu 利用率。 比如 http请求利用率是20/s个 , 现在是59/s 个, 则需要再扩展2个。 过去扩展都是手动来的, k8s 提供了一个控制器 HPA 水平pod 扩缩器来实现的。HPA 有2个版本 ,v1 v2。 如果无法直接得到指标, 可以通过自定义的指标来实现: 把一个pod 输出出来的指标转为 k8s 可以支持的格式就行了。 正常情况下 prometheus-adapter 默认只能暴露一些常规指标到 k8s 上来 ,由默认的规则进行暴露,如果想暴露http 相关的指标,你得自己定义。定义 prometheus-adapter 的值文件来实现。 值文件当中 rules 规则默认是true 自定义指标 只定义规则 示例, 写在cm 上, 或者 helm部署时指定值文件 编辑cm 让cm 生效 adapterpod 重启后,再部署验证是否可以抓取只定义的指标 例一: hpa v1有这样的功能,可以根据cpu 的消耗评估是否扩容 对demoapp 持续发起请求并且压测 cpu 使用率达到一定级别的时候 就自动扩容 而小于某个 水位后就自动缩容。hpa 的定义很简单,只要指明以哪个资源为标准进行监控,这个资源最大占多少比例 最少占多少比例 注意 这里查询的指标 是核心指标用的是metric server 而不是promethus server 查看资源 注意这里即时达到阈值也不是马上扩容的,为了稳定性,避免pod 抖动 对apiserver 产生压力 是等一会再扩容的 压测鉴定结果 验证抓取自定义的指标 hpa v2 的定义 不支持命令行 只支持 清单 压测监视 这里的m表示毫, 除1000 表示真正的值。 当请求下降时 ,就会自动缩容
[root@node01 ~]# kubectl get po -n monitoring
NAME READY STATUS RESTARTS AGE
prom-kube-state-metrics-f554d9d6-zzqvd 1/1 Running 0 3d11h
[root@node01 ~]# kubectl get po -n kube-system|grep ^m
metrics-server-5cd45478bf-xvvdc 0/1 Running 0 85m
E0129 13:30:37.138644 1 scraper.go:140] "Failed to scrape node" err="Get "https://192.168.2.1:10250/metrics/resource": x509: cannot validate certificate for 192.168.2.1 because it doesn't contain any IP SANs" node="master01"
I0129 13:30:41.433115 1 server.go:187] "Failed probe" probe="metric-storage-ready" err="no metrics to serve"。
主要原因是因为它无法把节点名解析为对应的IP地址。 core dns 解析了服务到服务的ip coredns 不会解析节点名 到节点ip 的
使用 --kubelet-insecure-tls 可解决。 或者在core dns 之中 加几条资源解析记录就行了,最好放在外部dns 上, 把com的解析 转发到外部dns 上(因为我使用的域名是 xx.magedu.com)
验证结果
[root@node01 ~]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master01 299m 14% 1727Mi 47%
node01 267m 13% 1886Mi 51%
node02 247m 12% 1556Mi 42%
node03 241m 12% 1646Mi 44%
[root@node01 ~]# helm repo list |grep pro
prometheus-community https://prometheus-community.github.io/helm-charts
[root@node01 ~]# helm show values prometheus-community/prometheus-adapter > /tmp/pro-adapter
[root@node01 ~]# kubectl get svc -n monitoring|sed -nr '/server/p;1p'
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prom-prometheus-server ClusterIP 10.110.204.145
[root@node01 ~]# vim /tmp/pro-adapter
prometheus:
# Value is templated
url: http://prom-prometheus-server.monitoring.svc.cluster.local.
port: 80
path: ""
[root@node01 ~]# helm install prom-adapter prometheus-community/prometheus-adapter -n kube-system -f /tmp/pro-adapter
[root@node01 ~]# kubectl api-versions|grep cu
custom.metrics.k8s.io/v1beta1
[root@node01 ~]# kubectl get po -n kube-system |sed -nr '/adapter/p;1p'
NAME READY STATUS RESTARTS AGE
prom-adapter-prometheus-adapter-86d8dc94c8-jcgh5 1/1 Running 0 4m
[root@node01 ~]# yum install jq
[root@node01 ~]# kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1|jq .
[root@node01 ~]# kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1|jq '.resources[].name'
v1 版本仅仅支持根据核心资源 cpu 、 内存 来扩展
v2 版本可以额外支持 根据自定义资源的伸缩。
rules:
default: true
# - seriesQuery: '{__name__=~"^some_metric_count$"}'
# resources:
# template: <<.Resource>>
# name:
# matches: ""
# as: "my_custom_metric"
rules:
default: true # 是否加载默认规则;
custom:
[root@node01 ~]# kubectl get cm/prom-adapter-prometheus-adapter -n kube-system -o yaml > /tmp/prom-adapter-prometheus-secret.yaml
- seriesQuery: 'http_requests_total{kubernetes_namespace!="",kubernetes_pod_name!=""}'
resources:
overrides:
kubernetes_namespace: {resource: "namespace"}
kubernetes_pod_name: {resource: "pod"}
name:
matches: "^(.*)_total"
as: "${1}_per_second"
metricsQuery: 'rate(<<.Series>>{<<.LabelMatchers>>}[2m])'
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: prom-adapter
meta.helm.sh/release-namespace: kube-system
labels:
app.kubernetes.io/component: metrics
app.kubernetes.io/instance: prom-adapter
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: prometheus-adapter
app.kubernetes.io/part-of: prometheus-adapter
app.kubernetes.io/version: v0.9.1
helm.sh/chart: prometheus-adapter-3.0.1
name: prom-adapter-prometheus-adapter
namespace: kube-system
:71,79s@^@ @ 行首添加2个空格
[root@node01 ~]# kubectl apply -f /tmp/prom-adapter-prometheus-secret.yaml
[root@node01 ~]# kubectl delete pod/prom-adapter-prometheus-adapter-86d8dc94c8-jcgh5 -n kube-system
pod "prom-adapter-prometheus-adapter-86d8dc94c8-jcgh5" deleted
创建hpa
[root@node01 hpa]# kubectl apply -f demoapp.yaml
deployment.apps/demoapp created
service/demoapp created
[root@node01 hpa]# cat demoapp.yaml
# Maintainer: MageEdu
[root@node01 hpa]# kubectl autoscale deploy/demoapp --min=2 --max=5 --cpu-percent=60
horizontalpodautoscaler.autoscaling/demoapp autoscaled
get hpa
[root@node01 hpa]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
demoapp Deployment/demoapp 2%/60% 2 2 2 58s
[root@node01 hpa]#
[root@node01 ~]# kubectl get hpa -oyaml
name: demoapp
namespace: default
resourceVersion: "898577"
uid: 7cb11806-d6eb-41d1-9dae-9c93a9dfcb59
spec:
maxReplicas: 2
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: demoapp
targetCPUUtilizationPercentage: 60
status:
currentCPUUtilizationPercentage: 2
currentReplicas: 2
desiredReplicas: 2
kind: List
[root@node01 ~]# kubectl run pod-$RANDOM --image='ikubernetes/demoapp:v1.0' --rm -it --command -- /bin/sh
[root@pod-24647 /]# while true ; do curl 10.107.219.99; done
[root@node01 ~]# kubectl get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
demoapp Deployment/demoapp 78%/60% 2 5 5 72s
例二: 根据自定义指标扩容
[root@node01 hpa]# cat metrics-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: metrics-app
spec:
replicas: 2
selector:
matchLabels:
app: metrics-app
controller: metrics-app
template:
metadata:
labels:
app: metrics-app
controller: metrics-app
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "80"
prometheus.io/path: "/metrics"
spec:
containers:
- image: ikubernetes/metrics-app
name: metrics-app
ports:
- name: web
containerPort: 80
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "256Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: metrics-app
spec:
type: NodePort
ports:
- name: web
port: 80
targetPort: 80
selector:
app: metrics-app
controller: metrics-app
[root@node01 ~]# kubectl get svc/metrics-app -ojson|jq .spec.clusterIP
"10.97.97.241"
[root@node01 ~]# curl 10.97.97.241/demoapp
Hello! My name is metrics-app-78b85cf78c-5st5j. The last 10 seconds, the average QPS has been 0.1. Total requests served: 11
[root@node01 ~]#
[root@node01 hpa]# cat metrics-app-hpa.yaml
kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2beta2
metadata:
name: metrics-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: metrics-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: Averagevalue
averagevalue: 5
behavior:
scaleDown:
stabilizationWindowSeconds: 120
[root@pod-26996 /]# while true ; do curl -s 10.97.97.241/metrics .5 ; done
[root@node01 hpa]# kubectl get hpa/metrics-app-hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
metrics-app-hpa Deployment/metrics-app 100m/5 2 10 2 2m12s
metrics-app-hpa Deployment/metrics-app 13800m/5 2 10 6 4m31s
metrics-app-hpa Deployment/metrics-app 43866m/5 2 10 6 5m3s
metrics-app-hpa Deployment/metrics-app 20750m/5 2 10 10 6m51s
metrics-app-hpa Deployment/metrics-app 10575m/5 2 10 10 7m6s
metrics-app-hpa Deployment/metrics-app 100m/5 2 10 10 7m21s
metrics-app-hpa Deployment/metrics-app 100m/5 2 10 10 8m54s
metrics-app-hpa Deployment/metrics-app 100m/5 2 10 10 9m9s
metrics-app-hpa Deployment/metrics-app 100m/5 2 10 2 9m24s



