- 遇到问题请先看,问题排查文档 ,其中汇总了场景问题和排查思路。
- 对应配置项为collect_mode
cadvisor_plugin | kubelet_agent | server_side
三选一 - 代码为同一套代码
模式名称 | 部署运行方式 | collect_mode配置 | 说明 |
---|---|---|---|
夜莺插件形式采集cadvisor raw api | 可执行的插件由夜莺agent调用 | cadvisor_plugin | 文档在readme最下面 (原有cadvisor采集模式) |
容器基础资源指标采集 | k8s daemonset 部署在每一个node上 | kubelet_agent | 统称为新模式 (kubelet地址由对应metrics port listen地址决定) |
集中采集k8s服务组件 | k8s deployment 部署 | server_side | 统称为新模式 |
- Histogram指标分位值预计算,节约存储、降低服务端压力(高基数指标往往来自histogram的海量bucket,同时除了算分位值以外的应用如分布情况又较少)
- 基础资源指标预计算,counterTogauge 简化最终查看的表达式
- 容器基础资源/k8s资源指标和夜莺树绑定
- 通过抓取各个组件的/metrics接口获得prometheus的数据,ETL后push到夜莺
- 各个采集项目有metirc和tag的白名单过滤
cadvisor
数据需要hold点做计算比率类指标,多用在百分比的情况,其余不需要counter
类型将有夜莺agent转换为gauge
型,即数值已经转为rate
了 ,所有counter
类型metric_name 加_rate
后缀- 指标说明在
metrics-detail
文件夹里 - k8s yaml配置在
k8s-config
中 - 服务组件监控时多实例问题:用户无需关心,k8s-mon自动发现并采集
- 采集每node上的
kube-proxy
kubelet-node
指标时支持并发数配置和静态分片 - 服务组件采集时会添加
func_name
标签作为区分具体组件任务,类似prometheus
的job
标签 - 基础指标添加
node_ip
,node_name
作为宿主机标识标签 - ksm指标没有nid的默认上报到服务节点
server_side_nid
,例如kube_node_status_allocatable_cpu_cores
这种共享指标 - 服务组件采集预聚合了一些指标,包括 分位值、平均值、成功率,对应文档在
metrics-detail/preaggregation.md
- 服务组件采集了对应golang 进程的指标 包括 内存、goroutine等 ,对应文档在
metrics-detail/process-resource.md
- 一般来说在k8s集群汇总我们关注一下4类指标
指标类型 | 采集源 | 应用举例 | 部署方式 |
---|---|---|---|
容器基础资源指标 | kubelet 内置cadvisor | 查看容器cpu、mem等 | k8s daemonset |
k8s资源指标 | kube-stats-metrics (简称ksm) | 查看pod状态、查看deployment信息等 | k8s deployment (需要提前部署ksm) |
k8s服务组件指标 | 各个服务组件的metrics接口(多实例自动发现) apiserver kube-controller-manager kube-scheduler etcd coredns kube-proxy kubelet-node |
查看请求延迟/QPS等 | 和ksm同一套代码,部署在 k8s deployment |
业务指标(暂不支持) | pod暴露的metrics接口 | - | - |
- 每种项目配置了相关配置段才会开启,如果不想采集某类指标可以去掉其配置
- 每种项目由
user_specified
配置是否采用用户指定的地址,用来处理有些服务组件以裸进程形式部署无法从内部发现的case - 当
user_specified:true
时,对应的addrs
为采集地址url列表 - 当
user_specified:false
时,则认为由内置的代码来进行动态发现,需要配置好对应的port
schema
metrics_path
等信息
采集类型 | 采集地址说明 | 配置/发现说明 |
---|---|---|
容器基础资源指标 kubelet-cadvisor | kubelet 在node上listen分两种情况: listen 0.0.0.0 listen机器内网ip |
默认为k8s-mon 自动根据配置的port 找到对应的地址 |
k8s资源指标 kube-stats-metrics | 默认为通过coredns 访问service http://kube-state-metrics.kube-system:8080/metrics |
同时支持指定 |
k8s服务组件指标(master侧) apiserver kube-controller-manager kube-scheduler etcd coredns |
需要注意这些组件的部署方式 : 部署在pod 中 以裸进程部署 |
k8s-mon 默认认这些组件部署在pod中,通过getpod获取地址列表 |
k8s服务组件指标(每node部署) kube-proxy kubelet-node |
需要注意这些组件的部署方式 : 部署在pod 中 以裸进程部署 |
k8s-mon 默认认这些组件在每个node都可以以ip:port/metrics 访问到,通过getnode获取internal ip ,对应的服务需要listen 内网ip或0.0.0.0 |
业务指标(暂不支持) | pod暴露的metrics接口 | - |
准备k8s环境 ,确保每个node节点部署夜莺agent
n9e-agent
# 创建namespace kube-admin
kubectl create ns kube-admin
# 创建访问etcd所需secret,在master上执行(不采集etcd则不需要)
# 注意如果 不采集etcd,没有创建对应的证书(如k8s使用公有云托管的),默认 deployment中挂载证书那几行是注释掉的,开启etcd采集再打开
# etcd证书信息依据自己环境替换即可
kubectl create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key --from-file=/etc/kubernetes/pki/etcd/ca.crt -n kube-admin
直接使用公共源的镜像
# 公共源使用阿里云的
# registry.cn-beijing.aliyuncs.com/n9e/k8s-mon:v1
或者自己下载代码,打镜像
mkdir -pv $GOPATH/github.com/n9e
cd $GOPATH/github.com/n9e
git clone https://github.com/n9e/k8s-mon
# 使用docker 命令,或者ci工具,将镜像同步到仓库中
# 如需修改镜像名字,需要同步修改daemonset 和deployment yaml文件中的image字段
# 镜像需要同步到所有node,最好上传到仓库中
cd k8s-mon && docker build -t k8s-mon:v1 .
修改对接夜莺nid标签的名字
- 对应配置为配置文件中的
n9e_nid_label_name
- 默认为:
N9E_NID
,与之前k8s-mon采集cadvisor指标要求容器环境变量名一致 - 如需修改则需要改
k8s-config/configMap_deployment.yaml
和k8s-config/configMap_daemonset.yaml
中的n9e_nid_label_name
字段
pod yaml文件中传入上述 nid标签,例如:
N9E_NID
- 举例:deployment中定义pod的
N9E_NID
label,假设test-server01这个模块对应的服务树节点nid为5 - 后续该pod的容器的基础指标出现在nid=5的节点下: 如 cpu.user
- 后续该pod的k8s的基础指标出现在nid=5的节点下: 如 kube_deployment_status_replicas_available
- 其余自定义标签不采集,如:
region: A
cluster: B
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-server01-deployment
labels:
app: test-server01
# 这里表示此deployment的nid为5
N9E_NID: "5"
spec:
replicas: 1
selector:
matchLabels:
app: test-server01
template:
metadata:
labels:
app: test-server01
region: A
cluster: B
# 这里表示此deployment启动的容器nid为5
N9E_NID: "5"
服务组件监控需要指定server_side_nid
- 修改
k8s-config/configMap_deployment.yaml
将 server_side_nid: 字段改为指定的服务组件监控叶子节点的nid - 举例:server_side_nid: "6":代表6为k8s集群的服务树叶子节点,k8s控制平面的指标都会上报到这里
k8s服务组件指标(master侧) 如果不是部署在pod中,需要指定采集地址
- apiserver 、kube-scheduler、coredns、etcd等
k8s-mon
默认认这些组件部署在pod中,通过getpod获取地址列表- 如果不是部署在pod中,需要指定采集地址(将user_specified设置为true,并指定addr,其余配置保持不变即可),举例如下
apiserver:
user_specified: true
addrs:
- "https://1.1.1.1:6443/metrics"
- "https://2.2.2.2:6443/metrics"
如果不想采集某类指标可以去掉其配置
- 举例:不想采集
apiserver
的指标 - 则去掉/注释掉
k8s-config/configMap_deployment.yaml
中apiserver
段即可 - deployment中需要采集每node的
kube-proxy
和kubelet
(node量大的时候)不需要可以去掉
每node的
kube-proxy
和kubelet
静态分片采集
- 默认采集所有node的指标,在node数量大时会导致性能问题,则需要开启分片采集
- 举例有1万个node需要采集kube-proxy,则部署3个k8s-mon,配置值开启kube-proxy段
- 其中
hash_mod_num
代表总分片数量hash_mod_shard
代表本实例取模后的index(取值范围是0 ~ hash_mod_num-1) - 那么这三个实例则会将1万个node分片采集
# 实例1
kube_proxy:
hash_mod_num: 3
hash_mod_shard: 0
# 实例2
kube_proxy:
hash_mod_num: 3
hash_mod_shard: 1
# 实例3
kube_proxy:
hash_mod_num: 3
hash_mod_shard: 2
想给某个采集项指定采集地址
- 举例:想设置kube-scheduler的采集地址为
https://1.1.1.1:1234/metrics
和https://2.2.2.2:1234/metrics
- 则修改
k8s-config/configMap_deployment.yaml
中user_specified
和addrs
即可
kube_scheduler:
user_specified: true
addrs:
- "https://1.1.1.1:1234/metrics"
- "https://2.2.2.2:1234/metrics"
如需给采集的指标添加自定义tag
- 则修改
k8s-config/configMap_deployment.yaml
k8s-config/configMap_daemonset.yaml
中的append_tags
字段即可
append_tags:
key1: value1
key2: value2
如需修改采集间隔
- 修改
k8s-config/configMap_deployment.yaml
k8s-config/configMap_daemonset.yaml
中的collect_step
字段
如需修改某个项目的采集并发
- 修改
k8s-config/configMap_deployment.yaml
中的指定项目的concurrency_limit
字段,默认10
如需服务组件采集多实例时的特征标签
- 修改
k8s-config/configMap_deployment.yaml
中的multi_server_instance_unique_label
字段
调整日志级别
- 修改
k8s-config/deployment.yaml
中的 spec.containers.command 加上--log.level=debug
即可看到debug日志,日志样例如下 - 单项数据处理耗时
level=debug ts=2021-02-24T15:47:31.810+08:00 caller=kube_controller_manager.go:180 msg=DoCollectSuccessfullyReadyToPush funcName=kube-controller-manager metrics_num=621 time_took_seconds=0.307592776
- 单项推送耗时
level=debug ts=2021-02-24T15:47:31.863+08:00 caller=push.go:25 msg=PushWorkSuccess funcName=kube-controller-manager url=http://localhost:2080/api/collector/push metricsNum=621 time_took_seconds=0.053355322
- 获取pod耗时
level=debug ts=2021-02-24T15:50:01.523+08:00 caller=get_pod.go:99 msg=server_pod_ips_result num_kubeSchedulerIps=1 num_kubeControllerIps=1 num_apiServerIps=1 num_coreDnsIps=2 num_kubeProxyIps=2 num_etcdIps=1 time_took_seconds=0.020384107
启动ksm服务(部署在kube-system namespace中 ,需要采集才启动)
kubectl apply -f k8s-config/kube-stats-metrics
启动k8s-mon daemonset 和deployment (部署在kube-admin namespace中,按需启动daemonset 和deployment)
kubectl apply -f k8s-config
查看日志
kubectl logs -l app=k8s-mon-deployment -n kube-admin -f
kubectl logs -l app=k8s-mon-daemonset -n kube-admin -f
即时看图查看指标
# 浏览器访问及时看图path: http://<n9e_addr>/mon/dashboard?nid=<nid>
导入大盘图
# 大盘图在 metrics-detail/夜莺大盘-xxxjson中
# 将三个大盘json文件放到夜莺服务端机器 <n9e_home>/etc/screen 下
# 或者 克隆夜莺3.5+代码,内置大盘图json在 etc/screen 下
# 刷新页面,在对应的节点选择导入内置大盘即可
- kubelet 内置了cadvisor作为容器采集 ,具体文档可以看这里 cadvisor housekeeping配置
- 同时kubelet 命令行透传了相关配置
--housekeeping-interval duration Default: `10s`
模式采集是10秒,所以在默认配置
下无论prometheus还是k8s-mon采集间隔不应低于10s- cpu 和mem指标需要pod设置limit,如果没有limit则某些指标会缺失
- 建议保持默认的metrics名单,metrics_white_list为空则全采集
- tag白名单可按需配置
- 提供基于 histogram的分位值,所有的_bucket指标已经被过滤掉了,提供分位值
quantile
50 90 95 99 - 线性插值法计算,和prometheus大致相同 :prometheus先算rate再算sum,k8s-mon是先算sum再算rate
- 举例
coredns_dns_request_duration_seconds_bucket --> coredns_dns_request_duration_seconds_quantile
代表coredns 解析平均延迟分位值 - 同时提供平均值 举例
coredns_dns_request_duration_seconds_bucket -->coredns_dns_request_duration_seconds_avg
作为Nightingale的插件,用于收集docker容器的监控指标
$ mkdir -p $GOPATH/src/github.com/n9e
$ cd $GOPATH/src/github.com/n9e
$ git clone https://github.com/n9e/k8s-mon.git
$ cd k8s-mon
$ make
$ ./k8s-mon
- docker容器所在宿主机已安装并启动了cadvisor
- docker容器的环境变量中包含 N9E_NID ,N9E_NID 的内容为夜莺服务树节点id,如果设置 N9E_NID = 1,则到节点id为1的节点下,就可以容器的监控指标
- 将 k8s-mon、k8s-mon.yml 分发到容器所在的宿主机上
- 到宿主机所属节点配置插件采集
-
CPU
cpu.user
cpu.sys
cpu.idle
cpu.util
cpu.periods
cpu.throttled_periods
cpu.throttled_time -
内存
mem.bytes.total
mem.bytes.used
mem.bytes.used.percent
mem.bytes.cached
mem.bytes.rss
mem.bytes.swap -
磁盘
disk.io.read.bytes
disk.io.write.bytes
disk.bytes.total
disk.bytes.used
disk.bytes.used.percent -
网络
net.sockets.tcp.timewait
net.in.bits
net.in.pps
net.in.errs
net.in.dropped
net.out.bits
net.out.pps
net.out.errs
net.out.dropped
net.tcp.established -
系统
sys.ps.process.used
sys.ps.thread.used
sys.fd.count.used
sys.socket.count.used
sys.restart.count