基于DaemonSet的Process Exporter監(jiān)控實(shí)踐指南
導(dǎo)語
作為一名Kubernetes管理員,你是否經(jīng)歷過:
- 服務(wù)正常卻找不到CPU飆升的根本原因?
- 容器進(jìn)程異常但無法快速定位根源?
- 缺乏完整的進(jìn)程級(jí)監(jiān)控體系導(dǎo)致故障排查困難?
本文將帶你掌握 Process Exporter 的完整使用鏈路,涵蓋基礎(chǔ)部署、Prometheus集成、Grafana可視化及告警規(guī)則配置,即使是新手也能輕松上手!
一、初識(shí)Process Exporter
1.什么是Process Exporter?
- 官方出品:Prometheus生態(tài)標(biāo)準(zhǔn)exporter
- 輕量級(jí):鏡像僅15MB,支持容器/宿主機(jī)進(jìn)程監(jiān)控
- 核心能力:
? 進(jìn)程CPU/內(nèi)存占用? 文件描述符數(shù)量? 線程數(shù)與運(yùn)行時(shí)長? 支持正則表達(dá)式過濾進(jìn)程
2.為什么必須用它?
對比項(xiàng) | Node Exporter | Process Exporter |
監(jiān)控粒度 | 節(jié)點(diǎn)級(jí)別 | 進(jìn)程級(jí)別(精確到PID) |
核心指標(biāo) | CPU/內(nèi)存/磁盤IO | CPU/內(nèi)存/線程/文件描述符 |
典型場景 | 整體資源負(fù)載分析 | 異常進(jìn)程根因定位 |
典型業(yè)務(wù)價(jià)值:
- 識(shí)別惡意進(jìn)程占用資源
- 監(jiān)控Java應(yīng)用GC行為
- 分析MySQL連接池耗盡原因
3. 部署控制器選擇
- 全節(jié)點(diǎn)覆蓋:確保每個(gè)Worker節(jié)點(diǎn)運(yùn)行監(jiān)控實(shí)例
- 混合監(jiān)控:同時(shí)采集容器進(jìn)程和宿主機(jī)關(guān)鍵服務(wù)(如kubelet、sshd)
- 資源占用優(yōu)化:避免Deployment模式下多副本的資源浪費(fèi)
二、快速部署Process Exporter
1.架構(gòu)設(shè)計(jì)圖
2.部署YAML模板
# 1. 創(chuàng)建RBAC權(quán)限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: process-exporter
rules:
- apiGroups: [""]
resources: ["nodes/proxy"]
verbs: ["get", "list", "watch"]
---
# 2. 配置DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: process-exporter
namespace: monitoring
spec:
selector:
matchLabels:
app: process-exporter
template:
metadata:
labels:
app: process-exporter
spec:
hostPID: true # 共享宿主機(jī) PID 命名空間
hostNetwork: true # 可選:共享宿主機(jī)網(wǎng)絡(luò)命名空間
# 添加容忍規(guī)則
tolerations:
- operator: Exists # 容忍所有污點(diǎn)
containers:
- name: process-exporter
image: prometheus/process-exporter:v1.7.0
args:
- "-procfs=/host/proc" # 指定宿主機(jī) /proc 路徑
- "-config.path=/etc/process-exporter/config.yaml"
volumeMounts:
- name: config-volume
mountPath: /etc/process-exporter/config.yaml # 掛載為文件
subPath: config.yaml # 指定子路徑
- name: proc # 掛載宿主機(jī)的 /proc
mountPath: /host/proc
readOnly: true
ports:
- containerPort: 9256
resources:
limits:
cpu: "200m"
memory: "256Mi"
securityContext:
capabilities:
add:
- SYS_PTRACE # 允許追蹤進(jìn)程
- SYS_ADMIN # 可選:訪問宿主機(jī)資源
volumes:
- name: config-volume
configMap:
name: process-exporter-config
items: # 明確指定 ConfigMap 的鍵和路徑
- key: config.yaml # ConfigMap 中的鍵名
path: config.yaml # 掛載到容器內(nèi)的文件名
- name: proc
hostPath:
path: /proc # 宿主機(jī) /proc 目錄
---
apiVersion: v1
kind: Service
metadata:
name: process-exporter
namespace: monitoring
labels:
app: process-exporter # 必須與 ServiceMonitor 的 selector 匹配
spec:
ports:
- port: 9256
targetPort: 9256
protocol: TCP
name: http # 端口名稱必須與 ServiceMonitor 的 endpoints.port 匹配
selector:
app: process-exporter # 關(guān)聯(lián)到 Deployment 的 Pod 標(biāo)簽
3.configmap配置
apiVersion: v1
kind: ConfigMap
metadata:
name: process-exporter-config
namespace: monitoring
data:
config.yaml: |
process_names:
- name: "{{.Comm}}" # 進(jìn)程組名稱模板(使用進(jìn)程名作為標(biāo)簽)
cmdline: # 匹配命令行參數(shù)的正則表達(dá)式
- '.+' # 匹配所有進(jìn)程
4.驗(yàn)證部署
# 查看Pod狀態(tài)
kubectl get pods -n monitoring -l app=process-exporter
# 測試數(shù)據(jù)采集
kubectl exec -it <pod-name> -- curl http://localhost:9103/metrics | grep java_process_cpu_seconds_total
三、與Prometheus監(jiān)控體系集成
1.Prometheus Operator自動(dòng)接入
步驟1:單獨(dú)創(chuàng)建ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: process-exporter
namespace: monitoring
spec:
endpoints:
- port: http
interval: 15s
path: /metrics
relabelings:
- sourceLabels: [__meta_kubernetes_pod_node_name]
targetLabel: node # 自動(dòng)添加節(jié)點(diǎn)標(biāo)簽
namespaceSelector:
matchNames:
- monitoring # 監(jiān)控的命名空間
selector:
matchLabels:
app: process-exporter
步驟2:自動(dòng)化數(shù)據(jù)同步
Operator會(huì)自動(dòng)完成以下操作:
- 創(chuàng)建TargetGroup
- 注冊到Prometheus Server
- 自動(dòng)生成Recording Rules
2.Grafana看板和指標(biāo)
(1)關(guān)鍵指標(biāo)
在實(shí)際監(jiān)控進(jìn)程時(shí),主要使用的指標(biāo)就是cpu和內(nèi)存。
- process-exporter中進(jìn)程的指標(biāo)以namedprocess_namegroup開頭:
- namedprocess_namegroup_cpu_seconds_total:cpu使用時(shí)間,通過mode區(qū)分是user還是system
- namedprocess_namegroup_memory_bytes:內(nèi)存占用,通過memtype區(qū)分不同的占用類型
- namedprocess_namegroup_num_threads:線程數(shù)
- namedprocess_namegroup_open_filedesc:打開的文件句柄數(shù)
- namedprocess_namegroup_read_bytes_total:進(jìn)程讀取的字節(jié)數(shù)
- namedprocess_namegroup_thread_context_switches_total:線程上下文切換統(tǒng)計(jì)
- namedprocess_namegroup_thread_count:線程數(shù)量統(tǒng)計(jì)
- namedprocess_namegroup_thread_cpu_seconds_total:線程的cpu使用時(shí)間
- namedprocess_namegroup_thread_io_bytes_total:線程的io
(2)cpu相關(guān)
cpu是我們最經(jīng)常關(guān)注的指標(biāo),如果使用node-exporter采集節(jié)點(diǎn)的指標(biāo)數(shù)據(jù),可以得到機(jī)器的cpu占比。
而使用process-exporter采集的是進(jìn)程的指標(biāo),具體來說就是采集/proc/pid/stat中與cpu時(shí)間有關(guān)的數(shù)據(jù):
- 第14個(gè)字段:utime,進(jìn)程在用戶態(tài)運(yùn)行的時(shí)間,單位為jiffies
- 第15個(gè)字段:stime,進(jìn)程在內(nèi)核態(tài)運(yùn)行的時(shí)間,單位為jiffies
- 第16個(gè)字段:cutime,子進(jìn)程在用戶態(tài)運(yùn)行的時(shí)間,單位為jiffies
- 第17個(gè)字段:cstime,子進(jìn)程在內(nèi)核態(tài)運(yùn)行的時(shí)間,單位為jiffies
那么通過上述值就可以得到進(jìn)程的單核CPU占比:
- 進(jìn)程的單核CPU占比=(utime+stime+cutime+cstime)/時(shí)間差
- 進(jìn)程的單核內(nèi)核態(tài)CPU占比=(stime+cstime)/時(shí)間差
因此,進(jìn)程的單核CPU占比的promsql語句為increase(namedprocess_namegroup_cpu_seconds_total{mode="user",groupname="procname"}[30s])*100/30,單核內(nèi)核態(tài)CPU占比的promsql語句為increase(namedprocess_namegroup_cpu_seconds_total{mode="system",groupname="procname"}[30s])*100/30。
注意:實(shí)測發(fā)現(xiàn),process-exporter獲取的數(shù)據(jù)與/proc/pid/stat中的有一定差異,需要進(jìn)一步看下。
(3)memory
process-exporter采集內(nèi)存的指標(biāo)時(shí)將內(nèi)存分成5種類型:
- resident:進(jìn)程實(shí)際占用的內(nèi)存大小,包括共享庫的內(nèi)存空間,可以從/proc/pid/status中的VmRSS獲取
- proportionalResident:與resident相比,共享庫的內(nèi)存空間會(huì)根據(jù)進(jìn)程數(shù)量平均分配
- swapped:交換空間,系統(tǒng)物理內(nèi)存不足時(shí),會(huì)將不常用的內(nèi)存頁放到硬盤的交換空間,可以從/proc/pid/status中的VmSwap獲取
- proportionalSwapped:將可能被交換的內(nèi)存頁按照可能性進(jìn)行加權(quán)平均
- virtual:虛擬內(nèi)存,描述了進(jìn)程運(yùn)行時(shí)所需要的總內(nèi)存大小,包括哪些還沒有實(shí)際加載到內(nèi)存中的代碼和數(shù)據(jù),可以從/proc/pid/status中的VmSize獲取
對于一般的程序來說,重點(diǎn)關(guān)注的肯定是實(shí)際內(nèi)存,也就是resident和virtual,分別表示實(shí)際在內(nèi)存中占用的空間和應(yīng)該占用的總空間
(4)看板
process-exporter基于上述指標(biāo)提供了grafana的面板可以直接導(dǎo)入:https://grafana.com/grafana/dashboards/249-named-processes/
可以看到,面板中的cpu和讀寫是直接基于指標(biāo)和rate函數(shù)得到的,內(nèi)存則是直接基于指標(biāo)而來的。
四、配置說明
proces-exporter的配置包括兩部分的配置項(xiàng),一個(gè)是process-exporter的一些參數(shù)控制,另一個(gè)是進(jìn)程信息的配置。
一般來說,exporter都會(huì)有幾部分的參數(shù)控制采集:
- config/config.path:指定配置文件路徑
- web.listen-address:指定監(jiān)聽端口,通常都會(huì)有默認(rèn)的端口,prometheus就是訪問該端口獲取指標(biāo)數(shù)據(jù)
- web.telemetry-path:指標(biāo)數(shù)據(jù)的url,通常都是/metrics
除了有以上配置項(xiàng)之外,process-exporter還有其他特有的配置項(xiàng):
- children:如果某個(gè)進(jìn)程被采集,那么它的子進(jìn)程也屬于該組
- namemapping:名稱映射,
- procfs:proc文件系統(tǒng)的路徑,默認(rèn)是/proc
- procnames:需要采集的進(jìn)程名列表
- threads:是否采集線程,默認(rèn)為是
基于性能的考慮,process-exporter只能對事先配置的進(jìn)程進(jìn)行指標(biāo)采集,因此,需要對進(jìn)程進(jìn)行過濾,只采集需要的進(jìn)程的指標(biāo)。
在過濾進(jìn)程時(shí),會(huì)將進(jìn)程進(jìn)行分組,因此,就會(huì)有分組的名稱,以及將進(jìn)程放到分組的規(guī)則。例如,如果使用deb/rpm安裝process-exporter時(shí),默認(rèn)的配置文件是:
process_names:
- name: "{{.Comm}}"
cmdline:
- '.+'
process_names是個(gè)數(shù)組,每個(gè)成員表示一個(gè)分組。
name是分組的名稱,這里使用模版。cmdline用于對分組中的進(jìn)程進(jìn)行過濾,這里的正則表達(dá)式就表示過濾所有進(jìn)程。
因此,上述配置文件的含義是:采集所有進(jìn)程的指標(biāo)數(shù)據(jù),當(dāng)遍歷到某個(gè)進(jìn)程時(shí),獲取該進(jìn)程的進(jìn)程名,然后放到進(jìn)程名對應(yīng)的分組。
name字段可以使用固定的字符串,也可以使用以下模版:
- {{.Comm}}:進(jìn)程名
- {{.ExeBase}}:可執(zhí)行文件的文件名,與進(jìn)程的區(qū)別是,進(jìn)程名有長度15的限制
- {{.ExeFull}}:可執(zhí)行文件的全路徑
- {{.Username}}:進(jìn)程的有效用戶名
- {{.Matches}}:用正則匹配cmdline等字段時(shí)得到的匹配項(xiàng)的map,例如下面的Cfgfile
- {{.PID}}:pid,使用pid表示這個(gè)組只會(huì)有這一個(gè)進(jìn)程
- {{.StartTime}}:進(jìn)程的起始時(shí)間
- {{.Cgroups}}:進(jìn)程的cgoup,可以用于區(qū)分不同的容器
進(jìn)行分組進(jìn)程過濾除了使用cmdline字段,還可以使用comm和exe,分別表示進(jìn)程名和二進(jìn)制路徑,并且遵循以下規(guī)則:
- 如果使用了多個(gè)字段,則必須都匹配,例如,如果既使用了comm,又使用了exe,兩個(gè)過濾必須都滿足
- 對于comm和exe,它們是字符串?dāng)?shù)組,并且是OR的關(guān)系
- 對于cmdline,則是正則表達(dá)式數(shù)組,并且是AND的關(guān)系
例如:
process_names:
# 進(jìn)程名過濾,超過15個(gè)字符會(huì)被截?cái)? - comm:
- bash
# argv[0],如果開頭不是/,說明匹配進(jìn)程名
# 如果開頭是/,則需要使用二進(jìn)制路徑全匹配
- exe:
- postgres
- /usr/local/bin/prometheus
# 如果使用多個(gè)字段進(jìn)行匹配,則需要都匹配
- name: "{{.ExeFull}}:{{.Matches.Cfgfile}}"
exe:
- /usr/local/bin/process-exporter
cmdline:
- -config.path\s+(?P<Cfgfile>\S+)
# 監(jiān)控NVIDIA GPU進(jìn)程
filter:
- name: gpu-process
pattern: "^nvidia-smi"
env: ["NVIDIA_VISIBLE_DEVICES=all"]
五、結(jié)語
通過DaemonSet部署的Process Exporter,配合Prometheus Operator和Grafana看板,可構(gòu)建覆蓋 容器進(jìn)程-宿主機(jī)服務(wù)-硬件資源 的全維度監(jiān)控體系。建議按照以下步驟落地:
- 分階段實(shí)施:從測試環(huán)境到生產(chǎn)逐步推進(jìn)
- 制定監(jiān)控SLA:明確不同級(jí)別進(jìn)程的監(jiān)控指標(biāo)閾值
- 定期演練:模擬進(jìn)程異常驗(yàn)證告警有效性
延伸學(xué)習(xí)
- 官方文檔:https://process_exporter.readthedocs.io
- Kubernetes監(jiān)控白皮書(https://example.com/k8s-monitoring-whitepaper)