用Prometheus监控Kubernetes,目前最实用的部署方式都说全了

2020 年 6 月 28 日

用Prometheus监控Kubernetes,目前最实用的部署方式都说全了

本文由 dbaplus 社群授权转载。


在过去的几年中,云计算已经成为及分布式计算最火热的技术之一,其中 Docker、Kubernetes、Prometheus 等开源软件的发展极大地推动了云计算的发展。本文首先从 Prometheus 是如何监控 Kubernetes 入手,介绍 Prometheus Operator 组件。接着详细介绍基于 Kubernetes 的两种 Prometheus 部署方式,最后介绍服务配置、监控对象以及数据展示和告警。通过本文,大家可以在 Kubernetes 集群的基础上学习和搭建完善的 Prometheus 监控系统。


一、Prometheus 与 Kubernetes 完美结合


Kubernetes 使用 Docker 进行容器管理,如果说 Docker 和 kubernetes 的搭配是云原生时代的基石,那么 Prometheus 为云原生插上了飞翔的翅膀。随着云原生社区的不断壮大,应用场景越来越复杂,需要一套针对云原生环境的完善并且开放的监控平台。在这样的环境下,Prometheus 应运而生,天然支持 Kubernetes。


1、Kubernetes Operator


在 Kubernetes 的支持下,管理和伸缩 Web 应用、移动应用后端以及 API 服务都变得比较简单了。因为这些应用一般都是无状态的,所以 Deployment 这样的基础 Kubernetes API 对象就可以在无需附加操作的情况下,对应用进行伸缩和故障恢复了。


而对于数据库、缓存或者监控系统等有状态应用的管理,就是挑战了。这些系统需要掌握应用领域的知识,正确地进行伸缩和升级,当数据丢失或不可用的时候,要进行有效的重新配置。我们希望这些应用相关的运维技能可以编码到软件之中,从而借助 Kubernetes 的能力,正确地运行和管理复杂应用。


Operator 这种软件,使用 TPR(第三方资源,现在已经升级为 CRD)机制对 Kubernetes API 进行扩展,将特定应用的知识融入其中,让用户可以创建、配置和管理应用。与 Kubernetes 的内置资源一样,Operator 操作的不是一个单实例应用,而是集群范围内的多实例。


2、Prometheus Operator


Kubernetes 的 Prometheus Operator 为 Kubernetes 服务和 Prometheus 实例的部署和管理提供了简单的监控定义。


安装完毕后,Prometheus Operator 提供了以下功能:


  • 创建/毁坏。在Kubernetes namespace中更容易启动一个Prometheus实例,一个特定的应用程序或团队更容易使用的Operato。

  • 简单配置。配Prometheus的基础东西,比如在Kubernetes的本地资源versions, persistence,retention policies和replicas。

  • Target Services通过标签。基于常见的Kubernetes label查询,自动生成监控target配置;不需要学习Prometheus特定的配置语言。


Prometheus Operator 架构如图 1 所示。



图 1 Prometheus Operator 架构


架构中的各组成部分以不同的资源方式运行在 Kubernetes 集群中,它们各自有不同的作用。


  • Operator: Operator资源会根据自定义资源(Custom Resource Definition,CRD)来部署和管理Prometheus Server,同时监控这些自定义资源事件的变化来做相应的处理,是整个系统的控制中心。

  • Prometheus: Prometheus资源是声明性地描述Prometheus部署的期望状态。

  • Prometheus Server: Operator根据自定义资源Prometheus类型中定义的内容而部署的Prometheus Server集群,这些自定义资源可以看作用来管理Prometheus Server 集群的StatefulSets资源。

  • ServiceMonitor: ServiceMonitor也是一个自定义资源,它描述了一组被Prometheus监控的target列表。该资源通过标签来选取对应的Service Endpoint,让Prometheus Server通过选取的Service来获取Metrics信息。

  • Service: Service资源主要用来对应Kubernetes集群中的Metrics Server Pod,提供给ServiceMonitor选取,让Prometheus Server来获取信息。简单说就是Prometheus监控的对象,例如Node Exporter Service、Mysql Exporter Service等。

  • Alertmanager: Alertmanager也是一个自定义资源类型,由Operator根据资源描述内容来部署Alertmanager集群。


二、在 Kubernetes 上部署 Prometheus 的传统方式


本节详细介绍 Kubernetes 通过 YAML 文件方式部署 Prometheus 的过程,即按顺序部署了 Prometheus、kube-state-metrics、node-exporter 以及 Grafana。图 2 展示了各个组件的调用关系。



图 2 传统方式 Kubernetes 部署 Prometheus


在 Kubernetes Node 上部署 Node exporter,获取该节点物理机或者虚拟机的监控信息,在 Kubernetes Master 上部署 kube-state-metrics 获取 Kubernetes 集群的状态。所有信息汇聚到 Prometheus 进行处理和存储,然后通过 Grafana 进行展示。


1、Kubernetes 部署 Prometheus


部署对外可访问 Prometheus,首先需要创建 Prometheus 所在命名空间,然后创建 Prometheus 使用的 RBAC 规则,创建 Prometheus 的 configmap 来保存配置文件。创建 service 进行固定集群 IP 访问,创建 deployment 部署带有 Prometheus 容器的 pod,最后创建 ingress 实现外部域名访问 Prometheus。


部署顺序如图 3 所示。



图 3 Kubernetes 集群架构


创建名为 monitoring 命名空间,相关对象都部署到该命名空间,使用以下命令创建命名空间:


$ kubectl create -f ns-monitoring.yaml 
复制代码


ns-monitoring.yaml 文件内容如下:


apiVersion: v1    kind: Namespace    metadata:name: monitoring
复制代码


可以看到该 YAML 文件使用的 apiVersion 版本是 v1,kind 是 Namespace,命名空间的名字是 monitoring。


使用以下命令确认名为 monitoring 的 ns 已经创建成功:


$ kubectl get ns monitoringNAME         STATUS    AGEmonitoring   Active    1d
复制代码


创建 RBAC 规则,包含 ServiceAccount、ClusterRole、ClusterRoleBinding 三类 YAML 文件。Service Account 是面向命名空间的,ClusterRole、ClusterRoleBinding 是面向整个集群所有命名空间的,可以看到 ClusterRole、ClusterRoleBinding 对象并没有指定任何命名空间。ServiceAccount 中可以看到,名字是 prometheus-k8s,在 monitoring 命名空间下。ClusterRole 一条规则由 apiGroups、resources、verbs 共同组成。ClusterRoleBinding 中 subjects 是访问 API 的主体,subjects 包含 users、groups、service accounts 三种类型,我们使用的是 ServiceAccount 类型,使用以下命令创建 RBAC:


kubectl create -f prometheus-rbac.yaml
复制代码


rometheus-rbac.yaml 文件内容如下:


apiVersion: v1kind: ServiceAccountmetadata:    name: prometheus-k8s    namespace: monitoring---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  name: prometheusrules:- apiGroups: [""]    resources: ["nodes", "services", "endpoints", "pods"]    verbs: ["get", "list", "watch"]- apiGroups: [""]    resources: ["configmaps"]    verbs: ["get"]- nonResourceURLs: ["/metrics"]    verbs: ["get"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:    name: prometheusroleRef:    apiGroup: rbac.authorization.k8s.io    kind: ClusterRole    name: cluster-adminsubjects:- kind: ServiceAccount    name: prometheus-k8s    namespace: monitoring
复制代码


使用以下命令确认 RBAC 是否创建成功:


$ kubectl get sa prometheus-k8s -n monitoringNAME       SECRETS   AGEprometheus-k8s   1         1d
$ kubectl get clusterroleprometheusNAME AGEprometheus 1d$ kubectl get clusterrolebinding prometheusNAME AGEprometheus 1d
复制代码


使用 ConfigMap 方式创建 Prometheus 配置文件,YAML 文件中使用的类型是 ConfigMap,命名空间为 monitoring,名称为 prometheus-core,apiVersion 是 v1,data 数据中包含 prometheus.yaml 文件,内容是 prometheus.yaml: |这行下面的内容。使用以下命令创建 Prometheus 的配置文件:


$ kubectl create -f prometheus-core-cm.yaml
复制代码


prometheus-core-cm.yaml 文件内容如下:


kind: ConfigMapmetadata:    creationTimestamp: null    name: prometheus-core    namespace: monitoringapiVersion: v1data:    prometheus.yaml: |        global:            scrape_interval: 15s            scrape_timeout: 15s            evaluation_interval: 15s        alerting:            alertmanagers:            - static_configs:                - targets: ["10.254.127.110:9093"]        rule_files:            - "/etc/prometheus-rules/*.yml"        scrape_configs:        - job_name: 'kubernetes-apiservers'            kubernetes_sd_configs:            - role: endpoints            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]                action: keep                regex: default;kubernetes;https
复制代码


由于篇幅有限,该配置文件只有一个名为 kubernetes-apiservers 的 job,完整配置请查看源码文件。


使用以下命令查看已创建的配置文件 prometheus-core:


$ kubectl get cm -n monitoring prometheus-coreNAME              DATA      AGEprometheus-core   1         1d
复制代码


通过以下命令查看配置文件 prometheus-core 的详细信息:


$ kubectl get cm -n monitoring prometheus-core -o yaml
复制代码


创建 prometheus rules 配置文件,使用 ConfigMap 方式创建 prometheus rules 配置文件,包含的内容是两个文件,分别是 node-up.yml 和 cpu-usage.yml。使用以下命令创建 Prometheus 的另外两个配置文件:


$ kubectl create -f prometheus-rules-cm.yaml
复制代码


prometheus-rules-cm.yaml 文件内容如下:


kind: ConfigMapapiVersion: v1metadata:    name: prometheus-rules    namespace: monitoringdata:    node-up.yml: |        groups:        - name: server_rules            rules:            - alert: 机器宕机                expr: up{component="node-exporter"} != 1                for: 1m                labels:                    severity: "warning"                    instance: "{{ $labels.instance }}"                annotations:                    summary: "机器 {{ $labels.instance }} 处于down的状态"                    description: "{{ $labels.instance }} of job {{ $labels.job }}                     已经处于down状态超过1分钟,请及时处理"    cpu-usage.yml: |        groups:        - name: cpu_rules            rules:            - alert: cpu 剩余量过低                expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode=                    "idle"}[5m])) * 100) > 85                for: 1m                labels:                    severity: "warning"                    instance: "{{ $labels.instance }}"                annotations:                    summary: "机器 {{ $labels.instance }} cpu 已用超过设定值"                    description: "{{ $labels.instance }} CPU 用量已超过 85% (current                                  value is: {{ $value }}),请及时处理。"     
复制代码


本节的配置文件是 Prometheus 告警信息的配置文件,篇幅有限,可在文件后继续增加告警信息文件。


使用以下命令查看已下发的配置文件 prometheus-core:


$ kubectl get cm -n monitoring prometheus-rulesNAME               DATA      AGEprometheus-rules   11        1d
复制代码


使用以下命令查看配置文件 prometheus-core 详细信息:


$ kubectl get cm -n monitoring prometheus-rules -o yaml
复制代码


创建 prometheus svc,会生成一个 CLUSTER-IP 进行集群内部的访问,CLUSTER-IP 也可以自己指定。使用以下命令创建 Prometheus 要用的 service:


$ kubectl create -f prometheus-service.yaml
复制代码


prometheus-service.yaml 文件内容如下:


apiVersion: v1kind: Servicemetadata:    name: prometheus    namespace: monitoring    labels:        app: prometheus        component: core    annotations:        prometheus.io/scrape: 'true'spec:    ports:        - port: 9090            targetPort: 9090            protocol: TCP            name: webui    selector:        app: prometheus          component: core
复制代码


使用以下命令查看已创建的名为 prometheus 的 service:


$ kubectl get svc prometheus  -n monitoringNAME     TYPE     CLUSTER-IP   EXTERNAL-IP  PORT(S)   AGEprometheus   ClusterIP   10.254.192.194   <none>        9090/TCP   1d
复制代码


使用 deployment 方式创建 prometheus 实例,命令如下:


$ kubectl create -f prometheus-deploy.yaml
复制代码


prometheus-deploy.yaml 文件内容如下:


apiVersion: extensions/v1beta1kind: Deploymentmetadata:    name: prometheus-core    namespace: monitoring    labels:        app: prometheus        component: corespec:    replicas: 1    template:        metadata:            name: prometheus-main            labels:                app: prometheus                component: core        spec:            serviceAccountName: prometheus-k8s            nodeSelector:                kubernetes.io/hostname: 192.168.10.2            containers:            - name: prometheus                image: zqdlove/prometheus:v2.0.0                args:                    - '--storage.tsdb.retention=15d'                    - '--config.file=/etc/prometheus/prometheus.yaml'                    - '--storage.tsdb.path=/home/prometheus_data'                    - '--web.enable-lifecycle'                 ports:                - name: webui                    containerPort: 9090                resources:                    requests:                        cpu: 20000m                        memory: 20000M                    limits:                        cpu: 20000m                        memory: 20000M                securityContext:                    privileged: true                volumeMounts:                - name: data                    mountPath: /home/prometheus_data                - name: config-volume                    mountPath: /etc/prometheus                - name: rules-volume                    mountPath: /etc/prometheus-rules                - name: time                    mountPath: /etc/localtime            volumes:            - name: data                hostPath:                    path: /home/cdnadmin/prometheus_data             - name: config-volume                configMap:                    name: prometheus-core            - name: rules-volume                configMap:                    name: prometheus-rules            - name: time                hostPath:                    path: /etc/localtime
复制代码


使用以下命令查看已创建的名字为 prometheus-core 的 deployment 的状态:


$ kubectl get deployment prometheus-core  -n monitoringNAME      DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGEprometheus-core   1         1         1            1           1d
复制代码


返回信息表示部署期望的 pod 有 1 个,当前有 1 个,更新到最新状态的有 1 个,可用的有 1 个,pod 当前的年龄是 1 天。


创建 prometheus ingress 实现外部域名访问,使用以下命令创建 Ingress:


apiVersion: extensions/v1beta1kind: Ingressmetadata:    name: traefik-prometheus    namespace: monitoringspec:    rules:    - host: prometheus.test.com        http:            paths:            - path: /                backend:                    serviceName: prometheus                    servicePort: 9090
复制代码


将 prometheus.test.com 域名解析到 Ingress 服务器,此时可以通过 prometheus.test.com 访问 Prometheus 的监控数据的界面了。


使用以下命令查看已创建 Ingress 的状态:


$ kubectl get ing traefik-prometheus-n monitoringNAME             HOSTS           ADDRESS   PORTS   AGEtraefik-prometheus   prometheus.test.com80      1d
复制代码


将域名 prometheus.test.com 指向 Ingress 服务器,并访问该域名,主界面如图 4 所示。



图 4 主界面


2、Kubernetes 部署 kube-state-metrics


kube-state-metrics 使用名为 monitoring 的命名空间,在上节已创建,不需要再次创建,通过以下命令确认 ns 创建是否成功:


$ kubectl get ns monitoringNAME         STATUS    AGEmonitoring   Active    1d
复制代码


创建 RBAC,包含 ServiceAccount、ClusterRole、ClusterRoleBinding 三类 YAML 文件,本节 RBAC 内容结构和上节中内容类似。使用以下命令创建 kube-state-metrics RBAC:


$ kubectl create -f kube-state-metrics-rbac.yaml
复制代码


kube-state-metrics-rbac.yaml 文件内容如下:


apiVersion: v1kind: ServiceAccountmetadata:    name: kube-state-metrics    namespace: monitoring---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:    name: kube-state-metricsrules:- apiGroups: [""]    resources: ["nodes","pods","services","resourcequotas",      "replicationcontrollers","limitranges"]    verbs: ["list", "watch"]- apiGroups: ["extensions"]    resources: ["daemonsets","deployments","replicasets"]    verbs: ["list", "watch"]- apiGroups: ["batch/v1"]    resources: ["job"]    verbs: ["list", "watch"]- apiGroups: ["v1"]    resources: ["persistentvolumeclaim"]    verbs: ["list", "watch"]- apiGroups: ["apps"]    resources: ["statefulset"]    verbs: ["list", "watch"]- apiGroups: ["batch/v2alpha1"]    resources: ["cronjob"]    verbs: ["list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:    name: kube-state-metricsroleRef:    apiGroup: rbac.authorization.k8s.io    kind: ClusterRole    name: kube-state-metrics#  name: cluster-adminsubjects:- kind: ServiceAccount    name: kube-state-metrics    namespace: monitoring
复制代码


使用以下命令确认 RBAC 是否创建成功,命令分别获取已创建的 ServiceAccount、ClusterRole、ClusterRoleBinding:


$ kubectl get sa kube-state-metrics -n monitoringNAME         SECRETS   AGEkube-state-metrics   1         1d$ kubectl get clusterrole kube-state-metricsNAME           AGEkube-state-metrics   1d$ kubectl get clusterrolebinding kube-state-metricsNAME          AGEkube-state-metrics   1d
复制代码


使用以下命令创建 kube-state-metrics Service:


$ kubectl create -f kube-state-metrics-service.yaml
复制代码


kube-state-metrics-service.yaml 文件内容如下:


apiVersion: v1kind: Servicemetadata:    annotations:        prometheus.io/scrape: 'true'    name: kube-state-metrics    namespace: monitoring    labels:        app: kube-state-metricsspec:    ports:    - name: kube-state-metrics        port: 8080        protocol: TCP    selector:        app: kube-state-metrics
复制代码


使用以下命令查看名为 kube-state-metrics 的 Service:


$ kubectl get svc kube-state-metrics -n monitoringNAME       TYPE     CLUSTER-IP  EXTERNAL-IP  PORT(S)    AGEkube-state-metrics   ClusterIP   10.254.76.203   <none>        8080/TCP   1d
复制代码


使用以下命令创建名为 kube-state-metrics 的 deployment,用来部署 kube-state-metrics Docker 容器:


$ kubectl create -f kube-state-metrics-deploy.yaml
复制代码


kube-state-metrics-deploy.yaml 文件内容如下:


apiVersion: extensions/v1beta1kind: Deploymentmetadata:    name: kube-state-metrics    namespace: monitoringspec:    replicas: 1    template:        metadata:            labels:                app: kube-state-metrics        spec:            serviceAccountName: kube-state-metrics            nodeSelector:                type: k8smaster            containers:            - name: kube-state-metrics                image: zqdlove/kube-state-metrics:v1.0.1                ports:                - containerPort: 8080
复制代码


使用以下命令查看 monitoring 命名空间下名为 kube-state-metrics 的 deployment 的状态信息:


$ kubectl get deployment  kube-state-metrics -n monitoringNAME      DESIRED   CURRENT  UP-TO-DATE  AVAILABLE  AGEkube-state-metrics   1         1         1            1           1d
复制代码


使用以下命令查看相关的详细信息:


$ kubectl get deployment  kube-state-metrics -n monitoring  -o yaml$ kubectl describe  deployment  kube-state-metrics -n monitoring
复制代码


通过上节已部署的 Prometheus 界面如图 5 所示。



图 5 Prometheus 监控目标


3、Kubernetes 部署 node-exporter


在 Prometheus 中负责数据汇报的程序统一称为 Exporter,而不同的 Exporter 负责不同的业务。它们具有统一命名格式,即 xx_exporter,例如,负责主机信息收集的 node_exporter。本节为安装 node_exporter 的教程。node_exporter 主要用于*NIX 系统监控,用 Golang 编写。


node-exporter 使用名为 monitoring 的命名空间,上节已创建,不需要再次创建,通过以下命令确认 ns 创建是否成功:


$ kubectl get ns monitoringNAME         STATUS    AGEmonitoring   Active    1d
复制代码


使用以下命令部署 node-exporter service:


$ kubectl create -f node_exporter-service.yaml
复制代码


node_exporter-service.yaml 文件内容如下:


apiVersion: v1kind: Servicemetadata:    annotations:        prometheus.io/scrape: 'true'    name: prometheus-node-exporter    namespace: monitoring    labels:        app: prometheus        component: node-exporterspec:    clusterIP: None    ports:        - name: prometheus-node-exporter            port: 9100            protocol: TCP    selector:        app: prometheus        component: node-exporter    type: ClusterIP
复制代码


使用以下命令查看 monitoring 命名空间下名为 prometheus-node-exporter 的 service:


$ kubectl get svc prometheus-node-exporter -n monitoringNAME              TYPE      CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGEprometheus-node-exporter   ClusterIP   None         <none>       9100/TCP   1d
复制代码


使用 daemonset 方式创建 node-exporter 容器,命令如下:


$ kubectl create -f node_exporter-daemonset.yaml
复制代码


node_exporter-daemonset.yaml 文件详细内容如下:


apiVersion: extensions/v1beta1kind: DaemonSetmetadata:    name: prometheus-node-exporter    namespace: monitoring    labels:        app: prometheus        component: node-exporterspec:    template:        metadata:            name: prometheus-node-exporter            labels:                app: prometheus                component: node-exporter        spec:            containers:            - image: zqdlove/node-exporter:v0.16.0                name: prometheus-node-exporter                ports:                - name: prom-node-exp                    containerPort: 9100                    hostPort: 9100                resources:                    requests:                      # cpu: 20000m                        cpu: "0.6"                        memory: 100M                    limits:                        cpu: "0.6"                        #cpu: 20000m                        memory: 100M                command:                - /bin/node_exporter                - --path.procfs                - /host/proc                - --path.sysfs                - /host/sys                -  --collector.filesystem.ignored-mount-points                - ^/(sys|proc|dev|host|etc)($|/)                volumeMounts:                - name: proc                    mountPath: /host/proc                - name: sys                    mountPath: /host/sys                - name: root                    mountPath: /rootfs            volumes:            - name: proc                hostPath:                    path: /proc            - name: sys                hostPath:                    path: /sys            - name: root                hostPath:                    path: /            // 此处可以指定固定IP 192.168.10.3不部署服务            // affinity:            //  nodeAffinity:            //  requiredDuringSchedulingIgnoredDuringExecution:            //      nodeSelectorTerms:            //      - matchExpressions:            //          - key: kubernetes.io/hostname            //            operator: NotIn            //            values:            //            - 192.168.10.3
hostNetwork: true hostPID: true
复制代码


查看 monitoring 命令空间下名为 prometheus-node-exporter 的 daemonset 的状态,命令如下:


$ kubectl get ds prometheus-node-exporter -n monitoringNAME DESIRED CURRENT READYUP-TO-DATE AVAILABLENODE SELECTOR AGEprometheus-node-exporter   3    3    333<none>1d
复制代码


从返回信息可以看到,名为 prometheus-node-exporter 的 daemonset,当前有 3 个实例,都已经是 Ready 状态,都可用。


查看 monitoring 命令空间下名为 prometheus-node-exporter 的 daemonset 的详细状态信息,命令如下:


$ kubectl get ds prometheus-node-exporter -n monitoring -o yaml$ kubectl describe ds prometheus-node-exporter -n monitoring
复制代码


4、Kubernetes 部署 Grafana


Grafana 使用名为 monitoring 的命名空间,前面小节已经创建,不需要再次创建,通过以下命令确认 ns 创建是否成功:


$ kubectl get ns monitoringNAME         STATUS    AGEmonitoring   Active    1d
复制代码


使用以下命令创建 Grafana Service:


$ kubectl create -f grafana-service.yaml
复制代码


grafana-service.yaml 文件内容如下:


apiVersion: v1kind: Servicemetadata:    name: grafana    namespace: monitoring    labels:        app: grafana        component: corespec:    ports:        - port: 3000    selector:        app: grafana          component: core
复制代码


使用以下命令查看 monitoring 命令空间下名为 grafana 的 service 的信息:


$ kubectl get svc grafana -n monitoringNAME      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGEgrafana   ClusterIP   10.254.254.2   <none>        4444/TCP   1d
复制代码


使用 deployment 方式部署 Grafana,命令如下:


$ kubectl create -f grafana-deploy.yaml
复制代码


grafana-deploy.yaml 文件内容如下:


apiVersion: extensions/v1beta1kind: Deploymentmetadata:    name: grafana-core    namespace: monitoring    labels:        app: grafana        component: corespec:    replicas: 1    template:        metadata:            labels:                app: grafana                component: core        spec:            nodeSelector:                kubernetes.io/hostname: 192.168.10.2            containers:            - image: zqdlove/grafana:v5.0.0                name: grafana-core                imagePullPolicy: IfNotPresent                #securityContext:                  # privileged: true                # env:                resources:                    # keep request = limit to keep this container in guaranteed class                    limits:                        cpu: 10000m                        memory: 32000Mi                    requests:                        cpu: 10000m                        memory: 32000Mi                env:                    # The following env variables set up basic auth twith the                       default admin user and admin password                    - name: GF_AUTH_BASIC_ENABLED                        value: "true"                    - name: GF_AUTH_ANONYMOUS_ENABLED                        value: "false"                    # - name: GF_AUTH_ANONYMOUS_ORG_ROLE                    #   value: Admin                    # does not really work, because of template variables in exported                       dashboards:                    # - name: GF_DASHBOARDS_JSON_ENABLED                    #   value: "true"                readinessProbe:                    httpGet:                        path: /login                        port: 3000                    # initialDelaySeconds: 30                    # timeoutSeconds: 1                volumeMounts:                - name: grafana-persistent-storage                    mountPath: /var                - name: grafana                    mountPath: /etc/grafana       # - name: grafana-ldap-grafana       #   mountPath: /etc/grafana       # - name: grafana-ldap-conf       #   mountPath: /usr/share/grafana/conf            volumes:            - name: grafana-persistent-storage                emptyDir: {}            - name: grafana                hostPath:                    path: /etc/grafana          # - name: grafana-ldap-grafana            #  configMap:              #   name: grafana-ldap-grafana-configmap     # - name: grafana-ldap-conf     #   configMap:     #     name: grafana-ldap-conf-configmap
复制代码


查看 monitoring 命令空间下名为 grafana-core 的 deployment 的状态,信息如下:


$ kubectl get deployment grafana-core -n monitoringNAME         DESIRED  CURRENT  UP-TO-DATE      AVAILABLE    AGEgrafana-core   1         1         1            1           1d
复制代码


要查看 monitoring 命令空间下名为 grafana-core 的 deployment 的详细信息,使用以下命令:


$ kubectl get deployment grafana-core -n monitoring -o yaml$ kubectl describe deployment grafana-core -n monitoring
复制代码


创建 grafana ingress 实现外部域名访问,命令如下:


$ kubectl create -f grafana-ingress.yaml
复制代码


grafana-ingress.yaml 文件内容如下:


apiVersion: extensions/v1beta1kind: Ingressmetadata:    name: traefik-grafana    namespace: monitoringspec:    rules:    - host: grafana.test.com        http:            paths:            - path: /                backend:                    serviceName: grafana                    servicePort: 4444
复制代码


查看 monitoring 命名空间下名为 traefik-grafana 的 Ingress,使用以下命令:


$ kubectl get ingress traefik-grafana -n monitoringNAME         HOSTS             ADDRESS   PORTS     AGEtraefik-grafana   grafana.test.com         80        1d
复制代码


查看 monitoring 命名空间下名为 traefik-grafana 的 Ingress 的详细信息,使用以下命令:


$ kubectl get ingress traefik-grafana  -n monitoring -o yaml
复制代码


将 grafana.test.com 解析到 Ingress 服务器,此时可以通过 grafana.test.com 访问 Grafana 的监控展示的界面。


三、通过 Operator 方式部署 Prometheus


传统方式部署步骤相对复杂,随着 Operator 的日益成熟,推荐使用 Operator 方式部署 Prometheus。通过 Operator 方式部署 Prometheus,可将更多的操作集成到 Operator 中,简化了操作过程,也使部署更加简单。本节详细介绍在 Kubernetes 中使用 Operator 方式部署整套 Prometheus 监控。


1、Kubernetes 基础环境


部署 Prometheus 依赖的基础环境如下:


  • Kubernetes版本为1.14.0。

  • helm版本为v2.13.1。

  • 按需要安装coreDNS、Nginx。


本节使用 Helm 安装。Helm chart 根据实际使用修改。


2、安装 Prometheus Operator


使用 git 下载 prometheus-operator 源码,并进入到源码目录,如下所示:


git clone https:// github.com/coreos/prometheus-operator.gitcd prometheus-operator
复制代码


使用 git 将软件切换到 v0.29.0 版本,并进入到 helm 目录:


git checkout -b  v0.29.0 v0.29.0cd helm
复制代码


使用 helm 在名为 monitoring 的命名空间下安装 prometheus-operator,命令如下:


helm install prometheus-operator --name prometheus-operator --namespace monitoring
复制代码


使用 helm 命令查看安装结果,命令如下:


$ helm ls prometheus-operatorNAME REVISION      UPDATE DSTATUS CHART APP VERSION    NAMESPACEprometheus-operator 1 Thu Apr 11 10:30:11 2019DEPLOYED    prometheus-operator-0.0.29 0.20.0monitoring
复制代码


3、部署 kube-prometheus


创建 kube-prometheus/charts 目录,使用如下命令:


mkdir -p kube-prometheus/charts
复制代码


使用 Helm 打包 kube-prometheus 所依赖的 chart 包,命令如下:


helm package -d kube-prometheus/charts alertmanager grafana prometheus exporter-kube-dns  exporter-kube-scheduler  exporter-kubelets  exporter-node  exporter-kube-controller-manager  exporter-kube-etcd  exporter-kube-state  exporter-coredns  exporter-kubernetes
复制代码


使用 Helm 在名为 monitoring 的命名空间下安装 kube-prometheus,具体命令如下:


helm install kube-prometheus --name kube-prometheus --namespace monitoring
复制代码


使用以下命令查看安装结果:


$ helm ls kube-prometheusNAME REVISION UPDATED STATUSCHART APP VERSION     NAMESPACEkube-prometheus 1 Thu Apr 11 11:55:44 2019 DEPLOYED kube-prometheus-0.0.105 monitoring
复制代码


四、服务配置


本节主要介绍 Prometheus 的静态配置和服务发现配置,以及静态配置和动态服务发现配置的用法。


1、静态配置


静态配置是 Prometheus 中简单的配置,指定获取指标的地址,并分配所获取指标的标签。Prometheus 最简单的配置是静态目标,如下配置文件:


scrape_configs:    - job_name: 'prometheus'        static_configs:            - targets: ['localhost:9090', 'localhost:9100']                labels:                    group: 'prometheus'
复制代码


scrape_configs 表示定义收集规则,指定了:localhost:9090 和 localhost:9100 作为获取信息的地址,并给获取的信息打上了 group=prometheus 的标签。


2、服务发现配置


Prometheus 支持多种服务发现机制:文件、DNS、Consul、Kubernetes、OpenStack、EC2 等。基于服务发现的过程并不复杂,通过第三方提供的接口,Prometheus 查询到需要监控的 Target 列表,然后轮训这些 Target 获取监控数据,下面主要介绍 Kubernetes 服务发现机制。


目前,在 Kubernetes 下,Prometheus 通过与 Kubernetes API 集成主要支持 5 种服务发现模式:Node、Service、Pod、Endpoints、Ingress。不同的服务发现模式适用于不同的场景,例如:node 适用于与主机相关的监控资源,如节点中运行的 Kubernetes 组件状态、节点上运行的容器状态等;service 和 igress 适用于通过黑盒监控的场景,如对服务的可用性以及服务质量的监控;endpoints 和 pod 均可用于获取 Pod 实例的监控数据,如监控用户或者管理员部署的支持 Prometheus 的应用。


以下配置文件指定了间歇时间是 30s,超时间是 10s,从目标获取数据的 http 路径是


/metrics,使用 http 协议。kubernetes 服务发现配置列表中指定了服务发现模式为 endpoints,命名空间为 monitoring。relabel_configs 允许在抓取之前对任何目标及其标签进行修改:


scrape_configs:- job_name: monitoring/kube-prometheus/0    scrape_interval: 30s    scrape_timeout: 10s    metrics_path: /metrics    scheme: http    kubernetes_sd_configs:    - api_server: null        role: endpoints        namespaces:            names:            - monitoring    relabel_configs:    - source_labels: [__meta_kubernetes_service_label_app]        separator: ;        regex: prometheus        replacement: $1        action: keep    - source_labels: [__meta_kubernetes_service_label_chart]        separator: ;        regex: prometheus-0.0.51        replacement: $1        action: keep    - source_labels: [__meta_kubernetes_service_label_prometheus]        separator: ;        regex: kube-prometheus        replacement: $1        action: keep    - source_labels: [__meta_kubernetes_endpoint_port_name]        separator: ;        regex: http        replacement: $1        action: keep    - source_labels: [__meta_kubernetes_namespace]        separator: ;        regex: (.*)        target_label: namespace        replacement: $1        action: replace    - source_labels: [__meta_kubernetes_pod_name]        separator: ;        regex: (.*)        target_label: pod        replacement: $1        action: replace    - source_labels: [__meta_kubernetes_service_name]        separator: ;        regex: (.*)        target_label: service        replacement: $1        action: replace    - source_labels: [__meta_kubernetes_service_name]        separator: ;        regex: (.*)        target_label: job        replacement: ${1}        action: replace    - source_labels: [__meta_kubernetes_service_label_app]        separator: ;        regex: (.+)        target_label: job        replacement: ${1}        action: replace    - separator: ;        regex: (.*)        target_label: endpoint        replacement: http        action: replace
复制代码


以上配置文件对应 Prometheus 服务发现界面中 monitoring/kube-prometheus/0,如图 6 所示。



图 6 Prometheus 服务发现


五、监控对象


Prometheus 可以监控 Kubernetes 非常多的对象,本节主要介绍 Docker 容器、kube-apiserver、kube-state-metrics 以及主机等几个方面。完整的 Targets 可以通过 Prometheus 界面查看,如图 7 所示。



图 7 Prometheus 监控 Kubernetes 环境服务


1、容器监控


Kubernetes 直接在 Kubelet 组件中集成了 cAdvisor,cAdvisor 会自动采集当前节点上容器 CPU、内存、文件系统,网络等资源的使用情况。以下是 Prometheus 配置中容器监控的部分代码:


- job_name: monitoring/kube-prometheus-exporter-kubelets/1    honor_labels: true    scrape_interval: 30s    scrape_timeout: 10s    metrics_path: /metrics/cadvisor    scheme: https    kubernetes_sd_configs:    - api_server: null        role: endpoints        namespaces:            names:            - kube-system    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token    tls_config:        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt        insecure_skip_verify: true    relabel_configs:    - source_labels: [__meta_kubernetes_service_label_k8s_app]        separator: ;        regex: kubelet        replacement: $1        action: keep    - separator: ;        regex: (.*)        target_label: endpoint        replacement: https-metrics        action: replace
复制代码


以上配置文件指定了间歇时间为 30s,超时间为 10s,从目标获取数据的 http 路径是


/metrics/cadvisor,使用 https 协议,指定了服务发现模式为 endpoints,命名空间为 kube-system,指定了 token file 和 tls ca file。relabel_configs 允许在抓取之前对任何目标及其标签进行修改,指定了 source_labels 为__meta_kubernetes_service_label_k8s_app。


2、kube-apiserver 监控


apiserver 的监控主要是 kube-apiserver,配置文件与容器监控类似。Prometheus 配置中关联 job 的部分配置文件如下:


- job_name: monitoring/kube-prometheus-exporter-kubernetes/0    scrape_interval: 15s    scrape_timeout: 10s    metrics_path: /metrics    scheme: https    kubernetes_sd_configs:    - api_server: null        role: endpoints        namespaces:            names:            - default    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token    tls_config:        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt        insecure_skip_verify: true    relabel_configs:    - source_labels: [__meta_kubernetes_service_label_component]        separator: ;        regex: apiserver        replacement: $1        action: keep    - source_labels: [__meta_kubernetes_endpoint_port_name]        separator: ;        regex: https        replacement: $1        action: keep    - separator: ;        regex: (.*)        target_label: endpoint        replacement: https        action: replace

复制代码


3、kube-state-metrics 监控


kube-state-metrics 关注于获取 Kubernetes 中各种资源的最新状态,如 deployment 或者 daemonset。prometheus 中关联 kube-state-metrics 的部分配置文件内容如下:


- job_name: monitoring/kube-prometheus-exporter-kube-state/0    honor_labels: true    scrape_interval: 15s    scrape_timeout: 10s    metrics_path: /metrics    scheme: http    kubernetes_sd_configs:    - api_server: null        role: endpoints        namespaces:            names:            - monitoring    relabel_configs:    - source_labels: [__meta_kubernetes_service_label_app]        separator: ;        regex: exporter-kube-state        replacement: $1        action: keep    - source_labels: [__meta_kubernetes_service_label_component]        separator: ;        regex: kube-state        replacement: $1        action: keep    - separator: ;        regex: (.*)        target_label: endpoint        replacement: kube-state-metrics        action: replace
复制代码


4、主机监控


主机监控是通过 node-exporter 组件来获取操作系统层面信息的,关联配置文件如下:


- job_name: monitoring/kube-prometheus-exporter-node/0    scrape_interval: 15s    scrape_timeout: 10s    metrics_path: /metrics    scheme: http    kubernetes_sd_configs:    - api_server: null        role: endpoints        namespaces:            names:            - monitoring    relabel_configs:    - source_labels: [__meta_kubernetes_service_label_app]        separator: ;        regex: exporter-node        replacement: $1        action: keep    - separator: ;        regex: (.*)        target_label: endpoint        replacement: metrics        action: replace
复制代码


六、数据展现


随着业务越来越复杂,对软件系统的要求也越来越高,这意味着我们需要随时掌控系统的运行情况。因此,对系统的实时监控以及可视化展示,就成了基础架构的必须能力。Grafana 是一个跨平台开源的度量分析和可视化工具,可以将采集的数据查询可视化地展示,并及时通知。


前面小节讨论监控数据的收集和部分处理,本节会使用已收集并处理的数据,通过 Grafana 展示到 Web 界面。主要包括在 Kubernetes 中部署、配置和使用 Grafana。


1、在 Kubernetes 集群中安装 Grafana


使用 helm 在名为 monitoring 的命名空间下安装 Grafana。命令如下:


helm install --name grafana grafana/ --namespace monitoring
复制代码


使用以下命令查看安装结果:


$ helm ls grafanaNAME REVISION UPDATEDSTATUS CHART     APP VERSION NAMESPACEgrafana    1 Thu Apr 11 11:00:52 2019    DEPLOYED    grafana-0.0.37         monitoring
复制代码


把服务 alertmanager、grafana-grafana、kube-prometheus 的类型改为 NodePort。使用如下命令获取 service 的信息:


$kubectl get svc--namespace monitoring
复制代码


使用如下命令编辑修改 alertmanager、grafana-grafana、kube-prometheus 的 service,将服务类型修改为 NodePort:


$kubectl edit svcalertmanager--namespace monitoring$kubectl edit svcgrafana-grafana--namespace monitoring$kubectl edit svckube-prometheus--namespace monitoring
复制代码


2、配置 Grafana


安装完成后可以打开 Grafana 界面,通过如下命令获取开放的端口号:


$ kubectl get svc grafana-grafana -n monitoringNAME              TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGEgrafana-grafana   NodePort   10.96.120.206   <none>        80:30747/TCP   26d
复制代码


打开http://192.168.99.101:30747配置界面,点击添加数据源。填写 Prometheus 数据源名称类型以及 HTTP URL,保存并测试。测试通过后,添加或导入所需模板。点击主界面 Create—>import,上传或粘贴所需 JSON 文件,点击 Load。Grafana 官方模板下载地址为:


https://grafana.com/dashboards
复制代码


Grafana 有许多可以使用的插件,参见官网:


https://grafana.com/plugins?utm_source=grafana_plugin_list
复制代码


3、集成 Grafana 展示数据


根据前几节的安装配置,可以自由配置展示监控内容。在 Grafana 界面可以查看所有已存在的仪表盘模板列表、已部署的 pod、deployment、statefulset,如图 8 至图 10 所示。



图 8 Grafana 中显示单 pod 状态信息



图 9 Grafana 中显示 Deployment 类型 pod 状态信息



图 10 Grafana 中显示 StatefulSet 类型 pod 状态信息


导入主机信息模板,该模板使用 Node-exporter 获取的数据,展示如图 11 所示。


七、告警


随着业务复杂性的增加,告警系统越来越重要,及时有效的告警可以在故障到来之前,提前预知风险,提前处理问题,将不良影响最小化。


使用 Prometheus 进行告警分为两部分。Prometheus 服务器中的警报规则会向 Alertmanager 发送警报。然后,Alertmanager 管理这些警报,包括静音、禁止、聚合,以及通过电子邮件、PagerDuty 和 HipChat 等方法发送通知。


设置告警和通知的主要步骤如下:


  • 设置并配置Alertmanager。

  • 配置Prometheus与Alertmanager协同信息。

  • 在Prometheus中创建告警规则。


1、安装 Alertmanager


使用 helm 在名为 monitoring 的命名空间下安装 Alertmanager,命令如下:


helm install --name alertmanager alertmanager/ --namespace monitoring
复制代码




图 11 Grafana 中显示 pod 状态信息


使用以下命令查看安装结果:


$ helm ls alertmanagerNAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACEAlertmanager 1 Thu Apr 11 11:00:34 2019 DEPLOYED alertmanager-0.1.70.15.1   monitoring
复制代码


Prometheus 与 Alertmanager 关联配置文件信息如下:


alerting:    alert_relabel_configs:    - separator: ;        regex: prometheus_replica        replacement: $1        action: labeldrop    alertmanagers:    - kubernetes_sd_configs:        - api_server: null            role: endpoints            namespaces:                names:                - monitoring        scheme: http        path_prefix: /        timeout: 10s        relabel_configs:        - source_labels: [__meta_kubernetes_service_name]            separator: ;            regex: kube-prometheus-alertmanager            replacement: $1            action: keep        - source_labels: [__meta_kubernetes_endpoint_port_name]            separator: ;            regex: http            replacement: $1            action: keep
复制代码


2、告警规则


在 Prometheus 全局配置文件中,通过 rule_files 指定一组告警规则文件的访问路径,配置文件如下:


rule_files:- /etc/prometheus/rules/*.yaml
复制代码


默认部署中包含 alertmanager.rules、kube-scheduler.rules、general.rules 等 rules。本节不做详细介绍。


3、微信告警


在某些情况下除了 Alertmanager 已经内置的集中告警通知方式以外,对于不同的用户和组织而言还需要一些自定义的告知方式。通过 Alertmanager 提供的 webhook 支持可以轻松实现这一类的扩展。


首先需要申请微信企业号,申请地址为:


https://work.weixin.qq.com/
复制代码


在 Alertmanager 配置文件中,加入微信配置信息即可:


global:    resolve_timeout: 2m    wechat_api_url: 'https:// qyapi.weixin.qq.com/cgi-bin/'    wechat_api_secret: 'xxx'    wechat_api_corp_id: 'xxx'
route: group_by: ['alertname'] group_wait: 10s group_interval: 10s repeat_interval: 1h receiver: 'wechat'receivers:- name: 'wechat' wechat_configs: - send_resolved: true to_party: '1' agent_id: '1000002'
复制代码


八、小结


Kubernetes 与 Prometheus 有着十分相似的历程,均是源自 Google 内部多年的运维经验,并且相继从 CNCF 基金会正式毕业。它们分别代表了云原生模式下容器编排以及监控的事实标准。


本文首先介绍了 Kubernetes 的监控的基本原理,以及两种基于 Kubernetes 安装 Prometheus 的实际方案。然后介绍了服务发现和监控对象是如何配置。最后通过 Grafana 可视化展示监控界面和 Alertmanager 告警处理。


作者介绍


陈金窗, 资深运维技术专家,从事 IT 基础设施建设、运维与技术管理 20 多年。


刘政委, 资深运维技术与管理人员,大型在线游戏和手游自动化运维老兵。


郑少斌, 长期从事云计算相关产品、研发、运维工作,具备丰富理论及实践经验。


张其栋, 中国电信云公司软件工程师,主要负责私有容器云平台的研发工作。


原文链接


https://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&mid=2650790245&idx=1&sn=def12422bfb5ee20f6311ab742fe9d7c&chksm=f3f96cf0c48ee5e687f019794a72e4838009714610da7479b1426e01c7e95da3001210f1d8d1&scene=27#wechat_redirect


2020 年 6 月 28 日 10:073846

评论

发布
暂无评论
发现更多内容

架构师训练营 1 期 - 第四周 - 系统架构

三板斧

极客大学架构师训练营

ARTS Week13

丽子

架构师训练营第三周课后练习

架构师训练营第一期-第四周课后作业

卖猪肉的大叔

极客大学架构师训练营

架构师训练营第一期-第四周学习总结

卖猪肉的大叔

极客大学架构师训练营

Flink处理函数-6-4

小知识点

scala 大数据 flink

第四周作业

icydolphin

极客大学架构师训练营

架构师训练营第 1 期第四周总结

Leo乐

极客大学架构师训练营

数据库技术丨GaussDB(DWS)数据同步状态查看方法

华为云开发者社区

数据库 高可用

京东区块链之供应链应用篇:溯源应用结合区块链能碰撞出什么火花?

京东智联云开发者

区块链 供应链

阿里云服务器搭建

时间是一个人最好的证明

阿里云 服务器 域名

聊聊前端 UI 组件:组件体系

欧雷

前端工程 组件化 前端工程化

2020.10.05-2020.10.11 学习总结

icydolphin

极客大学架构师训练营

上周,我密集面试了若干位Java后端的候选人,工作经验在3到5年间

Java架构师迁哥

《Java核心技术总结》+《面试题总结》PDF整理,阿里P8大牛熬了半个月肝出来的!

Java架构之路

Java 阿里巴巴 程序员 面试 编程语言

有符号类型引发的奇怪现象

jiangling500

Go 语言内存管理三部曲(二)解密栈内存管理

网管

go 堆栈 内存管理 内存布局

Java 中的反射是什么

Rayjun

Java 反射

架构师训练营第三周总结

研发和测试在多国陆续展开 全球央行数字货币研发驶入快车道

CECBC区块链专委会

数字货币 金融

《Linux学习笔记》从常用命令、常用操作到网络管理、性能优化

Java架构之路

Java Linux 程序员 面试 编程语言

如何设计一个牛逼的API接口

Java旅途

Spring Boot API

架构师训练营第四周作业

Shunyi

极客大学架构师训练营

全面到哭!BAT内部Java求职面试宝典,必须人手一份!

Java成神之路

Java 阿里巴巴 程序员 面试 编程语言

第四周学习代码系统架构总结

三板斧

区块链将这样影响你的生产生活

CECBC区块链专委会

区块链 信息发展

通证、通证经济与区块链

CECBC区块链专委会

区块链 通证经济

5张表的sql整懵阿里p7:你们能看明白自己写的啥吗?

小Q

MySQL 数据库 学习 调优 mycat

架构师训练营第四周总结

从格力直播看品牌商的渠道变革

boshi

数字化转型 品牌 直播带货 优化业务

架构师训练营第四周课后练习

用Prometheus监控Kubernetes,目前最实用的部署方式都说全了-InfoQ