资源监控及资源指标
Heapster仅支持基于CPU一项指标提供HPA
资源监控及Heapster
监控集群本身和监控Pod对象
kubelet程序中集成了cAdvisor,可对节点上资源及容器进行实时监控及指标数据采集(CPU、内存、网络、文件系统等使用情况),可通过TCP4194端口提供Web UI (kubeadm默认未启用)
cAdvisor仅能收集单个节点及其相关Pod资源的相关指标数据
Heapster是集群级别的监视和事件数据聚合工具
Heapster可作为集群中一个Pod对象运行,通过发现所有节点实现从每个节点kubelet内建的cAdvisor获取性能和指标数据,并通过标签将Pod对象及其相关监控数据进行分级、聚合后推送到可配置的后端存储系统进行存储和可视化
由InfluxDB作为存储后端,Grafana为可视化接口
新一代监控架构
资源指标API主要供核心系统组件使用,如调度程序、HPA、kubectl top等
新一代监控系统由核心指标流水线和监控指标流水线协同组成
HPA仅支持基于CPU利用率的自动缩放
HPAv2实现了基于观察到的指标,不仅是CPU
资源指标API的实现较主流的是 metrics-server
自定义指标API的实现较主流的是 k8s-prometheus-adapter
资源指标及其应用
指标API能查询某节点或Pod的当前资源占用情况,但API本身不存储任何指标数据,仅能提供实时数据
部署 metrics-server
只有在集群中部署 metrics-server 应用后,指标API方可用
metrics-server可看作是仅服务于指标数据的简化版Heapster
通过kube-aggregator注册到主API Server上,而后基于kubelet的Summary API收集每个节点上的指标数据,并将其存储于内存中(重启后会丢失,仅留存最近的指标数据)然后以指标API格式提供
Metrics Server 在每个集群仅运行一个实例,启动时,自动初始化与各节点的连接,出于安全考虑,需运行于普通节点而非Master节点
git clone https://github.com/kubernetes-incubator/metrics-server.git
# 默认会从kubelet的基于HTTP的10255端口获取指标数据,但出于安全通信目的,kubeadm在初始化集群时会关掉10255端口,导致无法正常获取数据
# 此外 deploy/1.8+/metrics-server-deployment.yaml中未明确主程序/metrics-server传递参数指定指标数据获取接口,通常应是 kubernetes.summary_api
deploy/1.8+/metrics-server-deployment.yaml需要作如下修改:
1 2 3 4 5 6 7 8 9 |
spec: ... containers: - name: metrics-server image: mirrorgooglecontainers/metrics-server-amd64:v0.3.1 ... args: - --kubelet-insecure-tls - --kubelet-preferred-address-types=InternalIP |
kubectl apply -f metrics-server/deploy/1.8+/
## 验证
# 查看api是否已添加metrics
kubectl api-versions | grep metrics
# 查看pod状态
kubectl get pods -n kube-system -l k8s-app=metrics-server
# 查看pod日志
kubectl logs metrics-server-6d5776fcd8-2vrmx -n kube-system
# 检查资源指标API是否为可用状态
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" | jq .
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/pods" | jq .
kubectl top 命令
kubectl top 可显示节点和Pod对象的资源使用信息,依赖于集群中的资源指标API来收集各项指标数据
kubectl top node [-l label | NAME]
kubectl top pod [NAME | -l label] [--all-namespaces] [--containers=false|true]
kubectl top pods --all-namespaces
自定义指标与Prometheus
k8s-prometheus-adapter 项目
Prometheus
1、监控代理程序,收集标准的主机指标数据
2、kubelet (cAdvisor),收集容器指标数据,即K8s核心指标
3、API Server,收集API Server的性能指标数据,包括控制队列的性能、请求速率、延迟,etcd缓存队列,普通进程状态,Golang状态
4、etcd,存储集群相关指标数据
5、kube-state-metrics,对象总数、资源限额、容器状态、Pod标签等
Prometheus把API Server作为服务发现系统发现和监控集群中的所有可被监控对象
Pod资源需添加以下注解才能被Prometheus系统自动发现并抓取其内建的指标数据:即内部部署有agent
prometheus.io/scrape,是否采集指标数据,true/false
prometheus.io/path,URL路径,常为 /metrics
prometheus.io/port,端口号
仅期望Prometheus为后端生成自定义指标时,仅部署Prometheus服务即可,甚至不需要持久功能
部署Prometheus监控系统
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/prometheus
# 包括prometheus、alertmanager、node_exporter、kube-state-metrics等
1、生成集群资源状态指标
kube-state-metrics 从API Server收集资源对象状态信息并转为指标数据,关注内部各种对象的整体运行状况
kube-state-metrics 提供prometheus格式的数据
部署,在kube-system空间创建名为kube-state-metrics的Deployment控制器,生成的Pod监听8080和8081端口,指供指标数据,同时会创建同名Service对象
k8s.gcr.io/addon-resizer:1.8.4 -> siriuszg/addon-resizer:1.8.4
quay.io/coreos/kube-state-metrics:v1.3.0
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/kube-state-metrics-deployment.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/kube-state-metrics-rbac.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/kube-state-metrics-service.yaml
查看提供的指标数据:curl 10.105.51.200:8080/metrics # 10.105.51.200 是Service的IP
2、Exporter及Node Exporter
监听 9100 端口
事实上,每个节点本身就能通过kubelet或cAdvisor提供节点指标数据,因此要不安装node_exporter程序
# 实际上配置清单中也没有加载各节点exporter上的指标
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/node-exporter-ds.yml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/node-exporter-service.yaml
只运行于node节点
查看提供的指标数据: curl 192.168.1.120:9100/metrics
3、告警系统 Alertmanager
prometheus根据告警规则将告警信息发送给alertmanager,而后alertmanager对收到的告警信息进行处理,包括去重、分组并路由到告警接收端
alertmanager使用了持久存储卷,PVC ;端口9093会有Web UI
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/alertmanager-configmap.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/alertmanager-deployment.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/alertmanager-pvc.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/alertmanager-service.yaml
# 这里pvc使用存储类 storageClassName: gluster-dynamic
# metadata.annotations: volume.beta.kubernetes.io/storage-class: gluster-dynamic
查看Web UI: http://192.168.1.110:30093/#/alerts
4、部署Prometheus服务器
Prometheus提供Web UI,端口9090,需要存储卷,通过volumeClaimTemplates提供
# storageClassName: gluster-dynamic
# storage: "3Gi"
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/prometheus-configmap.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/prometheus-rbac.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/prometheus-service.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.13.2/cluster/addons/prometheus/prometheus-statefulset.yaml
查看Web UI: http://192.168.1.110:30095/graph
自定义指标适配器 k8s-prometheus-adapter
PromQL接口无法直接作为自定义指标数据源,它非聚合API服务器
需要使用 k8s-prometheus-adapter
首先,用户需要生成SSL证书,并配置为Secret对象
cd /etc/kubernetes/pki/
(umask 077;openssl genrsa -out serving.key 2048)
openssl req -new -key serving.key -out serving.csr -subj "/CN=serving"
openssl x509 -req -in serving.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out serving.crt -days 3650
k8s-prometheus-adapter默认部署在custom-metrics名称空间,在该名称空间创建secret对象
# 证书和私钥键名为 serving.crt 和 serving.key
kubectl create namespace custom-metrics
kubectl create secret generic cm-adapter-serving-certs -n custom-metrics --from-file=serving.crt=./serving.crt --from-file=serving.key=./serving.key
# 部署
## git clone https://github.com/DirectXMan12/k8s-prometheus-adapter
kubectl apply -f k8s-prometheus-adapter/deploy/manifests/
编辑:custom-metrics-apiserver-deployment.yaml 第28行
--prometheus-url=http://prometheus.prom.svc:9090/ -> --prometheus-url=http://prometheus.kube-system.svc:9090/
会在kube-aggregator上注册API群组 custom.metrics.k8s.io
# 查看API
kubectl api-versions | grep custom
# 列出指标名称
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq '.resources[].name'
# 查看pod内存占用率
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/kube-system/pods/*/memory_usage_bytes" | jq .
HPA 自动弹性缩放
自动弹性伸缩工具 Auto Scaling:
HPA,Horizontal Pod Autoscaler,两个版本,HPA仅支持CPU指标;HPAv2支持资源指标API和自定义指标API
CA,Cluster Autoscaler,集群规模自动弹性伸缩,能自动增减节点数量,用于云环境
VPA,Vertical Pod Autoscaler,Pod应用垂直伸缩工具,调整Pod对象的CPU和内存资源需求量完成扩展或收缩
AR,Addon Resizer,简化版本的Pod应用垂直伸缩工具,基于集群中节点数量调整附加组件的资源需求量
HPA
HPA自身是一个控制循环,周期由 controller-manager的 --horizontal-pod-autoscaler-sync-period选项定义,默认为30s
对于未定义资源需求量的Pod对象,HPA控制器无法定义容器CPU利用率,且不会为该指标采取任何操作
对于每个Pod的自定义指标,HPA仅能处理原始值而非利用率
默认缩容延迟时长为5min,扩容延迟时长为3min,目的是防止出现抖动
HPA获取指标的方式:Heapster和REST客户端
Heapster要事先部署于集群上并在kube-system名称空间运行
事先部署好资源指标API及其API Server,必要时,还要部署好自定义指标API及其相关的API Server
autoscaling/v1 HPA
autoscaling/v2beta1 HPAv2
HPA(v1)控制器
# 创建 deployment及service
kubectl run myapp --image=ikubernetes/myapp:v1 --replicas=2 --requests='cpu=50m,memory=256Mi' --limits='cpu=50m,memory=256Mi' --labels='app=myapp' --expose --port=80
# 创建hpa控制器
kubectl autoscale deployment myapp --min=2 --max=5 --cpu-percent=60
# 查看hpa
kubectl get hpa
kubectl get hpa -o yaml --export
HPA(v2)控制器
HPA(v2)支持从metrics-server中请求核心指标;从k8s-prometheus-adapter一类自定义API中获取自定义指标数据
多个指标计算时,结果中数值较大的胜出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata: name: myapp spec: scaleTargetRef: # 要缩放的目标资源 apiVersion: apps/v1 kind: Deployment name: myapp minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 50 - type: Resource resource: name: memory targetAverageValue: 50Mi |
metrics,计算所需Pod副本数量的指标列表,每个指标单独计算,取所有计算结果的最大值作为最终副本数量
- external,引用非附属于任何对象的全局指标,可以是集群之外的组件的指标数据,如消息队列长度
- object,引用描述集群中某单一对象的特定指标,如Ingress对象上的hits-per-second等
- pods,引用当前被弹性伸缩的Pod对象的特定指标
- resource,引用资源指标,即当前被弹性伸缩的Pod对象中容器的requests和limits中定义的指标
- type,指标源的类型,可为Objects、Pods、Resource
示例:
ikubernetes/metrics-app 运行时会通过 /metrics路径输出 http_requests_total 和 http_requests_per_second 两个指标
注释 prometheus.io/scrape:"true" 使Pod对象能够被 Promethues采集相关指标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
apiVersion: apps/v1 kind: Deployment metadata: labels: app: metrics-app name: metrics-app spec: replicas: 2 selector: matchLabels: app: metrics-app template: metadata: labels: app: 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: cpu: 200m memory: 256Mi readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 3 periodSeconds: 5 livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 3 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: metrics-app labels: app: metrics-app spec: ports: - name: web port: 80 targetPort: 80 selector: app: metrics-app |
测试:访问curl 10.104.226.230/metrics
Prometheus通过服务发现机制发现新创建的Pod对象,根据注释提供的配置信息识别指标并纳入采集对象,而后由k8s-prometheus-adapter将这些指标注册到自定义API中,提供给HPA(v2)控制器和调度器等作为调度评估参数使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata: name: metrics-app-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: metrics-app minReplicas: 2 maxReplicas: 10 metrics: - type: Pods pods: metricName: http_requests_per_second targetAverageValue: 800m # 800m 即0.8个/秒 |
添加自定义指标 http_requests_per_second
编辑 k8s-prometheus-adapter/deploy/manifests/custom-metrics-config-map.yaml 添加规则:
1 2 3 4 5 6 7 8 9 10 |
rules: - 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: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)' |
自定义规则参考文档:
将prometheus指标升级为k8s自定义指标,需要定义规则
1、https://github.com/DirectXMan12/k8s-prometheus-adapter/blob/master/docs/config-walkthrough.md
2、https://github.com/DirectXMan12/k8s-prometheus-adapter/blob/master/docs/walkthrough.md
将 http_requests_total 命令为 http_requests_per_second 自定义指标
让配置生效:
需要先应用 custom-metrics-config-map.yaml 然后手动删除 custom-metrics 空间下 custom-metrics-apiserver-xxxx Pod
注意:修改config-map后,不删除Pod,不会生效
测试:
kubectl get pods -w
curl 10.104.226.230/metrics
kubectl run client -it --image=cirros --rm -- /bin/sh
while true; do curl http://metrics-app; let i++; sleep 0.$RANDOM; done # 模拟压力
测试需要达到数分钟后才能看到自动扩容,原因是:默认缩容延迟时长为5min,扩容延迟时长为3min
转载请注明:轻风博客 » 马哥_K8s进阶实战(12)资源指标及HPA控制器