目录
一、安装和配置 node-exporter
1.1 node-exporter介绍?
1.2 安装 node-exporter
二、Prometheus server 安装和配置
2.1 创建 sa 账号,对 sa 做 rbac 授权
2.2 创建 prometheus 数据存储目录
2.3 安装 Prometheus server 服务
(1)创建一个 configmap 存储卷,用来存放 prometheus 配置信息
(2)通过 deployment 部署 prometheus
(3)给 prometheus pod 创建一个 service
(4)Prometheus 热加载
本此安装 Prometheus server 所用资料文件下载地址:https://download.csdn.net/download/weixin_46560589/87378316
一、安装和配置 node-exporter
机器规划:
我的项目环境使用的 k8s-v1.23 集群是一个 master 节点和两个 node 节点:
- master1 节点的机器 ip 是 192.168.78.143,主机名是 k8s-master1
- node1 节点的机器 ip 是 192.168.78.144,主机名是 k8s-node1
- node2 节点的机器 ip 是 192.168.78.145,主机名是 k8s-node2
1.1 node-exporter介绍?
node-exporter 可以采集机器(物理机、虚拟机、云主机等)的监控指标数据,能够采集到的指标包括 CPU、内存、磁盘、网络、文件数等信息。
1.2 安装 node-exporter
# 创建名称空间
[root@k8s-master1 ~]# kubectl create ns monitor-sa
# 把 node-exporter.tar.gz 镜像压缩包上传到 k8s 的各个节点,手动解压
[root@k8s-master1 ~]# docker load -i node-exporter.tar.gz
[root@k8s-node1 ~]# docker load -i node-exporter.tar.gz
[root@k8s-node2 ~]# docker load -i node-exporter.tar.gz
# 创建目录用来存放配置文件
[root@k8s-master1 ~]# mkdir prometheus
[root@k8s-master1 ~]# cd prometheus/
[root@k8s-master1 prometheus]# vim node-export.yaml
apiVersion: apps/v1
kind: DaemonSet # 可以保证 k8s 集群的每个节点都运行完全一样的 pod
metadata:
name: node-exporter
namespace: monitor-sa
labels:
name: node-exporter
spec:
selector:
matchLabels:
name: node-exporter
template:
metadata:
labels:
name: node-exporter
spec:
hostPID: true # hostNetwork、hostIPC、hostPID 都为 True 时,表示这个 Pod 里的所有容器,会直接使用宿主机的网络,直接与宿主机进行 IPC(进程间通信)通信,可以看到宿主机里正在运行的所有进程。加入了 hostNetwork:true 会直接将我们的宿主机的 9100 端口映射出来,从而不需要创建 service 在我们的宿主机上就会有一个 9100 的端口。
hostIPC: true
hostNetwork: true
containers:
- name: node-exporter
image: prom/node-exporter:v0.16.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9100
resources:
requests:
cpu: 0.15 # 这个容器运行至少需要 0.15 核 cpu
securityContext:
privileged: true # 开启特权模式
args:
- --path.procfs # 配置挂载宿主机(node 节点)的路径
- /host/proc
- --path.sysfs # 配置挂载宿主机(node 节点)的路径
- /host/sys
- --collector.filesystem.ignored-mount-points
- '"^/(sys|proc|dev|host|etc)($|/)"' # 通过正则表达式忽略某些文件系统挂载点的信息收集
volumeMounts: # 将主机 /dev、/proc、/sys 这些目录挂在到容器中,这是因为我们采集的很多节点数据都是通过这些文件来获取系统信息的
- name: dev
mountPath: /host/dev
- name: proc
mountPath: /host/proc
- name: sys
mountPath: /host/sys
- name: rootfs
mountPath: /rootfs
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
volumes:
- name: proc
hostPath:
path: /proc
- name: dev
hostPath:
path: /dev
- name: sys
hostPath:
path: /sys
- name: rootfs
hostPath:
path: /
[root@k8s-master1 prometheus]# kubectl apply -f node-export.yaml
daemonset.apps/node-exporter created
# 查看 node-exporter 是否部署成功
[root@k8s-master1 prometheus]# kubectl get pods -n monitor-sa
NAME READY STATUS RESTARTS AGE
node-exporter-98zvk 1/1 Running 0 8s
node-exporter-9qb2g 1/1 Running 0 8s
node-exporter-t7q4g 1/1 Running 0 8s
# 通过 node-exporter 采集数据。node-export 默认的监听端口是 9100,可以看到当前主机获取到的所有监控数据:
[root@k8s-master1 prometheus]# curl http://192.168.78.143:9100/metrics
# 显示 192.168.78.143 主机 cpu 的使用情况
[root@k8s-master1 prometheus]# curl http://192.168.78.143:9100/metrics | grep node_cpu_seconds
-
#HELP:解释当前指标的含义,上面表示在每种模式下 node 节点的 cpu 花费的时间,以 s 为单位。
- #TYPE:说明当前指标的数据类型,上面是 counter 类型。
- node_cpu_seconds_total{cpu="0",mode="idle"} :cpu0 上 idle 进程占用 CPU 的总时间,CPU 占用时间是一个只增不减的度量指标,从类型中也可以看出 node_cpu 的数据类型是 counter(计数器)。
- counter 计数器:只是采集递增的指标。
[root@k8s-master1 prometheus]# curl http://192.168.78.143:9100/metrics | grep node_load
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 66923 100 66923 0 0 6376k 0 --:--:-- --:--:-- --:--:-- 7261k
# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 0.3
# HELP node_load15 15m load average.
# TYPE node_load15 gauge
node_load15 0.32
# HELP node_load5 5m load average.
# TYPE node_load5 gauge
node_load5 0.33
node_load1 该指标反映了当前主机在最近一分钟以内的负载情况,系统的负载情况会随系统资源的使用而变化,因此 node_load1 反映的是当前状态,数据可能增加也可能减少,从注释中可以看出当前指标类型为 gauge(标准尺寸)。
gauge 标准尺寸:统计的指标可增加可减少。
二、Prometheus server 安装和配置
2.1 创建 sa 账号,对 sa 做 rbac 授权
# 创建一个 sa 账号 monitor
[root@k8s-master1 prometheus]# kubectl create serviceaccount monitor -n monitor-sa
# 把 sa 账号 monitor 通过 clusterrolebing 绑定到 clusterrole 上
[root@k8s-master1 prometheus]# kubectl create clusterrolebinding monitor-clusterrolebinding -n monitor-sa --clusterrole=cluster-admin --serviceaccount=monitor-sa:monitor
2.2 创建 prometheus 数据存储目录
# 在 k8s 集群的 node1 节点上创建数据存储目录
[root@k8s-node1 ~]# mkdir /data
[root@k8s-node1 ~]# chmod 777 /data/
2.3 安装 Prometheus server 服务
-
(1)创建一个 configmap 存储卷,用来存放 prometheus 配置信息
[root@k8s-master1 prometheus]# vim prometheus-cfg.yaml
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
app: prometheus
name: prometheus-config
namespace: monitor-sa
data:
prometheus.yml: |
global:
scrape_interval: 15s # 采集目标主机监控据的时间间隔
scrape_timeout: 10s # 数据采集超时时间,默认 10s
evaluation_interval: 1m # 触发告警检测的时间,默认是 1m
scrape_configs: # 配置数据源,称为 target,每个 target 用 job_name 命名。又分为静态配置和服务发现
- job_name: 'kubernetes-node' # 使用的是 k8s 的服务发现
kubernetes_sd_configs:
- role: node # 使用 node 角色,它使用默认的 kubelet 提供的 http 端口来发现集群中每个 node 节点
relabel_configs: # 重新标记
- source_labels: [__address__] # 配置的原始标签,匹配地址
regex: '(.*):10250' # 匹配带有 10250 端口的 url
replacement: '${1}:9100' # 把匹配到的 ip:10250 的 ip 保留
target_label: __address__ # 新生成的 url 是 ${1} 获取到的 ip:9100
action: replace
- action: labelmap
regex: __meta_kubernetes_node_label_(.+) # 匹配到下面正则表达式的标签会被保留,如果不做 regex 正则的话,默认只是会显示 instance 标签
- job_name: 'kubernetes-node-cadvisor'# 抓取 cAdvisor 数据,是获取 kubelet上/metrics/cadvisor 接口数据来获取容器的资源使用情况
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- action: labelmap # 把匹配到的标签保留
regex: __meta_kubernetes_node_label_(.+) # 保留匹配到的具有__meta_kubernetes_node_label 的标签
- target_label: __address__ # 获取到的地址:__address__="192.168.78.143:10250"
replacement: kubernetes.default.svc:443 # 把获取到的地址替换成新的地址kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]# 把原始标签中__meta_kubernetes_node_name 值匹配到
regex: (.+)
target_label: __metrics_path__ # 获取 __metrics_path__ 对应的值
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor # 把 metrics 替换成新的值api/v1/nodes/xianchaomaster1/proxy/metrics/cadvisor;${1} 是 __meta_kubernetes_node_name 获取到的值;新的 url 就是 https://kubernetes.default.svc:443/api/v1/nodes/xianchaomaster1/proxy/metrics/cadvisor
- job_name: 'kubernetes-apiserver'
kubernetes_sd_configs:
- role: endpoints # 使用 k8s 中的 endpoint 服务发现,采集 apiserver 6443 端口获取到的数据
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] # endpoint 这个对象的名称空间、服务名、端口名称
action: keep # 采集满足条件的实例,其他实例不采集
regex: default;kubernetes;https # 正则匹配到的默认空间下的 service 名字是kubernetes,协议是 https 的 endpoint 类型保留下来
- job_name: 'kubernetes-service-endpoints'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true # 重新打标仅抓取到的具有 "prometheus.io/scrape: true" 的 annotation 的端点,意思是说如果某个 service 具有 prometheus.io/scrape = true annotation 声明则抓取,annotation 本身也是键值结构,所以这里的源标签设置为键,而 regex 设置值true,当值匹配到 regex 设定的内容时则执行 keep 动作也就是保留,其余则丢弃。
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?) # 重新设置 scheme,匹配源标签__meta_kubernetes_service_annotation_prometheus_io_scheme 也就是 prometheus.io/scheme annotation,如果源标签的值匹配到 regex,则把值替换为 __scheme__ 对应的值。
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+) # 应用中自定义暴露的指标,也许你暴露的 API 接口不是/metrics 这个路径,那么你可以在这个 POD 对应的 service 中做一个 "prometheus.io/path = /mymetrics" 声明,上面的意思就是把你声明的这个路径赋值给 __metrics_path__,其实就是让 prometheus来获取自定义应用暴露的 metrices 的具体路径,不过这里写的要和 service 中做好约定,如果 service 中这样写 prometheus.io/app-metrics-path: '/metrics' 那么你这里就要 __meta_kubernetes_service_annotation_prometheus_io_app_metrics_path 这样写。
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2 # 暴露自定义的应用的端口,就是把地址和你在 service 中定义的 "prometheus.io/port = <port>" 声明做一个拼接,然后赋值给 __address__,这样 prometheus 就能获取自定义应用的端口,然后通过这个端口再结合 __metrics_path__来获取指标,如果 __metrics_path__值不是默认的 /metrics 那么就要使用上面的标签替换来获取真正暴露的具体路径。
- action: labelmap # 保留下面匹配到的标签
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace # 替换 __meta_kubernetes_namespace 变成kubernetes_namespace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name
# 更新 configmap 资源
[root@k8s-master1 prometheus]# kubectl apply -f prometheus-cfg.yaml
-
(2)通过 deployment 部署 prometheus
# 安装 prometheus 需要的镜像 prometheus-2-2-1.tar.gz,上传到 k8s 的工作节点 node1、node2 上,手动解压:
[root@k8s-node1 ~]# docker load -i prometheus-2-2-1.tar.gz
[root@k8s-node2 ~]# docker load -i prometheus-2-2-1.tar.gz
[root@k8s-master1 prometheus]# vim prometheus-deploy.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-server
namespace: monitor-sa
labels:
app: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
component: server
#matchExpressions:
#- {key: app, operator: In, values: [prometheus]}
#- {key: component, operator: In, values: [server]}
template:
metadata:
labels:
app: prometheus
component: server
annotations:
prometheus.io/scrape: 'false'
spec:
nodeName: k8s-node1
serviceAccountName: monitor
containers:
- name: prometheus
image: prom/prometheus:v2.2.1
imagePullPolicy: IfNotPresent
command:
- prometheus
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus # 旧数据存储目录
- --storage.tsdb.retention=720h # 何时删除旧数据,默认为 15 天
- --web.enable-lifecycle # 开启热加载
ports:
- containerPort: 9090
protocol: TCP
volumeMounts:
- mountPath: /etc/prometheus/prometheus.yml
name: prometheus-config
subPath: prometheus.yml
- mountPath: /prometheus/
name: prometheus-storage-volume
volumes:
- name: prometheus-config
configMap:
name: prometheus-config
items:
- key: prometheus.yml
path: prometheus.yml
mode: 0644
- name: prometheus-storage-volume
hostPath:
path: /data
type: Directory
# 通过 kubectl apply 更新 prometheus
[root@k8s-master1 prometheus]# kubectl apply -f prometheus-deploy.yaml
# 查看 prometheus 是否部署成功
[root@k8s-master1 prometheus]# kubectl get pods -n monitor-sa
NAME READY STATUS RESTARTS AGE
node-exporter-98zvk 1/1 Running 1 (140m ago) 3h6m
node-exporter-9qb2g 1/1 Running 1 (140m ago) 3h6m
node-exporter-t7q4g 1/1 Running 1 (140m ago) 3h6m
prometheus-server-74d945f7d5-zqpxv 1/1 Running 0 18s
注意:在上面的 prometheus-deploy.yaml 文件有个 nodeName 字段,这个就是用来指定创建的这个 prometheus 的 pod 调度到哪个节点上,我们这里让 nodeName=k8s-node1,也即是让 pod 调度到 k8s-node1 节点上,因为 k8s-node1 节点我们创建了数据目录 /data,所以大家记住:你在k8s 集群的哪个节点创建 /data,就让 pod 调度到哪个节点,nodeName 根据你们自己环境主机去修改即可。
-
(3)给 prometheus pod 创建一个 service
[root@k8s-master1 prometheus]# vim prometheus-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: monitor-sa
labels:
app: prometheus
spec:
type: NodePort
ports:
- port: 9090
targetPort: 9090
protocol: TCP
selector:
app: prometheus
component: server
# 通过 kubectl apply 更新 service
[root@k8s-master1 prometheus]# kubectl apply -f prometheus-svc.yaml
# 查看 service 在物理机映射的端口
[root@k8s-master1 prometheus]# kubectl get svc -n monitor-sa
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus NodePort 10.108.228.243 <none> 9090:30812/TCP 9s
通过上面可以看到 service 在宿主机上映射的端口是 30812,这样我们访问 k8s 集群的任意节点的主机 ip:30812,就可以访问到 prometheus 的 web ui 界面了。在浏览器输入如下地址:
http://192.168.78.143:30812
点击页面的 Status -> Targets,可看到如下,说明我们配置的服务发现可以正常采集数据:
-
(4)Prometheus 热加载
为了每次修改配置文件可以热加载 prometheus,也就是不停止 prometheus,就可以使配置生效,想要使配置生效可用如下热加载命令:
# 查看 prometheus 的 pod ip
[root@k8s-master1 prometheus]# kubectl get pods -n monitor-sa -o wide -l app=prometheus
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
prometheus-server-74d945f7d5-zqpxv 1/1 Running 0 24m 10.244.36.66 k8s-node1 <none> <none>
# 10.244.36.66 是 prometheus 的 pod 的 ip 地址
# 想要使配置生效可用如下命令热加载:
[root@k8s-master1 prometheus]# curl -X POST http://10.244.36.66:9090/-/reload
热加载速度可能比较慢,可以暴力重启 prometheus,如修改上面的 prometheus-cfg.yaml 文件之后,可执行如下强制删除:
kubectl delete -f prometheus-cfg.yaml
kubectl delete -f prometheus-deploy.yaml
# 然后再通过 apply 更新:
kubectl apply -f prometheus-cfg.yaml
kubectl apply -f prometheus-deploy.yaml
注意:生产环境中最好热加载,暴力删除可能造成监控数据的丢失!!!
上一篇文章:【Kubernetes 企业项目实战】02、基于 Prometheus 和 K8s 构建智能化监控告警系统(上)_Stars.Sky的博客-CSDN博客