首页 > 技术文章 > Prometheus监控k8s(10)-PrometheusOperator-更优雅的Prometheus部署【转】

zhangrui153169 2020-09-03 18:22 原文

安装部署PrometheusOperator

https://www.cnblogs.com/wangxu01/articles/11655459.html

https://www.qikqiak.com/k8s-book/docs/58.Prometheus%20Operator.html

https://blog.csdn.net/ygqygq2/article/details/83655552

 

1 前言

prometheus用自定义的方式来对 Kubernetes 集群进行监控,但是还是有一些缺陷,比如 Prometheus、AlertManager 这些组件服务本身的高可用,当然也完全可以用自定义的方式来实现这些需求,Promethues 在代码上就已经对 Kubernetes 有了原生的支持,可以通过服务发现的形式来自动监控集群,因此我们可以使用另外一种更加高级的方式来部署 Prometheus:Operator 框架。

Operator

Operator是由CoreOS公司开发的,用来扩展 Kubernetes API,特定的应用程序控制器,它用来创建、配置和管理复杂的有状态应用,如数据库、缓存和监控系统。Operator基于 Kubernetes 的资源和控制器概念之上构建,但同时又包含了应用程序特定的一些专业知识,比如创建一个数据库的Operator,则必须对创建的数据库的各种运维方式非常了解,创建Operator的关键是CRD(自定义资源)的设计。

CRD是对 Kubernetes API 的扩展,Kubernetes 中的每个资源都是一个 API 对象的集合,例如我们在YAML文件里定义的那些spec都是对 Kubernetes 中的资源对象的定义,所有的自定义资源可以跟 Kubernetes 中内建的资源一样使用 kubectl 操作。

Operator是将运维人员对软件操作的知识给代码化,同时利用 Kubernetes 强大的抽象来管理大规模的软件应用。目前CoreOS官方提供了几种Operator的实现,其中就包括我们今天的主角:Prometheus OperatorOperator的核心实现就是基于 Kubernetes 的以下两个概念:

  • 资源:对象的状态定义
  • 控制器:观测、分析和行动,以调节资源的分布

2 Prometheus-Operator简介

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

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

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

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

Prometheus-Operator的架构图:

 

 

 

上图是Prometheus-Operator官方提供的架构图,其中Operator是最核心的部分,作为一个控制器,他会去创建PrometheusServiceMonitorAlertManager以及PrometheusRule4个CRD资源对象,然后会一直监控并维持这4个资源对象的状态。

其中创建的prometheus这种资源对象就是作为Prometheus Server存在,而ServiceMonitor就是exporter的各种抽象,exporter前面我们已经学习了,是用来提供专门提供metrics数据接口的工具,Prometheus就是通过ServiceMonitor提供的metrics数据接口去 pull 数据的,当然alertmanager这种资源对象就是对应的AlertManager的抽象,而PrometheusRule是用来被Prometheus实例使用的报警规则文件。

这样我们要在集群中监控什么数据,就变成了直接去操作 Kubernetes 集群的资源对象了,是不是方便很多了。上图中的 Service 和 ServiceMonitor 都是 Kubernetes 的资源,一个 ServiceMonitor 可以通过 labelSelector 的方式去匹配一类 Service,Prometheus 也可以通过 labelSelector 去匹配多个ServiceMonitor。

 

 

总的来说:

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

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

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

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

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

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

 

3 安装配置

3.1 清理环境

之前自定义安装的环境清除一下,会有很多干扰,例如node-exporter都占用9100端口

3.2 下载源码

直接通过 Prometheus-Operator 的源码来进行安装,当然也可以用 Helm 来进行一键安装,我们采用源码安装可以去了解更多的实现细节。首先将源码 Clone 下来:

最新的版本官方将资源https://github.com/coreos/prometheus-operator/tree/master/contrib/kube-prometheus迁移到了独立的 git 仓库中:https://github.com/coreos/kube-prometheus.git

 

复制代码
[root@k8s-master operator]# git clone https://github.com/coreos/kube-prometheus.git
正克隆到 'kube-prometheus'...
remote: Enumerating objects: 40, done.
remote: Counting objects: 100% (40/40), done.
remote: Compressing objects: 100% (28/28), done.
remote: Total 6581 (delta 14), reused 19 (delta 8), pack-reused 6541
接收对象中: 100% (6581/6581), 4.01 MiB | 208.00 KiB/s, done.
处理 delta 中: 100% (3921/3921), done.
[root@k8s-master operator]# ls
kube-prometheus
[root@k8s-master operator]# cd kube-prometheus/
[root@k8s-master kube-prometheus]# ls
build.sh            example.jsonnet  go.sum            jsonnetfile.lock.json  manifests  sync-to-internal-registry.jsonnet
code-of-conduct.md  examples         hack              kustomization.yaml     NOTICE     tests
DCO                 experimental     jsonnet           LICENSE                OWNERS     test.sh
docs                go.mod           jsonnetfile.json  Makefile               README.md
复制代码

 

3.3 修改metrics配置文件,配置监控kubelet

复制代码
[root@k8s-master manifests]# pwd
/root/prometheus/operator/kube-prometheus/manifests
[root@k8s-master manifests]# ls
00namespace-namespace.yaml                                         node-exporter-clusterRole.yaml
0prometheus-operator-0alertmanagerCustomResourceDefinition.yaml    node-exporter-daemonset.yaml
0prometheus-operator-0podmonitorCustomResourceDefinition.yaml      node-exporter-
[root@k8s-master manifests]# cat prometheus-serviceMonitorKubelet.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    k8s-app: kubelet
  name: kubelet
  namespace: monitoring
spec:
  endpoints:
  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
    honorLabels: true
    interval: 30s
    port: http-metrics
    scheme: http
    tlsConfig:
      insecureSkipVerify: true
  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
    honorLabels: true
    interval: 30s
    metricRelabelings:
    - action: drop
      regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)
      sourceLabels:
      - __name__
    path: /metrics/cadvisor
    port: http-metrics
    scheme: http
    tlsConfig:
      insecureSkipVerify: true
  jobLabel: k8s-app
  namespaceSelector:
    matchNames:
    - kube-system
  selector:
    matchLabels:
      k8s-app: kubelet
复制代码

 

修改 kubelet 打开只读端口

prometheus 需要访问 kubelet 的 10255 端口获取 metrics。但是默认情况下 10255 端口是不开放的,会导致 prometheus 上有 unhealthy。打开只读端口需要编辑所有节点的vi /var/lib/kubelet/config.yaml (我这里有图形界面可以用gedit命令)文件,加入以下内容

port: 10250
readOnlyPort: 10255          #增加此行

 

重启 kubelet 服务  

1
systemctl restart kubelet.service

 

3.4 部署

修改完成后,直接在该文件夹下面执行创建资源命令即可:

1
kubectl apply -f .

 

 

3.5 部署验证

部署完成后,会创建一个名为monitoring的 namespace,所以资源对象对将部署在改命名空间下面,此外 Operator 会自动创建5个 CRD 资源对象:

复制代码
[root@k8s-master manifests]# kubectl get crd |grep coreos
alertmanagers.monitoring.coreos.com     2019-09-26T02:22:11Z
podmonitors.monitoring.coreos.com       2019-09-26T02:22:11Z
prometheuses.monitoring.coreos.com      2019-09-26T02:22:12Z
prometheusrules.monitoring.coreos.com   2019-09-26T02:22:12Z
servicemonitors.monitoring.coreos.com   2019-09-26T02:22:12Z
[root@k8s-master manifests]#
复制代码

 

 

可以在 monitoring 命名空间下面查看所有的 Pod,其中 alertmanager 和 prometheus 是用 StatefulSet 控制器管理的,其中还有一个比较核心的 prometheus-operator 的 Pod,用来控制其他资源对象和监听对象变化的:

复制代码
[root@k8s-master manifests]# kubectl get pods -n monitoring
NAME                                  READY   STATUS    RESTARTS   AGE
alertmanager-main-0                   2/2     Running   0          2m49s
alertmanager-main-1                   2/2     Running   0          2m49s
alertmanager-main-2                   2/2     Running   0          2m49s
grafana-57bfdd47f8-89jmq              1/1     Running   0          14m
kube-state-metrics-ff5cb7949-8tbqj    3/3     Running   0          14m
node-exporter-6pqr7                   2/2     Running   0          14m
node-exporter-sktbx                   2/2     Running   0          14m
node-exporter-v8hcc                   2/2     Running   0          14m
prometheus-adapter-668748ddbd-zqllq   1/1     Running   0          14m
prometheus-k8s-0                      3/3     Running   1          2m47s
prometheus-k8s-1                      3/3     Running   1          2m47s
prometheus-operator-55b978b89-6wtlf   1/1     Running   0          14m
[root@k8s-master manifests]#
复制代码

 

 

查看创建的 Service:

复制代码
[root@k8s-master manifests]# kubectl get svc -n monitoring
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
alertmanager-main       ClusterIP   10.97.193.245   <none>        9093/TCP                     14m
alertmanager-operated   ClusterIP   None            <none>        9093/TCP,9094/TCP,9094/UDP   3m14s
grafana                 ClusterIP   10.100.31.73    <none>        3000/TCP                     14m
kube-state-metrics      ClusterIP   None            <none>        8443/TCP,9443/TCP            14m
node-exporter           ClusterIP   None            <none>        9100/TCP                     14m
prometheus-adapter      ClusterIP   10.97.88.175    <none>        443/TCP                      14m
prometheus-k8s          ClusterIP   10.97.199.239   <none>        9090/TCP                     14m
prometheus-operated     ClusterIP   None            <none>        9090/TCP                     3m13s
prometheus-operator     ClusterIP   None            <none>        8080/TCP                     14m
[root@k8s-master manifests]#
复制代码

 

 

3.6 配置grafana和prometheus外网访问

针对 grafana 和 prometheus 都创建了一个类型为 ClusterIP 的 Service,当然如果我们想要在外网访问这两个服务的话可以通过创建对应的 Ingress 对象或者使用 NodePort 类型的 Service,我们这里为了简单,直接使用 NodePort 类型的服务即可,编辑 grafana 和 prometheus-k8s 这两个 Service,将服务类型更改为 NodePort:

 

复制代码
[root@k8s-master manifests]# kubectl edit svc grafana -n monitoring
service/grafana edited
[root@k8s-master manifests]# kubectl edit svc prometheus-k8s -n monitoring
service/prometheus-k8s edited
[root@k8s-master manifests]# kubectl get svc -n monitoring| grep -E "grafana|prometheus-k8s"
grafana                 NodePort    10.100.31.73    <none>        3000:32339/TCP               35m
prometheus-k8s          NodePort    10.97.199.239   <none>        9090:31466/TCP               35m
[root@k8s-master manifests]#
复制代码

 

3.7        外网访问

grafana

 

 

 

 

prometheus

 

 

 

 

 

3.8  监控k8s二进制组件

3大组件,kubelet上面自动配置了

可以看到大部分的配置都是正常的,只有两三个没有管理到对应的监控目标,比如 kube-controller-manager 和 kube-scheduler 这两个系统组件,这就和 ServiceMonitor 的定义有关系了

复制代码
[root@k8s-master manifests]# cat  prometheus-serviceMonitorKubeScheduler.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    k8s-app: kube-scheduler
  name: kube-scheduler
  namespace: monitoring
spec:
  endpoints:
  - interval: 30s # 每30s获取一次信息
    port: http-metrics  # 对应service的端口名
  jobLabel: k8s-app
  namespaceSelector: # 表示去匹配某一命名空间中的service,如果想从所有的namespace中匹配用any: true
    matchNames:
    - kube-system
  selector:  # 匹配的 Service 的labels,如果使用mathLabels,则下面的所有标签都匹配时才会匹配该service,如果使用matchExpressions,则至少匹配一个标签的service都会被选择
    matchLabels:
      k8s-app: kube-scheduler

[root@k8s-master manifests]# cat prometheus-serviceMonitorKubeControllerManager.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    k8s-app: kube-controller-manager
  name: kube-controller-manager
  namespace: monitoring
spec:
  endpoints:
  - interval: 30s
    metricRelabelings:
    - action: drop
      regex: etcd_(debugging|disk|request|server).*
      sourceLabels:
      - __name__
    port: http-metrics
  jobLabel: k8s-app
  namespaceSelector:
    matchNames:
    - kube-system
  selector:
    matchLabels:
      k8s-app: kube-controller-manager
复制代码

 

上面是一个典型的 ServiceMonitor 资源文件的声明方式,上面我们通过selector.matchLabels在 kube-system 这个命名空间下面匹配具有k8s-app=kube-scheduler这样的 Service,但是我们系统中根本就没有对应的 Service,所以我们需要手动创建一个 Service:

prometheus-kube-controller-manager-service.yaml

prometheus-kube-scheduler-service.yaml

 

复制代码
[root@k8s-master manifests]# cat  prometheus-kube-controller-manager-service.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: kube-system
  name: kube-controller-manager
  labels:
    k8s-app: kube-controller-manager
spec:
  selector:
    component: kube-controller-manager
  ports:
  - name: http-metrics
    port: 10252
    targetPort: 10252
    protocol: TCP
复制代码

 

复制代码
[root@k8s-master manifests]# cat  prometheus-kube-scheduler-service.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: kube-system
  name: kube-scheduler
  labels:
    k8s-app: kube-scheduler
spec:
  selector:
    component: kube-scheduler
  ports:
  - name: http-metrics
    port: 10251
    targetPort: 10251
    protocol: TCP
复制代码

 

#10251是kube-scheduler组件 metrics 数据所在的端口,10252是kube-controller-manager组件的监控数据所在端口。

 

 

上面 labels 和 selector 部分,labels 区域的配置必须和我们上面的 ServiceMonitor 对象中的 selector 保持一致,selector下面配置的是component=kube-scheduler,为什么会是这个 label 标签呢,我们可以去 describe 下 kube-scheduelr 这个 Pod

 

复制代码
[root@k8s-master manifests]#  kubectl describe pod kube-scheduler-k8s-master -n kube-system
Name:                 kube-scheduler-k8s-master
Namespace:            kube-system
Priority:             2000000000
Priority Class Name:  system-cluster-critical
Node:                 k8s-master/10.6.76.25
Start Time:           Thu, 29 Aug 2019 09:21:01 +0800
Labels:               component=kube-scheduler
                      tier=control-plane
...
复制代码

 

 

复制代码
[root@k8s-master manifests]#  kubectl describe pod kube-controller-manager-k8s-master -n kube-system
Name:                 kube-controller-manager-k8s-master
Namespace:            kube-system
Priority:             2000000000
Priority Class Name:  system-cluster-critical
Node:                 k8s-master/10.6.76.25
Start Time:           Thu, 29 Aug 2019 09:21:01 +0800
Labels:               component=kube-controller-manager
                      tier=control-plane
复制代码

 

 

我们可以看到这个 Pod 具有component=kube-schedulertier=control-plane这两个标签,而前面这个标签具有更唯一的特性,所以使用前面这个标签较好,这样上面创建的 Service 就可以和我们的 Pod 进行关联了,直接创建即可:

 

复制代码
kubectl create -f prometheus-kube-scheduler-service.yaml
kubectl create -f prometheus-kube-controller-manager-service.yaml

[root@k8s-master manifests]# kubectl get svc -n kube-system  | grep -E "contr|sche"
kube-controller-manager    ClusterIP   10.105.206.57    <none>        10252/TCP                86s
kube-scheduler             ClusterIP   10.108.11.188    <none>        10251/TCP                21m
[root@k8s-master manifests]#
复制代码

 

 

 

有文章说需要修改kube-scheduler和kube- controller-manager绑定地址,我没有遇到

 

 

 

 

 

如果需要修改

$ ls /etc/kubernetes/manifests/
etcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml  kube-scheduler.yam

 

将 kube-scheduler.yaml 文件中-command--address地址更改成0.0.0.0

containers:
- command:
- kube-scheduler
- --leader-elect=true
- --kubeconfig=/etc/kubernetes/scheduler.conf
- --address=0.0.0.0

 

 

4 grafana-dashboart展示

上面的监控数据配置完成后,现在我们可以去查看下 grafana 下面的 dashboard,同样使用上面的 NodePort 访问即可,第一次登录使用 admin:admin 登录即可,进入首页后,可以发现已经和我们的 Prometheus 数据源关联上了,正常来说可以看到一些监控图表了:

 

 

 

 

自动配置很多模板

 

 

 

 

 

 

 

 

5 配置alertmanger展示

编辑alertmanager-main Service,将服务类型更改为 NodePort:

 

复制代码
[root@k8s-master manifests]# kubectl get svc -n monitoring| grep alertmanager-main
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
alertmanager-main       ClusterIP   10.97.193.245   <none>        9093/TCP                     4h28m
[root@k8s-master manifests]# kubectl edit svc alertmanager-main -n monitoring
service/alertmanager-main edited
[root@k8s-master manifests]# kubectl get svc -n monitoring | grep alertmanager-main
alertmanager-main       NodePort    10.97.193.245   <none>        9093:31067/TCP               4h30m
[root@k8s-master manifests]#
复制代码

 




推荐阅读