资源监控系统是容器编排系统必不可少的组件,它为用户提供了快速了解系统资源分配和利用状态的有效途径,同时也是系统编排赖以实现的基础要件。
Kubernetes有多个数据指标需要采集相关的数据,而这些指标大体上由监控集群本身和监控Pod对象两部分组成,监控集群需要监控节点资源状态、节点数量、运行的pod数量;监控Pod资源对象需要监控kubernetes指标,容器指标和应用程序指标。
Kubernetes系统与kubelet程序中集成相关的工具程序cAdisor用于对节点上的资源及容器进行实时监控及指标数据采集,这类监控的实现方式有Heapster。从kubernetes1.11开始Heapster被废弃不在使用,metrics-server 替代了heapster
新一代的kubernetes监控系统架构主要由核心指标流水线和监控指标流水线协同组成。核心指标流水线由kubelet、资源评估器、metrics-server及API server提供的API群组组成,可用于为kubernetes系统提供核心指标从而能够了解其内部组件和核心程序。监控指标流水线用于从系统收集各种指标数据并提供给终端用户、存储系统及HPA控制器使用。
资源指标API主流的实现是metrics-server,自定义指标API以构建在监控系统Prometheus之上到k8s-prometheus-adapter使用最为广泛。
Metrics server是集群级别的资源利用率数据的聚合器。Metrics server通过kubernetes聚合器(kube-aggregator)注册到主API server之上,然后基于kubelet的summary api收集每个节点上的指标数据,并将它们存储于内存中然后以指标API格式提供。Metrics server的部署步骤如下:
# 拉取资源
]# git clone https://github.com/kubernetes-incubator/metrics-server
# 替换metrics-server/deploy/1.8+/metrics-server-deployment.yaml的镜像地址为deploy/1.8+/metrics-server-deployment.yaml
]# sed -i "s#k8s.gcr.io/metrics-server-amd64:v0.3.3#mirrorgooglecontainers/metrics-server-amd64:v0.3.1#g" /tmp/metrics-server/deploy/1.8+/metrics-server-deployment.yaml
由于metrics-server默认使用节点hostname通过kubelet 10250端口获取数据,但是coredns里面没有该数据无法解析,所以可在metrics server启动命令添加参数 --kubelet-preferred-address-types=InternalIP 直接使用节点IP地址获取数据;同时由于kubelet 的10250端口使用的是https协议,连接需要验证tls证书。可以在metrics server启动命令添加参数--kubelet-insecure-tls不验证客户端证书。
# 在配置文件metrics-server/deploy/1.8+/metrics-server-deployment.yaml添加启动参数
command:
- /metrics-server
- --metric-resolution=30s
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
# 创建资源
]# kubectl create -f metrics-server/deploy/1.8+/metrics-server-deployment.yaml
serviceaccount/metrics-server created
deployment.extensions/metrics-server created
# 查看相关pod资源状态
]# kubectl get pods -n kube-system -l k8s-app=metrics-server -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
metrics-server-8445cfc4db-m4nff 1/1 Running 0 6m47s 10.244.2.63 node02.dayi123.com
# 检查资源的可用性
]# kubectl proxy --port=8080
Starting to serve on 127.0.0.1:8080
# 另开一个窗口检查node节点可用性
]# curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/nodes
{
"kind": "NodeMetricsList",
"apiVersion": "metrics.k8s.io/v1beta1",
"metadata": {
"selfLink": "/apis/metrics.k8s.io/v1beta1/nodes"
},
"items": [
{
"metadata": {
"name": "master01.dayi123.com",
"selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/master01.dayi123.com",
"creationTimestamp": "2019-06-13T11:02:57Z"
},
"timestamp": "2019-06-13T11:03:19Z",
"window": "30s",
"usage": {
"cpu": "222451436n",
"memory": "1129748Ki"
}
. . . . . .
# 获取集群上所有pod对象的相关资源消耗数据
]# curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/pods
Metrics-server正常安装完成后就可以使用kubectl top命令显示节点和pod对象的资源使用信息。
# 显示各节点的资源使用信息
]# kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master01.dayi123.com 200m 10% 1106Mi 64%
node01.dayi123.com 44m 4% 649Mi 46%
node02.dayi123.com 84m 4% 929Mi 54%
# 显示符合条件的pod的资源使用信息
]# kubectl top pods -n kube-system -l k8s-app=kubernetes-dashboard
NAME CPU(cores) MEMORY(bytes)
kubernetes-dashboard-76479d66bb-9xhkf 1m 20Mi
Prometheus是一个开源的服务监控系统和时序数据库,由社交音乐平台SoundClound在2012年开发,目前已成为kubernetes生态圈中的核心监控系统。
Kubernetes源代码的集群附件目录中统一提供了Prometheus、Alertmanager、node_exporter和kube-state-metrics相关的配置清单,路劲为cluster/addons/Prometheus。
# 将kubernetes源码下载至本地
]# wget https://github.com/kubernetes/kubernetes/releases/download/v1.13.2/kubernetes.tar.gz
]# tar -xf kubernetes.tar.gz
(1)生成集群资源状态指标
Kube-state-metrics能够从Kubernete API Server上收集各大多数资源对象的状态信息并将其转化为指标数据,它工作于HTTP的/metrics接口,通过prometheus客户端暴露于外。Kube-state-metric主要负责为Cronjob、deployment、persistentvolumeclaim等各类型的资源对象生成指标数据。
# 修改镜像地址
]# cd kubernetes/cluster/addons/prometheus/
]# sed -i "s#k8s.gcr.io/addon-resizer:1.8.4#googlecontainer/addon-resizer:1.8.4#g" kube-state-metrics-deployment.yaml
# 部署安装kube-state-metrices
]# kubectl apply -f kube-state-metrics-rbac.yaml
]# kubectl create -f kube-state-metrics-deployment.yaml
]# kubectl create -f kube-state-metrics-service.yaml
# 查看相关pod的运行状况
]# kubectl get pods -n kube-system -l k8s-app=kube-state-metrics
NAME READY STATUS RESTARTS AGE
kube-state-metrics-7f8bd888d9-cph86 2/2 Running 0 3m25s
# 创建一个客户端去测试
]# kubectl run client-$RANDOM --image=cirros -it --rm -- sh
/ # curl -s kube-state-metrics.kube-system:8080/metrics | tail
kube_service_spec_type{namespace="default",service="glusterfs-dynamic-d4149b1c-7ad2-11e9-8957-000c29063a23",type="ClusterIP"} 1
kube_service_spec_type{namespace="default",service="kubernetes",type="ClusterIP"} 1
(2)Exporter及Node Exporter
Prometheus通过HTTP周期性的抓取指标数据,监控目标上用于接收并响应数据抓取请求的组件统称为exporter。在监控系统上exporter将收集到的数据转化为文本格式,并通过HTTP对外暴露相应的接口。
Prometheus为监控类UNIX操作系统提供了一个专用的node_exporter程序。Node_exporter运行为守护进程监听在节点的9100端口,通过URL路劲/metrics提供指标数据。
# 安装node_exporter
# kubectl create -f node-exporter-ds.yml
]# kubectl create -f node-exporter-service.yaml
# 查看创建的node_exporter
]# kubectl get pods -n kube-system -l k8s-app=node-exporter
NAME READY STATUS RESTARTS AGE
node-exporter-9pz7b 1/1 Running 0 15s
node-exporter-q9449 1/1 Running 0 15s
# 测试node_exporter
]# curl node01:9100/metrics | more
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 6.5346e-05
go_gc_duration_seconds{quantile="0.25"} 6.5346e-05
go_gc_duration_seconds{quantile="0.5"} 6.5346e-05
(3)告警系统Alertmanager
Prometheus的告警功能由两个步骤实现,首先是Prometheus服务器根据告警规则将告警信息发送给Alertmanager,然后由Alertmanager对收到的告警信息进行处理。
# 查看可供使用的pv
]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
alert-pv01 2Gi RWO Retain Available
由于使用静态pv供给,在创建pvc前先将alertmanager-pvc.yaml中”storageClassName: nfs”注释掉,否则无法绑定合适的pv。
# 创建pvc并查看创建的pvc
]# sed -i “s@storageClassName: nfs@#storageClassName: nfs @g”
]# kubectl apply -f alertmanager-pvc.yaml
]# kubectl get pvc -n kube-system
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
alertmanager Bound alert-pv01 2Gi RWO 11m
# 创建其他资源
]# kubectl apply -f alertmanager-configmap.yaml
]# kubectl apply -f alertmanager-deployment.yaml
# 创建service时先修改service类型为NodePort
]# sed -i "s#ClusterIP#NodePort#g" alertmanager-service.yaml
]# sed -i "s#ClusterIP#NodePort#g" alertmanager-service.yaml
# 查看创建的svc
]# kubectl get svc -n kube-system -l kubernetes.io/name=Alertmanager
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager NodePort 10.106.61.11 80:32442/TCP 2m51s
Alertmanager安装后的界面如下:
(4)部署Prometheus服务器
Prometheus服务器是整个监控系统的核心,它通过各exporter周期性的采集指标数据,存储于本地的TSDB后端存储系统中,并通过PromQL向客户端提供查询接口。
# 先创建configmap和rbac
]# kubectl apply -f prometheus-rbac.yaml
serviceaccount/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
]# kubectl apply -f prometheus-configmap.yaml
在kubernetes项目提供的附件配置清单中,Prometheus使用StatefulSet配置对象,pod对象通过volumeClaimTemplate对象对象动态申请使用存储卷,在部署前,要确保能为其提供使用的存储卷。
# 创建statefulset控制器前先查看可使用的存储类
]# kubectl get StorageClass
NAME PROVISIONER AGE
glusterfs kubernetes.io/glusterfs 24d
# 修改alertmanager-service.yaml中存储供给如下
volumeClaimTemplates:
- metadata:
name: prometheus-data
spec:
storageClassName: glusterfs
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "5Gi"
# 创建该资源
]# kubectl create -f prometheus-statefulset.yaml
]# kubectl get pods -n kube-system -l k8s-app=prometheus
NAME READY STATUS RESTARTS AGE
prometheus-0 2/2 Running 0 7m44s
# 修改service类型为NodePort
]# cat prometheus-service.yaml | tail -1
type: "NodePort"
# 创建service并查看
]# kubectl create -f prometheus-service.yaml
]# kubectl get svc -n kube-system -l kubernetes.io/name=Prometheus
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus NodePort 10.111.119.52 9090:30143/TCP 48s
service资源创建完成后,通过浏览器打开如图所示:
由于手动调整各Pod控制器的副本数量存在一定的滞后性,对此,kubernetes提供了多种弹性的伸缩工具。主要的工具有HPA、CA、VPA、AR。
HPA可作为KubernetesAPI资源的控制实现,它基于采集到得资源指标数据来调整控制器的行为,HPA获取资源指标数据是通过Heapster和REST客户端接口获取。目前HPA有两个版本分别是HPA和HPA v1。
HPA也是标准的Kubernetes API资源,它的创建方式可通过资源配置清单的方式创建或者通过”kubectl autoscale”命令创建。
# 先创建一个deployment控制器
]# kubectl run mynginx --image=nginx:1.12 --replicas=2 --requests='cpu=5m,memory=128Mi' --limits='cpu=50m,memory=128Mi' --labels='app=mynginx' --expose --port=80
# 创建HPA控制器自动管控Pod副本
]# kubectl autoscale deploy mynginx --min=2 --max=5 --cpu-percent=60
HPA(v1)只能基于cpu实现自动弹性伸缩,HPA(v2)控制器基支持基于核心指标CPU和内存资源及基于任意自定义指标资源占用状态实现规模的弹性伸缩,它从metrics-service中请求查看核心指标。
基于前面创建的mynginx的deployment控制器定义一个基于内存和cpu的hpa控制器资源配置清单如下:
]# cat hpav2-mynginx.yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: mynginx
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: mynginx
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 50
- type: Resource
resource:
name: memory
targetAverageValue: 50Mi
spec中嵌套的个字段的说明如下:
(1)minReplicas:自动伸缩pod副本数下限
(2)maxReplicas:自动伸缩可扩展至Pod副本数的上限
(3)scaleTargetRef:要伸缩的目标资源
(4)metrics:用于计算所需的Pod副本数量的指标列表
(5)external:用于应用非附属于任何对象的全局指标
(6)object:应用描述集群中某单一对象的特定指标
(7)pods:应用被弹性伸缩的pod对象的特定指标
(8)resource:应用资源指标,即当前被弹性伸缩的pod对象中容器的requests和limits中定义的指标。
(9)type:标识指标源的类型