kube-state-metrics是什么?

如需监控k8s比较全面的资源指标,需要在集群内安装相应的exports,例如:CAdvisor,kube-state-metrics

  • CAdvisor: 已集成在kubelet内,不需要单独安装,它可以收集集群内容器的cpu,内存等指标;

  • kube-state-metrics: kube-state-metrics可以轮询api-server,可以监听 add、delete、update等事件,如仅有CAdvisor这些基本指标去监控,维度还是不够的,例如:对Deployment,Pod,Daemonset,Cronjob等k8s资源对象并没有监控,例如:replace是多少?Pod当前状态(pending or running?),CAdvisor并没有对具体的资源对象就行监控,因此就需引用新的exports来暴漏监控指标,这个exports就是kube-state-metrics;

  • kube-state-metrics关注于获取k8s各种资源的最新状态,如deployment或者daemonset,之所以没有把kube-state-metrics纳入到metric-server的能力中,是因为它们的关注点本质上是不一样的。metric-server仅仅是获取、格式化现有数据,写入特定的存储,实质上是一个监控系统;而kube-state-metrics是将k8s的运行状况在内存中做了个快照,并且获取新的指标,但它没有能力导出这些指标。

kube-state-metrics部署

在k8s集群master节点上clone
git clone https://github.com/kubernetes/kube-state-metrics.git

切换clone下载目录
cd kube-state-metrics/

切换对应tag
git checkout v2.0.0   我这里版本较低,因为我的k8s是v1.18.6版本

切换到标准部署目录
cd examples/standard/

查看目录中部署描述文件
ls
cluster-role-binding.yaml  cluster-role.yaml  deployment.yaml  service-account.yaml  service.yaml

img

部署前修改部署描述文件

cat cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: 2.0.0
  name: kube-state-metrics
rules:
- apiGroups:
  - ""
  resources:
  - configmaps
  - secrets
  - nodes
  - pods
  - services
  - resourcequotas
  - replicationcontrollers
  - limitranges
  - persistentvolumeclaims
  - persistentvolumes
  - namespaces
  - endpoints
  verbs:
  - list
  - watch
- apiGroups:
  - apps
  resources:
  - statefulsets
  - daemonsets
  - deployments
  - replicasets
  verbs:
  - list
  - watch
- apiGroups:
  - batch
  resources:
  - cronjobs
  - jobs
  verbs:
  - list
  - watch
- apiGroups:
  - autoscaling
  resources:
  - horizontalpodautoscalers
  verbs:
  - list
  - watch
- apiGroups:
  - authentication.k8s.io
  resources:
  - tokenreviews
  verbs:
  - create
- apiGroups:
  - authorization.k8s.io
  resources:
  - subjectaccessreviews
  verbs:
  - create
- apiGroups:
  - policy
  resources:
  - poddisruptionbudgets
  verbs:
  - list
  - watch
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests
  verbs:
  - list
  - watch
- apiGroups:
  - storage.k8s.io
  resources:
  - storageclasses
  - volumeattachments
  verbs:
  - list
  - watch
- apiGroups:
  - admissionregistration.k8s.io
  resources:
  - mutatingwebhookconfigurations
  - validatingwebhookconfigurations
  verbs:
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - networkpolicies
  - ingresses
  verbs:
  - list
  - watch
- apiGroups:
  - coordination.k8s.io
  resources:
  - leases
  verbs:
  - list
  - watch
cat cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: 2.0.0
  name: kube-state-metrics
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kube-state-metrics
subjects:
- kind: ServiceAccount
  name: kube-state-metrics
  namespace: ops-monit   添加了一个命名空间
cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: 2.0.0
  name: kube-state-metrics
  namespace: ops-monit  修改命名空间
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: kube-state-metrics
  template:
    metadata:
      labels:
        app.kubernetes.io/name: kube-state-metrics
        app.kubernetes.io/version: 2.0.0
    spec:
      automountServiceAccountToken: true  在大于1.24版本的K8S集群中,此行不生效
      containers:
      - image: k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          timeoutSeconds: 5
        name: kube-state-metrics
        ports:
        - containerPort: 8080
          name: http-metrics
        - containerPort: 8081
          name: telemetry
        readinessProbe:
          httpGet:
            path: /
            port: 8081
          initialDelaySeconds: 5
          timeoutSeconds: 5
        securityContext:
          runAsUser: 65534
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: kube-state-metrics
service类型为NodePort,并分别添加nodePort端口

cat service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: 2.0.0
  name: kube-state-metrics
  namespace: ops-monit   修改名称空间
spec:
  type: NodePort
  ports:
  - name: http-metrics
    port: 8080
    targetPort: http-metrics
    nodePort: 30860
  - name: telemetry
    port: 8081
    targetPort: telemetry
    nodePort: 30861
  selector:
    app.kubernetes.io/name: kube-state-metrics

8080 端口返回的内容就是各类 Kubernetes 对象信息,比如 node 相关的信息
8081 端口,暴露的是 KSM 自身的指标,KSM 要调用 APIServer 的接口,watch 相关数据,需要度量这些动作的健康状况
cat service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: 2.0.0
  name: kube-state-metrics
  namespace: ops-monit  修改命名空间
自己创建secret
cat kube-state-metrics-token.yaml
apiVersion: v1
kind: Secret
metadata:
  name: kube-state-metrics
  namespace: ops-monit
  annotations:
    kubernetes.io/service-account.name: kube-state-metrics
type: kubernetes.io/service-account-token

执行部署描述文件

kubectl apply -f .
kubectl get all -n ops-monit
NAME                                      READY   STATUS    RESTARTS   AGE
pod/kube-state-metrics-699f478764-86xqq   1/1     Running   0          56s

NAME                         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                         AGE
service/kube-state-metrics   NodePort   10.10.21.134   <none>        8080:30860/TCP,8081:30861/TCP   2m55s

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kube-state-metrics   1/1     1            1           56s

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/kube-state-metrics-699f478764   1         1         1       56s
curl http://127.0.0.1:30861/healthz
<html>
             <head><title>Kube-State-Metrics Metrics Server</title></head>
             <body>
             <h1>Kube-State-Metrics Metrics</h1>
             <ul>
             <li><a href='/metrics'>metrics</a></li>
             </ul>
             </body>
             </html>
curl http://127.0.0.1:30860/healthz
OK

修改promethues.yml文件添加监控配置

创建k8s.token文件

kubectl get secret -n ops-monit
kube-state-metrics               kubernetes.io/service-account-token   3      107s


kubectl describe secret kube-state-metrics -n ops-monit
Name:         kube-state-metrics
Namespace:    ops-monit
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: kube-state-metrics
              kubernetes.io/service-account.uid: b55fdd9a-ba7b-4782-aa2e-51871dad0c56

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     2032 bytes
namespace:  9 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IlJGbkJVSVQ1Wl93ZXVDdmc3di1DMW1HbmJJbnlnRGt0ZXU2ekJVLVpPV3cifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJvcHMtbW9uaXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoia3ViZS1zdGF0ZS1tZXRyaWNzIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmUtc3RhdGUtbWV0cmljcyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImI1NWZkZDlhLWJhN2ItNDc4Mi1hYTJlLTUxODcxZGFkMGM1NiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpvcHMtbW9uaXQ6a3ViZS1zdGF0ZS1tZXRyaWNzIn0.SGrUwXjTp1l6VDzsbCCEupCqVgAWTsN6s6RA91uWFlrwVwHff8ZAqBml0bK8igIk_kxzB3d5b-uq6sOiuymj-UGL5XmGUc68Xx_fMDSSqgSAl9Q9dV4jdd19oX-WLroHijk6NMzdcJlGmXnMoA9DI7utDb2jWMWwVDI7qo_sHEbkpWxec8ElCvqn9S3dpnrWY7whS7J1p52XU09CL7GozgT88fZ7I4slwiY45sF8nlXrVP_Q2l9MO3McZw79S6b1KNxJ6-tDSRwGrisaX4fZKi-1tcpnXgM8QngJMHHAkQwqnrobNACott_bsr7T9V7QMOMl1IKwEGz33jl8sSXWSw



以下命令亦可直接获取token值
kubectl describe secret kube-state-metrics -n ops-monit | grep token: | awk {'print $2'}
eyJhbGciOiJSUzI1NiIsImtpZCI6IlJGbkJVSVQ1Wl93ZXVDdmc3di1DMW1HbmJJbnlnRGt0ZXU2ekJVLVpPV3cifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJvcHMtbW9uaXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoia3ViZS1zdGF0ZS1tZXRyaWNzIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmUtc3RhdGUtbWV0cmljcyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImI1NWZkZDlhLWJhN2ItNDc4Mi1hYTJlLTUxODcxZGFkMGM1NiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpvcHMtbW9uaXQ6a3ViZS1zdGF0ZS1tZXRyaWNzIn0.SGrUwXjTp1l6VDzsbCCEupCqVgAWTsN6s6RA91uWFlrwVwHff8ZAqBml0bK8igIk_kxzB3d5b-uq6sOiuymj-UGL5XmGUc68Xx_fMDSSqgSAl9Q9dV4jdd19oX-WLroHijk6NMzdcJlGmXnMoA9DI7utDb2jWMWwVDI7qo_sHEbkpWxec8ElCvqn9S3dpnrWY7whS7J1p52XU09CL7GozgT88fZ7I4slwiY45sF8nlXrVP_Q2l9MO3McZw79S6b1KNxJ6-tDSRwGrisaX4fZKi-1tcpnXgM8QngJMHHAkQwqnrobNACott_bsr7T9V7QMOMl1IKwEGz33jl8sSXWSw


cat /app/prometheus/k8s.token
eyJhbGciOiJSUzI1NiIsImtpZCI6IlJGbkJVSVQ1Wl93ZXVDdmc3di1DMW1HbmJJbnlnRGt0ZXU2ekJVLVpPV3cifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJvcHMtbW9uaXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoia3ViZS1zdGF0ZS1tZXRyaWNzIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmUtc3RhdGUtbWV0cmljcyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImI1NWZkZDlhLWJhN2ItNDc4Mi1hYTJlLTUxODcxZGFkMGM1NiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpvcHMtbW9uaXQ6a3ViZS1zdGF0ZS1tZXRyaWNzIn0.SGrUwXjTp1l6VDzsbCCEupCqVgAWTsN6s6RA91uWFlrwVwHff8ZAqBml0bK8igIk_kxzB3d5b-uq6sOiuymj-UGL5XmGUc68Xx_fMDSSqgSAl9Q9dV4jdd19oX-WLroHijk6NMzdcJlGmXnMoA9DI7utDb2jWMWwVDI7qo_sHEbkpWxec8ElCvqn9S3dpnrWY7whS7J1p52XU09CL7GozgT88fZ7I4slwiY45sF8nlXrVP_Q2l9MO3McZw79S6b1KNxJ6-tDSRwGrisaX4fZKi-1tcpnXgM8QngJMHHAkQwqnrobNACott_bsr7T9V7QMOMl1IKwEGz33jl8sSXWSw

添加监控配置

以下为添加内容

  - job_name: 'k8s-cadvisor'
    scrape_interval: 60s
    scrape_timeout: 60s
    metrics_path: /metrics/cadvisor
    kubernetes_sd_configs:  # kubernetes 自动发现
    - api_server: https://172.22.138.27:6443  # apiserver 地址
      role: node  # node 类型的自动发现
      namespaces:
        names:
        - ops-monit
      bearer_token_file: k8s.token
      tls_config:
        insecure_skip_verify: true
    bearer_token_file: k8s.token
    tls_config:
      insecure_skip_verify: true
    relabel_configs:
    - source_labels: [__address__]
      regex: '(.*):10250'
      replacement: '${1}:10255'
      target_label: __address__
      action: replace
    - action: labelmap
      regex: __meta_kubernetes_node_label_(.+)
    metric_relabel_configs:
    - source_labels: [instance]
      separator: ;
      regex: (.+)
      target_label: node
      replacement: $1
      action: replace
    - source_labels: [pod_name]
      separator: ;
      regex: (.+)
      target_label: pod
      replacement: $1
      action: replace
    - source_labels: [container_name]
      separator: ;
      regex: (.+)
      target_label: container
      replacement: $1
      action: replace
  - job_name: kube-state-metrics-1
    kubernetes_sd_configs:
    - api_server: https://172.22.138.27:6443  # apiserver 地址
      role: endpoints  # 端点类型的自动发现
      namespaces:
        names:
        - ops-monit      
      bearer_token_file: k8s.token
      tls_config:
        insecure_skip_verify: true
    bearer_token_file: k8s.token
    tls_config:
      insecure_skip_verify: true
    relabel_configs:
    - action: labelmap
      regex: __meta_kubernetes_node_label_(.+)
    - separator: ;
      regex: (.*)
      target_label: __address__
      replacement: 172.22.138.27:30860
    - source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name]
      regex: kube-state-metrics
      replacement: $1
      action: keep
    - action: labelmap
      regex: __meta_kubernetes_service_label_(.+)
    - source_labels: [__meta_kubernetes_namespace]
      action: replace
      target_label: k8s_namespace
    - source_labels: [__meta_kubernetes_service_name]
      action: replace
      target_label: k8s_sname    
  - job_name: kube-state-metrics-2
    kubernetes_sd_configs:
    - api_server: https://172.22.138.27:6443  # apiserver 地址
      role: endpoints  # 端点类型的自动发现
      namespaces:
        names:
        - ops-monit
      bearer_token_file: k8s.token
      tls_config:
        insecure_skip_verify: true
    bearer_token_file: k8s.token
    tls_config:
      insecure_skip_verify: true
    relabel_configs:
    - action: labelmap
      regex: __meta_kubernetes_node_label_(.+)
    - separator: ;
      regex: (.*)
      target_label: __address__
      replacement: 172.22.138.27:30861
    - source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name]
      regex: kube-state-metrics
      replacement: $1
      action: keep
    - action: labelmap
      regex: __meta_kubernetes_service_label_(.+)
    - source_labels: [__meta_kubernetes_namespace]
      action: replace
      target_label: k8s_namespace
    - source_labels: [__meta_kubernetes_service_name]
      action: replace
      target_label: k8s_sname

对上述的解释:

job1:
job_name: 'k8s-cadvisor':作业的名称为 'k8s-cadvisor',用于识别该作业的唯一标识符。

scrape_interval: 60s:采集数据的时间间隔为 60 秒,即每隔 60 秒从目标获取一次指标数据。

scrape_timeout: 60s:在 60 秒内完成单次采集操作,超时后将终止该次采集。

metrics_path: /metrics/cadvisor:目标提供指标数据的路径为 '/metrics/cadvisor'。

kubernetes_sd_configs:Kubernetes 服务发现配置,用于指定要监控的 Kubernetes 节点。

api_server: https://192.168.10.160:6443:Kubernetes API 服务器的地址。
role: node:指定要监控的角色为节点。
namespaces:指定要监控的命名空间。
names: ['ops-monit']:指定要监控的命名空间为 'ops-monit'。
bearer_token_file: k8s.token:指定用于身份验证的令牌文件的路径。
tls_config:配置用于与 Kubernetes API 服务器建立安全连接的 TLS 设置。
insecure_skip_verify: true:忽略对服务器证书的验证。
bearer_token_file: k8s.token:指定用于身份验证的令牌文件的路径。

tls_config:配置用于与目标建立安全连接的 TLS 设置。

insecure_skip_verify: true:忽略对服务器证书的验证。
relabel_configs:标签重写配置,用于更改指标数据的标签值。

第一个 relabel 配置:
source_labels: [__address__]:指定源标签为 'address',即原始地址标签。
regex: '(.*):10250':使用正则表达式匹配地址,并捕获匹配组。
replacement: '${1}:10255':将匹配组替换为新的地址。
target_label: __address__:指定目标标签为 'address',即目标地址标签。
action: replace:替换操作,将新的地址值应用到目标地址标签上。
第二个 relabel 配置:
action: labelmap:标签映射操作,用于从源标签中提取标签键值对。
regex: __meta_kubernetes_node_label_(.+):使用正则表达式匹配源标签。
metric_relabel_configs:指标标签重写配置,用于更改指标数据的标签值。

第一个 metric_relabel 配置:
source_labels: [instance]:指定源标签为 'instance'。
separator: ;:标签值之间的分隔符为 ';'。
regex: (.+):使用正则表达式匹配源标签的值,并捕获匹配组。
target_label: node:指定目标标签为 'node'。
replacement: $1:将匹配组替换为新的标签值。
action: replace:替换操作,将新的标签值应用到目标标签上。
第二个 metric_relabel 配置:
source_labels: [pod_name]:指定源标签为 'pod_name'。
separator: ;:标签值之间的分隔符为 ';'。
regex: (.+):使用正则表达式匹配源标签的值,并捕获匹配组。
target_label: pod:指定目标标签为 'pod'。
replacement: $1:将匹配组替换为新的标签值。
action: replace:替换操作,将新的标签值应用到目标标签上。
第三个 metric_relabel 配置:
source_labels: [container_name]:指定源标签为 'container_name'。
separator: ;:标签值之间的分隔符为 ';'。
regex: (.+):使用正则表达式匹配源标签的值,并捕获匹配组。
target_label: container:指定目标标签为 'container'。
replacement: $1:将匹配组替换为新的标签值。
action: replace:替换操作,将新的标签值应用到目标标签上。
job2:
job_name: kube-state-metrics-1:定义了作业的名称为 'kube-state-metrics-1',作为作业的唯一标识符。

kubernetes_sd_configs:Kubernetes 服务发现配置,用于指定要监控的 Kubernetes 资源。

api_server: https://192.168.10.160:6443:指定 Kubernetes API 服务器的地址。
role: endpoints:指定要监控的资源角色为端点(Endpoints)。
namespaces:指定要监控的命名空间。
names: ['ops-monit']:指定要监控的命名空间为 'ops-monit'。
bearer_token_file: k8s.token:指定用于身份验证的令牌文件的路径。
tls_config:配置用于与 Kubernetes API 服务器建立安全连接的 TLS 设置。
insecure_skip_verify: true:忽略对服务器证书的验证。
bearer_token_file: k8s.token:指定用于身份验证的令牌文件的路径。

tls_config:配置用于与目标建立安全连接的 TLS 设置。

insecure_skip_verify: true:忽略对服务器证书的验证。
relabel_configs:标签重写配置,用于更改指标数据的标签值。

第一个 relabel 配置:
action: labelmap:标签映射操作,用于从源标签中提取标签键值对。
regex: __meta_kubernetes_node_label_(.+):使用正则表达式匹配源标签。
第二个 relabel 配置:
separator: ;:标签值之间的分隔符为 ';'。
regex: (.*):使用正则表达式匹配所有内容。
target_label: __address__:指定目标标签为 'address',即目标地址标签。
replacement: 192.168.10.160:30866:将目标地址标签的值替换为 '192.168.10.160:30866'。
第三个 relabel 配置:
source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name]:指定源标签为 'app.kubernetes.io/name'。
regex: kube-state-metrics:使用正则表达式匹配源标签的值。
replacement: $1:将匹配的值作为替换结果。
action: keep:保留操作,保持该标签不变。
第四个 relabel 配置:
action: labelmap:标签映射操作,用于从源标签中提取标签键值对。
regex: __meta_kubernetes_service_label_(.+):使用正则表达式匹配源标签。
第五个 relabel 配置:
source_labels: [__meta_kubernetes_namespace]:指定源标签为 '__meta_kubernetes_namespace'。
action: replace:替换操作,将源标签的值替换到目标标签上。
target_label: k8s_namespace:指定目标标签为 'k8s_namespace'。
第六个 relabel 配置:
source_labels: [__meta_kubernetes_service_name]:指定源标签为 '__meta_kubernetes_service_name'。
action: replace:替换操作,将源标签的值替换到目标标签上。
target_label: k8s_sname:指定目标标签为 'k8s_sname'。
这个配置文件定义了一个 Prometheus 作业,用于从 Kubernetes 的端点中收集指标数据。它通过标签重写和重标记来修改指标数据的标签,以便更好地组织和标识数据。其中的 relabel 配置用于提取和修改特定的标签值,以满足监控需求。
job3:
job_name: kube-state-metrics-2:定义了作业的名称为 'kube-state-metrics-2',作为作业的唯一标识符。

kubernetes_sd_configs:Kubernetes 服务发现配置,用于指定要监控的 Kubernetes 资源。

api_server: https://192.168.10.160:6443:指定 Kubernetes API 服务器的地址。
role: endpoints:指定要监控的资源角色为端点(Endpoints)。
namespaces:指定要监控的命名空间。
names: ['ops-monit']:指定要监控的命名空间为 'ops-monit'。
bearer_token_file: k8s.token:指定用于身份验证的令牌文件的路径。
tls_config:配置用于与 Kubernetes API 服务器建立安全连接的 TLS 设置。
insecure_skip_verify: true:忽略对服务器证书的验证。
bearer_token_file: k8s.token:指定用于身份验证的令牌文件的路径。

tls_config:配置用于与目标建立安全连接的 TLS 设置。

insecure_skip_verify: true:忽略对服务器证书的验证。
relabel_configs:标签重写配置,用于更改指标数据的标签值。

第一个 relabel 配置:
action: labelmap:标签映射操作,用于从源标签中提取标签键值对。
regex: __meta_kubernetes_node_label_(.+):使用正则表达式匹配源标签。
第二个 relabel 配置:
separator: ;:标签值之间的分隔符为 ';'。
regex: (.*):使用正则表达式匹配所有内容。
target_label: __address__:指定目标标签为 'address',即目标地址标签。
replacement: 192.168.10.160:30867:将目标地址标签的值替换为 '192.168.10.160:30867'。
第三个 relabel 配置:
source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name]:指定源标签为 'app.kubernetes.io/name'。
regex: kube-state-metrics:使用正则表达式匹配源标签的值。
replacement: $1:将匹配的值作为替换结果。
action: keep:保留操作,保持该标签不变。
第四个 relabel 配置:
action: labelmap:标签映射操作,用于从源标签中提取标签键值对。
regex: __meta_kubernetes_service_label_(.+):使用正则表达式匹配源标签。
第五个 relabel 配置:
source_labels: [__meta_kubernetes_namespace]:指定源标签为 '__meta_kubernetes_namespace'。
action: replace:替换操作,将源标签的值替换到目标标签上。
target_label: k8s_namespace:指定目标标签为 'k8s_namespace'。
第六个 relabel 配置:
source_labels: [__meta_kubernetes_service_name]:指定源标签为 '__meta_kubernetes_service_name'。
action: replace:替换操作,将源标签的值替换到目标标签上。
target_label: k8s_sname:指定目标标签为 'k8s_sname'。
这个配置文件定义了另一个 Prometheus 作业,用于从 Kubernetes 的端点中收集指标数据。它与前一个配置文件的区别在于作业的名称、目标地址以及可能的标签映射。该作业配置用于特定的监控需求,可能对应不同的服务或命名空间。

重启Prometheus

systemctl restart prometheus

修改kubelet配置开启10255端口

10250(kubelet API):是kubelet与 API Server通信的端口,定期请求 API Server获取自己所应当处理的任务,通过该端口可以访问获取node资源以及状态。如果kubelet的10250端口对外暴露,攻击者可创建恶意pod或控制已有pod,后续可尝试逃逸至宿主机。

10255(readonly API):提供了pod和node的信息。如果对外开放,攻击者利用公开api可以获取敏感信息。

如果不开启10255端口,将会拿不到容器相关的监控指标

cat /etc/kubernetes/kubelet.env
KUBE_LOG_LEVEL="--v=2"
KUBELET_ADDRESS="--node-ip=192.168.10.16X"
KUBELET_HOSTNAME="--hostname-override=nodeX"



KUBELET_ARGS="--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \
--config=/etc/kubernetes/kubelet-config.yaml \
--kubeconfig=/etc/kubernetes/kubelet.conf \
--container-runtime=remote \
--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \
--runtime-cgroups=/system.slice/containerd.service \
--read-only-port=10255 \ 添加此行内容
  "
KUBELET_CLOUDPROVIDER=""

PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
systemctl restart kubelet
ss -anput | grep ":10255"
tcp    LISTEN     0      4096   192.168.10.16X:10255                 *:*                   users:(("kubelet",pid=61365,fd=24))

添加Grafana仪表盘实现监控可视化

导入模板:13105

image-20250424163531070

PromQL语句(扩展)

Node节点数量监控

kube_node_info{instance="192.168.10.160:30866"}

集群节点状态错误

监控集群节点状态是否错误,如果值为1就是有错误,可以告警。

kube_node_status_condition{condition="Ready",status!="true"}==1

集群节点状态是否准备好

kube_node_status_condition{condition='Ready',status='true'}

集群节点内存或硬盘资源是否短缺

kube_node_status_condition{condition=~"OutOfDisk|MemoryPressure|DiskPressure",status!="false"}

集群中存在失败的PVC监控

kube_persistentvolumeclaim_status_phase{phase="Failed"}

集群中存在启动失败的Pod监控

kube_pod_status_phase{phase=~"Failed|Unknown"}

集群中已运行的容器

kube_pod_container_status_running{namespace=~".*"}==1

集群中已停止的容器

kube_pod_container_status_terminated{namespace=~".*"}==1

集群磁盘使用率

(sum (node_filesystem_size_bytes{nodename=~".*"}) - sum (node_filesystem_free_bytes{nodename=~".*"})) / sum (node_filesystem_size_bytes{nodename=~".*"})

results matching ""

    No results matching ""