环境

主机名 IP地址
ops-server 10.0.20.106
master01.whisper-tech.net 10.0.10.53
master02.whisper-tech.net 10.0.20.109
master03.whisper-tech.net 10.0.20.108
node01.whisper-tech.net (暂时调用) 10.0.10.52
node02.whisper-tech.net 10.0.20.105
node03.whisper-tech.net 10.0.20.110
islb.whisper-tech.net 10.0.10.54

NFS

nfs-server部署

ops-server部署nfs-server服务, 让prometheus和grafana能持久化数据, 保证重启不丢失配置和数据

安装依赖包

  1. yum install -y nfs-utils rpcbind

创建存储目录

mkdir -p /data/k8s_dir

配置

vim /etc/exports

/data/k8s_dir 10.0.0.0/16(rw,async,no_root_squash)
  • 常用选项:
    • ro:客户端挂载后,其权限为只读,默认选项;
    • rw:读写权限;
    • sync:同时将数据写入到内存与硬盘中;
    • async:异步,优先将数据保存到内存,然后再写入硬盘;
    • Secure:要求请求源的端口小于1024
  • 用户映射:
    • root_squash:当NFS客户端使用root用户访问时,映射到NFS服务器的匿名用户;
    • no_root_squash:当NFS客户端使用root用户访问时,映射到NFS服务器的root用户;
    • all_squash:全部用户都映射为服务器端的匿名用户;
    • anonuid=UID:将客户端登录用户映射为此处指定的用户uid;
    • anongid=GID:将客户端登录用户映射为此处指定的用户gid

设置开机启动 并 启动服务

systemctl enable rpcbind  nfs-server.service --now

如有防火墙,请开启

etcd.jsonnet

(import 'github.com/etcd-io/etcd/contrib/mixin/mixin.libsonnet') + {
  values+:: {
    etcd: {
      ips: [],
      clientCA: null,
      clientKey: null,
      clientCert: null,
      serverName: null,
      insecureSkipVerify: null,
    },
  },
  prometheus+: {
    secretEtcdCerts: {
      // Prometheus Operator allows us to mount secrets in the pod. By loading the secrets as files, they can be made available inside the Prometheus pod.
      apiVersion: 'v1',
      kind: 'Secret',
      type: 'Opaque',
      metadata: {
        name: 'kube-etcd-client-certs',
        namespace: $.values.common.namespace,
      },
      data: {
        'etcd-client-ca.crt': std.base64($.values.etcd.clientCA),
        'etcd-client.key': std.base64($.values.etcd.clientKey),
        'etcd-client.crt': std.base64($.values.etcd.clientCert),
      },
    },
    prometheus+: {
      // Reference info: https://coreos.com/operators/prometheus/docs/latest/api.html#prometheusspec
      spec+: {
        secrets+: [$.prometheus.secretEtcdCerts.metadata.name],
      },
    },
  },
  etcd+: {
    serviceEtcd: {
      apiVersion: 'v1',
      kind: 'Service',
      metadata: {
        name: 'etcd',
        namespace: 'kube-system',
        labels: { 'app.kubernetes.io/name': 'etcd' },
      },
      spec: {
        ports: [
          { name: 'metrics', targetPort: 2379, port: 2379 },
        ],
        clusterIP: 'None',
      },
    },
    endpointsEtcd: {
      apiVersion: 'v1',
      kind: 'Endpoints',
      metadata: {
        name: 'etcd',
        namespace: 'kube-system',
        labels: { 'app.kubernetes.io/name': 'etcd' },
      },
      subsets: [{
        addresses: [
          { ip: etcdIP }
          for etcdIP in $.values.etcd.ips
        ],
        ports: [
          { name: 'metrics', port: 2379, protocol: 'TCP' },
        ],
      }],
    },
    serviceMonitorEtcd: {
      apiVersion: 'monitoring.coreos.com/v1',
      kind: 'ServiceMonitor',
      metadata: {
        name: 'etcd',
        namespace: 'kube-system',
        labels: {
          'app.kubernetes.io/name': 'etcd',
        },
      },
      spec: {
        jobLabel: 'app.kubernetes.io/name',
        endpoints: [
          {
            port: 'metrics',
            interval: '30s',
            scheme: 'https',
            // Prometheus Operator (and Prometheus) allow us to specify a tlsConfig. This is required as most likely your etcd metrics end points is secure.
            tlsConfig: {
              caFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client-ca.crt',
              keyFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client.key',
              certFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client.crt',
              [if $.values.etcd.serverName != null then 'serverName']: $.values.etcd.serverName,
              [if $.values.etcd.insecureSkipVerify != null then 'insecureSkipVerify']: $.values.etcd.insecureSkipVerify,
            },
          },
        ],
        selector: {
          matchLabels: {
            'app.kubernetes.io/name': 'etcd',
          },
        },
      },
    },
  },
}
local kp =
  (import 'kube-prometheus/main.libsonnet') +
  // Uncomment the following imports to enable its patches
  // (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
  // (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
  // (import 'kube-prometheus/addons/node-ports.libsonnet') +
  (import 'kube-prometheus/addons/static-etcd.libsonnet') +
  // (import 'kube-prometheus/addons/custom-metrics.libsonnet') +
  // (import 'kube-prometheus/addons/external-metrics.libsonnet') +
  {
    values+:: {
        common+: {
            namespace: 'monitoring',
        }, //common+::
        etcd+: {
            // 文件: prometheus-secretEtcdCerts.yaml  prometheus-endpointsEtcd.yaml prometheus-serviceEtcd.yaml
            // etcd secret 默认名称为 kube-etcd-client-certs, 如无必要, 不做修改
            // ips必须IP地址,否则apply报错
            ips: ["10.0.10.53","10.0.20.109","10.0.20.108"],
            clientCA: importstr '/opt/certs/ca.pem',
            clientCert: importstr  '/opt/certs/etcd.pem' ,
            clientKey: importstr  '/opt/certs/etcd-key.pem' ,
            insecureSkipVerify: true ,
        }, //etcd
    }, // values+::

    etcd+:{
        prometheusRule:{
            apiVersion: 'monitoring.coreos.com/v1',
            kind: 'PrometheusRule',
            metadata: {
                name: 'my-prometheus-rule',
                namespace: $.values.common.namespace,
            },
            spec: {
                groups: (kp.prometheusAlerts.groups),
            },
        },
    },
};

{ 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
{
  ['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
  for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
} +
// serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
{ 'prometheus/prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
{ 'prometheus/prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
{ 'prometheus/kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
{ ['alertmanager/alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
{ ['blackbox-exporter/blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
{ ['grafana/grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
{ ['kube-state-metrics/kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
{ ['kubernetes/kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) }
{ ['node-exporter/node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
{ ['prometheus/prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
{ ['prometheus-adapter/prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }+
{ ['etcd/etcd-' + name]: kp.etcd[name] for name in std.objectFields(kp.etcd) }

部署nfs-client-provisioner资源

nfs-rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: kube-system        #根据实际环境设定namespace,下面类同
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
  namespace: kube-system
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
  namespace: kube-system
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
    # replace with namespace where provisioner is deployed
  namespace: kube-system
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: kube-system
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: kube-system
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

nfs-StorageClass.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage
provisioner: fuseim.pri/ifs  #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:
  archiveOnDelete: "false"

nfs-provisioner.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  namespace: kube-system #与RBAC文件中的namespace保持一致
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs  #provisioner名称,请确保该名称与 nfs-StorageClass.yaml文件中的provisioner名称保持一致
            - name: NFS_SERVER
              value: ops-server           #NFS Server IP地址
            - name: NFS_PATH  
              value: /data/k8s_dir   #NFS挂载卷
      volumes:
        - name: nfs-client-root
          nfs:
            server: ops-server          #NFS Server IP地址
            path: /data/k8s_dir     #NFS 挂载卷

生成资源

kubectl apply -f nfs-rbac.yaml
kubectl apply -f nfs-provisioner.yaml
kubectl apply -f nfs-StorageClass.yaml

prometheus

https://zhuanlan.zhihu.com/p/342823695

  • address:默认为 host:port,也是之后抓取之后 instance 的值;
  • scheme:http or https ?;
  • metrics_path:就是 metrics path,默认为 /metrics
  • _param${name}:用来作为 URL parameter,比如 http://…/metrics?name=value
  • _meta:这个开头的配置都是 SD 相关的配置;

kubernetes二进制安装的组件prometheus默认配置中是无法进行有效监控,

问题

kubernetes-cadvisor (0/2 up)

https://kubernetes.default.svc/api/v1/nodes/node02.whisper-tech.net/proxy/metrics/cadvisor server returned HTTP status 403 Forbidden
问题描述: 根据文档部署prometheus后 发现以上问题.
参考地址: https://www.cnblogs.com/qkhh/p/14517861.html
解决:

  1. 查看secret与prometheus资源里面的base64是否对应 ```shell $ kubectl exec -it prometheus-5564464485-cjqmj -n monitoring cat /var/run/secrets/kubernetes.io/serviceaccount/token

eyJhbGciOiJSUzI1NiIsImtpZCI6IldIcmZ5bWtyUUtOZFpXbnRnZGp4X0tuRkNPVHhVbXprWGYza2hJRnp5cEEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJtb25pdG9yaW5nIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InByb21ldGhldXMtdG9rZW4temhnZ3oiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicHJvbWV0aGV1cyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjAwY2FhZTZiLTg2OGUtNGUzZS1iN2YyLWRhYTZiMDRkNDljNSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDptb25pdG9yaW5nOnByb21ldGhldXMifQ.qB-vfp3frHMKiwO9rZqRpbvVjlRZTk0kYy6o6CCtAzBJO6YEawC8N-AHV_XABR-D663QcCmmPXEIcSNtLhp_8T-Fi8k4NFzFPxVZvHTpQZ5Rm1cuA6TxDb9hV54f-f_JTQREADxw_pXCDm7upgJjNt5Gd02zvZYqrjm7oGIu9Bxs8ZicIpYLtfLrmfpjwF0HnQX3Q74agdArIjTB-LWT6g6KMXU1ZdgQJ3ZRAeshhfcWhMKiUCW9chjK4nJM5T0DB-B-bjyK0v0vm43K4kiWH8hxFtwXpyLS3dXqNVxYhSRQq7XmKQjoY0B5vsN8o4Alsbo9ft7owk-oqo9keca_LQ

修改secret资源名称

$ echo $(kubectl get secret -n monitoring prometheus-token-zhggz -o jsonpath=’{.data.token}’) | base64 —decode

eyJhbGciOiJSUzI1NiIsImtpZCI6IldIcmZ5bWtyUUtOZFpXbnRnZGp4X0tuRkNPVHhVbXprWGYza2hJRnp5cEEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJtb25pdG9yaW5nIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InByb21ldGhldXMtdG9rZW4temhnZ3oiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicHJvbWV0aGV1cyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjAwY2FhZTZiLTg2OGUtNGUzZS1iN2YyLWRhYTZiMDRkNDljNSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDptb25pdG9yaW5nOnByb21ldGhldXMifQ.qB-vfp3frHMKiwO9rZqRpbvVjlRZTk0kYy6o6CCtAzBJO6YEawC8N-AHV_XABR-D663QcCmmPXEIcSNtLhp_8T-Fi8k4NFzFPxVZvHTpQZ5Rm1cuA6TxDb9hV54f-f_JTQREADxw_pXCDm7upgJjNt5Gd02zvZYqrjm7oGIu9Bxs8ZicIpYLtfLrmfpjwF0HnQX3Q74agdArIjTB-LWT6g6KMXU1ZdgQJ3ZRAeshhfcWhMKiUCW9chjK4nJM5T0DB-B-bjyK0v0vm43K4kiWH8hxFtwXpyLS3dXqNVxYhSRQq7XmKQjoY0B5vsN8o4Alsbo9ft7owk-oqo9keca_LQ


2. 修改prometheus的rbac授权, 由于 cadvisor 对应的 api 是,/api/v1/nodes/${1}/proxy/metrics/cadvisor   (这里的 ${1} 会替换成具体的节点名称)。所属的 api 资源 nodes/proxy 没有被授权。如果加上授权:
```shell
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/cluster-service: "true"
  name: prometheus
  namespace: monitoring
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  # 新增资源
  - nodes/proxy
  - nodes/metrics
  - services
  - endpoints
  - pods

kubenetes-apiservers

image.png
在job_name中添加server_name: kubernetes 解决了问题 原因暂时未知

      # 采集组件信息,etcd controller-manager, kube-scheduler 集成在apiserver中
      - job_name: "kubernetes-apiservers"
        honor_timestamps: true
        scrape_interval: 30s
        scrape_timeout: 10s
        metrics_path: /metrics
        scheme: https
        kubernetes_sd_configs:
        - role: endpoints
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        tls_config:
            ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
            # 添加
            server_name: kubernetes
            insecure_skip_verify: true
        relabel_configs:
        - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
          separator: ;
          regex: default;kubernetes;https
          replacement: $1
          action: keep

prometheus-oprator

通过prometheus-oprator安装方式安装, 对prometheus访问路径添加前缀后, grafana默认prometheus数据源变更也无法访问,
该问题由于grafana挂载了datasources.yaml配置文件, 写死了prometheus url地址, 无论如何修改, 始终都是该url地址
所以需要找到datasources.yaml的定义位置.

kube-prometheus/manifests/grafana-dashboardDatasources.yaml

该配置文件是一组加密的配置文件,该如何修改呢

apiVersion: v1
data:
  datasources.yaml: ewogICAgImFwaVZlcnNpb24iOiAxLAogICAgImRhdGFzb3VyY2VzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgIm9yZ0lkIjogMSwKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1cmwiOiAiaHR0cDovL3Byb21ldGhldXMtazhzLm1vbml0b3Jpbmcuc3ZjOjkwOTAiLAogICAgICAgICAgICAidmVyc2lvbiI6IDEKICAgICAgICB9CiAgICBdCn0=
kind: Secret
metadata:
  labels:
    app.kubernetes.io/component: grafana
    app.kubernetes.io/name: grafana
    app.kubernetes.io/part-of: kube-prometheus
    app.kubernetes.io/version: 8.0.3
  name: grafana-datasources
  namespace: monitoring
type: Opaque

解压

echo -n "ewogICAgImFwaVZlcnNpb24iOiAxLAogICAgImRhdGFzb3VyY2VzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgIm9yZ0lkIjogMSwKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1cmwiOiAiaHR0cDovL3Byb21ldGhldXMtazhzLm1vbml0b3Jpbmcuc3ZjOjkwOTAiLAogICAgICAgICAgICAidmVyc2lvbiI6IDEKICAgICAgICB9CiAgICBdCn0="| base64 --decode
{
    "apiVersion": 1,
    "datasources": [
        {
            "access": "proxy",
            "editable": false,
            "name": "prometheus",
            "orgId": 1,
            "type": "prometheus",
            "url": "http://prometheus-k8s.monitoring.svc:9090",
            "version": 1
        }
    ]
}

生成临时文件tmp.json 修改url

{
    "apiVersion": 1,
    "datasources": [
        {
            "access": "proxy",
            "editable": false,
            "name": "prometheus",
            "orgId": 1,
            "type": "prometheus",
            "url": "http://prometheus-k8s.monitoring.svc:9090/prometheus",
            "version": 1
        }
    ]
}

加密

base64 < tmp.json | tr -d '\n'

ewogICAgImFwaVZlcnNpb24iOiAxLAogICAgImRhdGFzb3VyY2VzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgIm9yZ0lkIjogMSwKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1cmwiOiAiaHR0cDovL3Byb21ldGhldXMtazhzLm1vbml0b3Jpbmcuc3ZjOjkwOTAvcHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ2ZXJzaW9uIjogMQogICAgICAgIH0KICAgIF0KfQo=

修改配置文件 对应位置, 重新apply和restart相关资源

compact head: persist head block: populate block: add series: out-of-order series added with label set

node-exporter

报错

level=error ts=2021-08-09T06:38:05.034Z caller=collector.go:169 msg=”collector failed” name=nvme duration_seconds=2.7019e-05 err=”error obtaining NVMe class info: failed to list NVMe devices at \”/host/sys/class/nvme\”: open /host/sys/class/nvme: no such file or directory”

帖子: https://www.geek-share.com/detail/2766066853.html

修改配置

      - args:
        - --web.listen-address=0.0.0.0:9100
        - --path.sysfs=/host/sys
        - --path.rootfs=/host/root
        - --no-collector.wifi
        - --no-collector.hwmon
        # 新增配置 忽略nvme驱动
        - --collector.diskstats.ignored-devices="^(nvme\\d+n\\d+p)\\d+$"
        - --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)
        - --collector.netclass.ignored-devices=^(veth.*|[a-z0-9]+@if\d+)$
        - --collector.netdev.device-exclude=^(veth.*|[a-z0-9]+@if\d+)$
        image: quay.io/prometheus/node-exporter:v1.2.0

prometheus-adapter

$ kubectl get apiService
v1beta1.metrics.k8s.io                  monitoring/prometheus-adapter   False (FailedDiscoveryCheck)   44m

$ kubectl top nodes
Error from server (ServiceUnavailable): the server is currently unable to handle the request (get nodes.metrics.k8s.io)

$ kubectl get  --raw "/apis/metrics.k8s.io/v1beta1"
Error from server (ServiceUnavailable): the server is currently unable to handle the request

添加配置
hostNetwork: true

E0812 10:03:02.469561       1 provider.go:265] failed querying node metrics: unable to fetch node CPU metrics: unable to execute query: Get "http://prometheus-k8s.monitoring.svc.cluster.local:9090/prometheus/api/v1/query?query=sum+by+%28node%29+%28%0A++1+-+irate%28%0A++++node_cpu_seconds_total%7Bmode%3D%22idle%22%7D%5B60s%5D%0A++%29%0A++%2A+on%28namespace%2C+pod%29+group_left%28node%29+%28%0A++++node_namespace_pod%3Akube_pod_info%3A%7Bnode%3D~%22node02.whisper-tech.net%7Cnode03.whisper-tech.net%22%7D%0A++%29%0A%29%0Aor+sum+by+%28node%29+%28%0A++1+-+irate%28%0A++++windows_cpu_time_total%7Bmode%3D%22idle%22%2C+job%3D%22windows-exporter%22%2Cnode%3D~%22node02.whisper-tech.net%7Cnode03.whisper-tech.net%22%7D%5B4m%5D%0A++%29%0A%29%0A&time=1628762582.467": dial tcp: lookup prometheus-k8s.monitoring.svc.cluster.local on 100.100.2.136:53: no such host

prometheus target配置

官方文档英文 : https://prometheus.io/docs/prometheus/latest/configuration/configuration/

scrape_configs

  • job_name: serviceMonitor/monitoring/kube-state-metrics/0

target 名称

scrape_interval: 30s

抓取间隔, 默认继承global值

scrape_timeout: 30s

抓取超时时间,默认继承global值

metrics_path: /metrics

抓取路径, 默认是/metrics

scheme: https

指定采集使用的协议 http或https

honor_labels: true

解决prometheus server与exporter端用户自定义label冲突问题 默认值为 flase
设置为”True” , 通过保留label来解决标签冲突值, 并忽略 冲突的服务端侧标签
设置为”Flase”过重命名来解决标签冲突问题, 会在冲突的标签前添加exported_<原有标签>
例如 exported_instance exported_job

honor_timestamps: true

默认值为 true
设置为true 则使用目标公开的指标的时间戳
设置为false 则目标忽略的度量标准的时间戳将被忽略

base_auth: [ username: ] [ password: ] [ password_file: ]

使用配置的用户和密码 在每个抓取上设置”Authorization”标头 password 和 password_file 互斥

bearer_token

使用配置的载体令牌在每个抓取请求上设置“Authorization”标头。 它与bearer_token_file互斥。

bearer_token_file: /path/to/bearer/token/file

使用从配置文件中读取的承载令牌,在每个抓取请求上设置“Authorization”标头。 它与bearer_token互斥。

authorization: type: Bearer credentials: credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token

由prometheus 2.26.0开始, 新增此参数. authorization与bearer_token对比, 此配置更方便后续扩展
使用配置在每个scrape请求设置 “authorization” 头部信息
type 设置请求的身份验证类型 默认为 Bearer
credentials 设置请求凭据, 它与 cerdentials_file互斥
credentials_file 读取配置文件中的凭据, 它与credentials互斥

follow_redirects: true

配置抓取请求是否遵循HTTP 3xx重定向。 默认为true

tls_config ca_file: cert_file: key_file: server_name: insecure_skip_verify:

配置scrape请求的TLS
ca_file 用于验证API服务器证书的CA证书
cert_file 向服务器进行客户端证书认证的证书
key_file 向服务器进行客户端证书认证的密钥文件
server_name ServerName扩展名,表示服务器的名称。
insecure_skip_verify 禁用服务器证书验证

kubernetes_sd_config

kubernetes_sd_config:

 - role: <string>

api_server: kubeconfig_file:
basic_auth: username: password: password_file: authorization: type: credentials: credentials_file: follow_redirects: namespaces: names:

role kubernetes发现的角色名称 node service pod endpoints ingress
api_server API地址如果为空,则嘉定prometheus在集群内部运行,它将会自动发现API服务器, 并使用POD证书和令牌(/var/run/secrets/kubernetes.io/serviceaccount/)
kubeconfig_file kubeconfig文件路径, 注意apiserver与kubeconfig_file互斥
basic_auth 用于向API服务器进行身份验证的可选身份验证信息, 注意 basic_auth 和 authorization 选项互斥
authorization authentication 请求头信息配置
follow_redirects 配置HTTP请求是否遵循HTTP 3xx重定向 默认为true
namespaces 可选的命名空间发现, 如果沈略, 将使用所有命名空间

node

node角色为每个集群节点发现一个目标,其地址默认为 Kubelet 的 HTTP 端口。目标地址默认为 Kubernetes 节点对象的第一个现有地址,地址类型顺序为NodeInternalIPNodeExternalIPNodeLegacyHostIPNodeHostName
可用的元标签:

  • __meta_kubernetes_node_name: 节点对象的名称。
  • _meta_kubernetes_node_label:来自节点对象的每个标签。
  • _meta_kubernetes_node_labelpresent:true对于来自节点对象的每个标签。
  • _meta_kubernetes_node_annotation:来自节点对象的每个注释。
  • _meta_kubernetes_node_annotationpresent:true对于来自节点对象的每个注释。
  • _meta_kubernetes_node_address: 每个节点地址类型的首地址(如果存在)。

此外,instance节点的标签将设置为从 API 服务器检索到的节点名称。

service

service角色为每个服务的每个服务端口发现一个目标。这对于服务的黑盒监控通常很有用。该地址将设置为服务的 Kubernetes DNS 名称和相应的服务端口。
可用的元标签:

  • __meta_kubernetes_namespace:服务对象的命名空间。
  • _meta_kubernetes_service_annotation:来自服务对象的每个注解。
  • _meta_kubernetes_service_annotationpresent:服务对象的每个注解为“true”。
  • __meta_kubernetes_service_cluster_ip:服务的集群IP地址。(不适用于 ExternalName 类型的服务)
  • __meta_kubernetes_service_external_name:服务的 DNS 名称。(适用于 ExternalName 类型的服务)
  • _meta_kubernetes_service_label:来自服务对象的每个标签。
  • _meta_kubernetes_service_labelpresent:true对于服务对象的每个标签。
  • __meta_kubernetes_service_name:服务对象的名称。
  • __meta_kubernetes_service_port_name:目标服务端口的名称。
  • __meta_kubernetes_service_port_protocol:目标服务端口的协议。
  • __meta_kubernetes_service_type: 服务类型。

pod

该pod角色会发现所有 Pod 并将其容器公开为目标。对于容器的每个声明的端口,都会生成一个目标。如果容器没有指定端口,则为每个容器创建一个无端口目标,用于通过重新标记手动添加端口。
可用的元标签:

  • __meta_kubernetes_namespace: pod 对象的命名空间。
  • __meta_kubernetes_pod_name: pod 对象的名称。
  • __meta_kubernetes_pod_ip:pod 对象的 pod IP。
  • _meta_kubernetes_pod_label:来自 pod 对象的每个标签。
  • _meta_kubernetes_pod_labelpresent:true对于来自 pod 对象的每个标签。
  • _meta_kubernetes_pod_annotation:来自 pod 对象的每个注释。
  • _meta_kubernetes_pod_annotationpresent:true对于来自 pod 对象的每个注释。
  • __meta_kubernetes_pod_container_init:true如果容器是一个InitContainer
  • __meta_kubernetes_pod_container_name:目标地址指向的容器名称。
  • __meta_kubernetes_pod_container_port_name: 容器端口的名称。
  • __meta_kubernetes_pod_container_port_number:集装箱港口编号。
  • __meta_kubernetes_pod_container_port_protocol:容器端口的协议。
  • __meta_kubernetes_pod_ready: 设置为true或false为 pod 的就绪状态。
  • __meta_kubernetes_pod_phase: 设置为Pending, Running, Succeeded,Failed或Unknown 在生命周期中。
  • __meta_kubernetes_pod_node_name:pod 被调度到的节点的名称。
  • __meta_kubernetes_pod_host_ip: pod 对象的当前主机 IP。
  • __meta_kubernetes_pod_uid:pod 对象的 UID。
  • __meta_kubernetes_pod_controller_kind: Pod 控制器的对象类型。
  • __meta_kubernetes_pod_controller_name:Pod 控制器的名称。

endpoints

该endpoints角色从服务的列出端点中发现目标。对于每个端点地址,每个端口都会发现一个目标。如果端点由 pod 支持,则 pod 的所有其他容器端口(未绑定到端点端口)也会被发现为目标。
可用的元标签:

  • __meta_kubernetes_namespace:端点对象的命名空间。
  • __meta_kubernetes_endpoints_name:端点对象的名称。
  • 对于直接从端点列表中发现的所有目标(那些不是从底层 pod 额外推断的),附加了以下标签:
    • __meta_kubernetes_endpoint_hostname:端点的主机名。
    • __meta_kubernetes_endpoint_node_name:托管端点的节点的名称。
    • __meta_kubernetes_endpoint_ready: 设置为true或false为端点的就绪状态。
    • __meta_kubernetes_endpoint_port_name:端点端口的名称。
    • __meta_kubernetes_endpoint_port_protocol:端点端口的协议。
    • __meta_kubernetes_endpoint_address_target_kind:端点地址目标的种类。
    • __meta_kubernetes_endpoint_address_target_name:端点地址目标的名称。
  • 如果端点属于服务,role: service则附加发现的所有标签。
  • 对于 pod 支持的所有目标,都会role: pod附加发现的所有标签。

ingress

该ingress角色为每个入口的每个路径发现一个目标。这对于入口的黑盒监控通常很有用。地址将设置为入口规范中指定的主机。
可用的元标签:

  • __meta_kubernetes_namespace:入口对象的命名空间。
  • __meta_kubernetes_ingress_name:入口对象的名称。
  • _meta_kubernetes_ingress_label:来自入口对象的每个标签。
  • _meta_kubernetes_ingress_labelpresent:true对于来自入口对象的每个标签。
  • _meta_kubernetes_ingress_annotation:来自入口对象的每个注释。
  • _meta_kubernetes_ingress_annotationpresent:true对于来自入口对象的每个注释。
  • __meta_kubernetes_ingress_class_name:来自入口规范的类名(如果存在)。
  • __meta_kubernetes_ingress_scheme:入口的协议方案,https如果设置了 TLS 配置。默认为http.
  • __meta_kubernetes_ingress_path:来自入口规范的路径。默认为/.

relabel_config

relabel_configs:

  • source_labels: [job] separator: ; regex: (.*) target_label: __tmp_prometheus_job_name replacement: $1 action: replace

source_labels 源标签从现有标签中选择值。它们的内容使用配置的分隔符连接起来,并根据配置的正则表达式进行匹配
separator 分隔符放在连接的源标签值之间。 默认值为 ;
regex 匹配所提取值的正则表达式。默认值为 (.*)
target_label 在replace操作中写入结果值的标签
replacement 如果使用正则表达式, 则对其执行正则表达式替换
action 基于正则表达式匹配执行的操作, 默认为replace, 以下为可选项

  • replace 匹配regex连接的source_labels 设置target_label为replacement, 并用它们的值替换匹配组引用, 如果regex不匹配, 则不进行替换
  • keep 删除regex与连接的source_labels 不匹配的目标
  • drop 删除regex匹配连接的目标source_labels
  • hashmod 设置target_label为modulus连接的散列的source_labels
  • labelmap 匹配regex所有标签名称. 然后将匹配标签的值复制到由replacement匹配组引用 ( ${1}, ${2}, …)给出的标签名称,replacement替换为它们的值。
  • labeldrop: 匹配regex所有标签名称。任何匹配的标签都将从标签集中删除。
  • labelkeep: 匹配regex所有标签名称。任何不匹配的标签都将从标签集中删除。

必须注意labeldroplabelkeep确保在移除标签后指标仍具有唯一标签。

metric_relabel_configs

指标重新标记适用于样本,作为摄取前的最后一步。它具有与目标重新标记相同的配置格式和操作。指标重新标记不适用于自动生成的时间序列,例如up.
一种用途是排除摄取成本太高的时间序列。