安裝部署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 Operator
,Operator
的核心實現就是基於 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
是最核心的部分,作為一個控制器,他會去創建Prometheus
、ServiceMonitor
、AlertManager
以及PrometheusRule
4個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-scheduler
和tier=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]#