日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Prometheus监控kubernetes

發布時間:2024/3/13 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Prometheus监控kubernetes 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Prometheus監控 kubernetes

咱們的目標通過Prometheus監控Kubernetes集群。

1.使用ConfigMaps管理Prometheus的配置文件

創建prometheus-config.yml文件,并寫入以下內容

apiVersion: v1 kind: ConfigMap metadata:name: prometheus-config data:prometheus.yml: |global:scrape_interval: 15sevaluation_interval: 15sscrape_configs:- job_name: 'prometheus'static_configs:- targets: ['localhost:9090']

使用kubectl命令行工具,在命名空間default創建ConfigMap資源:

kubectl create -f prometheus-config.yml configmap "prometheus-config" created

2.使用Deployment部署Prometheus

當ConfigMap資源創建成功后,我們就可以通過Volume掛載的方式,將Prometheus的配置文件掛載到容器中。 這里我們通過Deployment部署Prometheus Server實例,創建prometheus-deployment.yml文件,并寫入以下內容:

apiVersion: v1 kind: "Service" metadata:name: prometheuslabels:name: prometheus spec:ports:- name: prometheusprotocol: TCPport: 9090targetPort: 9090selector:app: prometheustype: NodePort --- apiVersion: apps/v1 kind: Deployment metadata:labels:name: prometheusname: prometheus spec:replicas: 1selector:matchLabels:app: prometheustemplate:metadata:labels:app: prometheusspec:containers:- name: prometheusimage: prom/prometheus:v2.2.1command:- "/bin/prometheus"args:- "--config.file=/etc/prometheus/prometheus.yml"ports:- containerPort: 9090protocol: TCPvolumeMounts:- mountPath: "/etc/prometheus"name: prometheus-configvolumes:- name: prometheus-configconfigMap:name: prometheus-config

該文件中分別定義了Service和Deployment,Service類型為NodePort,這樣我們可以通過虛擬機IP和端口訪問到Prometheus實例。為了能夠讓Prometheus實例使用ConfigMap中管理的配置文件,這里通過volumes聲明了一個磁盤卷。并且通過volumeMounts將該磁盤卷掛載到了Prometheus實例的/etc/prometheus目錄下。

使用以下命令創建資源,并查看資源的創建情況:

[root@master-1 prometheus]# kubectl create -f prometheus-deployment.yml service "prometheus" created deployment "prometheus" created[root@master-1 prometheus]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deploy-fb74b55d4-gz6cz 1/1 Running 2 (2d3h ago) 3d prometheus-b487b9dfc-n74nv 1/1 Running 0 2d1h [root@master-1 prometheus]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d1h nginx-svc NodePort 10.104.88.55 <none> 80:30523/TCP 3d prometheus NodePort 10.100.208.234 <none> 9090:32053/TCP 2d2h

我們可以通過worker虛擬機的IP地址和端口32053訪問http://192.168.5.21:32053到Prometheus的服務。

但是這里只有Prometheus 9000的監控。接下來,我們配置Prometheus的config 和 rbac開始監控k8s.

3.kubernetes的服務發現

3.1kubernetes的訪問授權

為了能夠讓Prometheus能夠訪問收到認證保護的Kubernetes API,我們首先需要做的是,對Prometheus進行訪問授權。在Kubernetes中主要使用基于角色的訪問控制模型(Role-Based Access Control),用于管理Kubernetes下資源訪問權限。首先我們需要在Kubernetes下定義角色(ClusterRole),并且為該角色賦予相應的訪問權限。同時創建Prometheus所使用的賬號(ServiceAccount),最后則是將該賬號與角色進行綁定(ClusterRoleBinding)。這些所有的操作在Kubernetes同樣被視為是一系列的資源,可以通過YAML文件進行描述并創建,這里創建prometheus-rbac-setup.yml文件,并寫入以下內容:

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:name: prometheus rules: - apiGroups: [""]resources:- nodes- nodes/proxy- services- endpoints- podsverbs: ["get", "list", "watch"] - apiGroups:- extensionsresources:- ingressesverbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics"]verbs: ["get"] --- apiVersion: v1 kind: ServiceAccount metadata:name: prometheusnamespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: prometheus roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: prometheus subjects: - kind: ServiceAccountname: prometheusnamespace: default

其中需要注意的是ClusterRole是全局的,不需要指定命名空間。而ServiceAccount是屬于特定命名空間的資源。通過kubectl命令創建RBAC對應的各個資源:

$ kubectl create -f prometheus-rbac-setup.yml clusterrole "prometheus" created serviceaccount "prometheus" created clusterrolebinding "prometheus" created

在完成角色權限以及用戶的綁定之后,就可以指定Prometheus使用特定的ServiceAccount創建Pod實例。修改prometheus-deployment.yml文件,并添加serviceAccountName和serviceAccount定義:

apiVersion: v1 kind: "Service" metadata:name: prometheuslabels:name: prometheus spec:ports:- name: prometheusprotocol: TCPport: 9090targetPort: 9090selector:app: prometheustype: NodePort --- apiVersion: apps/v1 kind: Deployment metadata:labels:name: prometheusname: prometheus spec:replicas: 1selector:matchLabels:app: prometheustemplate:metadata:labels:app: prometheusspec:serviceAccountName: prometheus # 添加ServiceAccountName containers:- name: prometheusimage: prom/prometheus:v2.2.1command:- "/bin/prometheus"args:- "--config.file=/etc/prometheus/prometheus.yml"ports:- containerPort: 9090protocol: TCPvolumeMounts:- mountPath: "/etc/prometheus"name: prometheus-configvolumes:- name: prometheus-configconfigMap:name: prometheus-config

通過kubectl apply對Deployment進行變更升級:

$ kubectl apply -f prometheus-deployment.yml service "prometheus" configured deployment "prometheus" configured[root@master-1 prometheus]# kubectl get pod NAME READY STATUS RESTARTS AGE prometheus-b487b9dfc-n73dv 0/1 Terminating 0 3d prometheus-b487b9dfc-n74nv 1/1 Running 0 2d1h

指定ServiceAccount創建的Pod實例中,會自動將用于訪問Kubernetes API的CA證書以及當前賬戶對應的訪問令牌文件掛載到Pod實例的/var/run/secrets/kubernetes.io/serviceaccount/目錄下,可以通過以下命令進行查看:

[root@master-1 prometheus]# kubectl exec -it prometheus-b487b9dfc-n74nv -- ls /var/run/secrets/kubernetes.io/serviceaccount/ ca.crt namespace token

3.2服務發現

在Kubernetes下,Promethues通過與Kubernetes API集成目前主要支持5種服務發現模式,分別是:Node、Service、Pod、Endpoints、Ingress。

通過kubectl命令行,可以方便的獲取到當前集群中的所有節點信息:

[root@master-1 prometheus]# kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME master-1 Ready control-plane,master 3d1h v1.22.1 192.168.5.11 <none> CentOS Linux 7 (Core) 3.10.0-1160.49.1.el7.x86_64 docker://20.10.12 master-2 Ready control-plane,master 3d1h v1.22.1 192.168.5.12 <none> CentOS Linux 7 (Core) 3.10.0-1160.49.1.el7.x86_64 docker://20.10.12 master-3 Ready control-plane,master 3d1h v1.22.1 192.168.5.13 <none> CentOS Linux 7 (Core) 3.10.0-1160.49.1.el7.x86_64 docker://20.10.12 worker-1 Ready <none> 3d1h v1.22.1 192.168.5.21 <none> CentOS Linux 7 (Core) 3.10.0-1160.49.1.el7.x86_64 docker://20.10.12

為了能夠讓Prometheus能夠獲取到當前集群中所有節點的信息,在Promtheus的配置文件中,我們添加如下Job配置:

- job_name: 'kubernetes-nodes'tls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: node

通過指定kubernetes_sd_config的模式為node,Prometheus會自動從Kubernetes中發現到所有的node節點并作為當前Job監控的Target實例。如下所示,這里需要指定用于訪問Kubernetes API的ca以及token文件路徑。

對于Ingress,Service,Endpoints, Pod的使用方式也是類似的,下面給出了一個完整Prometheus配置的示例:

apiVersion: v1 data:prometheus.yml: |-global:scrape_interval: 15s evaluation_interval: 15sscrape_configs:- job_name: 'kubernetes-nodes'tls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: node- job_name: 'kubernetes-service'tls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: service- job_name: 'kubernetes-endpoints'tls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: endpoints- job_name: 'kubernetes-ingress'tls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: ingress- job_name: 'kubernetes-pods'tls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: podkind: ConfigMap metadata:name: prometheus-config

更新Prometheus配置文件,并重建Prometheus實例:

$ kubectl apply -f prometheus-config.yml configmap "prometheus-config" configured[root@master-1 prometheus]# kubectl get pod NAME READY STATUS RESTARTS AGE prometheus-b487b9dfc-n74nv 1/1 Running 0 2d1h[root@master-1 prometheus]# kubectl delete pod prometheus-b487b9dfc-n74nv pod "prometheus-b487b9dfc-n74nv" deleted[root@master-1 prometheus]# kubectl get pod NAME READY STATUS RESTARTS AGE prometheus-b487b9dfc-s2rrr 1/1 Running 0 5s

Prometheus使用新的配置文件重建之后,打開Prometheus UI,通過Service Discovery頁面可以查看到當前Prometheus通過Kubernetes發現的所有資源對象了:

同時Prometheus會自動將該資源的所有信息,并通過標簽的形式體現在Target對象上。如下所示,是Promthues獲取到的Node節點的標簽信息:

__address__="192.168.5.13:10250" __meta_kubernetes_node_address_Hostname="master-3" __meta_kubernetes_node_address_InternalIP="192.168.5.13" __meta_kubernetes_node_annotation_flannel_alpha_coreos_com_backend_data="{"VNI":1,"VtepMAC":"56:87:0f:ed:d7:eb"}" __meta_kubernetes_node_annotation_flannel_alpha_coreos_com_backend_type="vxlan" __meta_kubernetes_node_annotation_flannel_alpha_coreos_com_kube_subnet_manager="true" __meta_kubernetes_node_annotation_flannel_alpha_coreos_com_public_ip="192.168.5.13" __meta_kubernetes_node_annotation_kubeadm_alpha_kubernetes_io_cri_socket="/var/run/dockershim.sock" __meta_kubernetes_node_annotation_node_alpha_kubernetes_io_ttl="0" __meta_kubernetes_node_annotation_volumes_kubernetes_io_controller_managed_attach_detach="true" __meta_kubernetes_node_label_beta_kubernetes_io_arch="amd64" __meta_kubernetes_node_label_beta_kubernetes_io_os="linux" __meta_kubernetes_node_label_kubernetes_io_arch="amd64" __meta_kubernetes_node_label_kubernetes_io_hostname="master-3" __meta_kubernetes_node_label_kubernetes_io_os="linux" __meta_kubernetes_node_label_node_kubernetes_io_exclude_from_external_load_balancers="" __meta_kubernetes_node_label_node_role_kubernetes_io_control_plane="" __meta_kubernetes_node_label_node_role_kubernetes_io_master="" __meta_kubernetes_node_name="master-3" __metrics_path__="/metrics" __scheme__="http" instance="master-3" job="kubernetes-nodes"

目前為止,我們已經能夠通過Prometheus自動發現Kubernetes集群中的各類資源以及其基本信息。不過,如果現在查看Promtheus的Target狀態頁面,結果可能會讓人不太滿意:

雖然Prometheus能夠自動發現所有的資源對象,并且將其作為Target對象進行數據采集。 但并不是所有的資源對象都是支持Promethues的,并且不同類型資源對象的采集方式可能是不同的。因此,在實際的操作中,我們需要有明確的監控目標,并且針對不同類型的監控目標設置不同的數據采集方式。

接下來,我們將利用Promtheus的服務發現能力,實現對Kubernetes集群的全面監控。

4.監控kubernetes集群

我們介紹了Promtheus在Kubernetes下的服務發現能力,并且通過kubernetes_sd_config實現了對Kubernetes下各類資源的自動發現。在本小節中,我們將帶領讀者利用Promethues提供的服務發現能力,實現對Kubernetes集群以及其中部署的各類資源的自動化監控。

下表中,梳理了監控Kubernetes集群監控的各個維度以及策略:

目標服務發現模式監控方法數據源
從集群各節點kubelet組件中獲取節點kubelet的基本運行狀態的監控指標node白盒監控kubelet
從集群各節點kubelet內置的cAdvisor中獲取,節點中運行的容器的監控指標node白盒監控kubelet
從部署到各個節點的Node Exporter中采集主機資源相關的運行資源node白盒監控node exporter
對于內置了Promthues支持的應用,需要從Pod實例中采集其自定義監控指標pod白盒監控custom pod
獲取API Server組件的訪問地址,并從中獲取Kubernetes集群相關的運行監控指標endpoints白盒監控api server
獲取集群中Service的訪問地址,并通過Blackbox Exporter獲取網絡探測指標service黑盒監控blackbox exporter
獲取集群中Ingress的訪問信息,并通過Blackbox Exporter獲取網絡探測指標ingress黑盒監控blackbox exporter

4.1從Kubelet獲取節點運行狀態

Kubelet組件運行在Kubernetes集群的各個節點中,其負責維護和管理節點上Pod的運行狀態。kubelet組件的正常運行直接關系到該節點是否能夠正常的被Kubernetes集群正常使用。

基于Node模式,Prometheus會自動發現Kubernetes中所有Node節點的信息并作為監控的目標Target。 而這些Target的訪問地址實際上就是Kubelet的訪問地址,并且Kubelet實際上直接內置了對Promtheus的支持。

修改prometheus.yml配置文件,并添加以下采集任務配置:

- job_name: 'kubernetes-kubelet'scheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: noderelabel_configs:- action: labelmapregex: __meta_kubernetes_node_label_(.+)

這里使用Node模式自動發現集群中所有Kubelet作為監控的數據采集目標,同時通過labelmap步驟,將Node節點上的標簽,作為樣本的標簽保存到時間序列當中。

重新加載promethues配置文件,并重建Promthues的Pod實例后,查看kubernetes-kubelet任務采集狀態,我們會看到以下錯誤提示信息:

Get https://192.168.99.100:10250/metrics: x509: cannot validate certificate for 192.168.99.100 because it doesn't contain any IP SANs

這是由于當前使用的ca證書中,并不包含192.168.99.100的地址信息。為了解決該問題,第一種方法是直接跳過ca證書校驗過程,通過在tls_config中設置 insecure_skip_verify為true即可。 這樣Promthues在采集樣本數據時,將會自動跳過ca證書的校驗過程,從而從kubelet采集到監控數據:

- job_name: 'kubernetes-kubelet'scheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtinsecure_skip_verify: truebearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: noderelabel_configs:- action: labelmapregex: __meta_kubernetes_node_label_(.+)

第二種方式,不直接通過kubelet的metrics服務采集監控數據,而通過Kubernetes的api-server提供的代理API訪問各個節點中kubelet的metrics服務,如下所示:

- job_name: 'kubernetes-kubelet'scheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: noderelabel_configs:- action: labelmapregex: __meta_kubernetes_node_label_(.+)- target_label: __address__replacement: kubernetes.default.svc:443- source_labels: [__meta_kubernetes_node_name]regex: (.+)target_label: __metrics_path__replacement: /api/v1/nodes/${1}/proxy/metrics

通過relabeling,將從Kubernetes獲取到的默認地址__address__替換為kubernetes.default.svc:443。同時將__metrics_path__替換為api-server的代理地址/api/v1/nodes/${1}/proxy/metrics。

通過獲取各個節點中kubelet的監控指標,用戶可以評估集群中各節點的性能表現。例如,通過指標kubelet_pod_start_duration_seconds_count可以獲得當前節點中Pod啟動的數量。

4.2從Kubelet獲取節點容器資源使用情況

各節點的kubelet組件中除了包含自身的監控指標信息以外,kubelet組件還內置了對cAdvisor的支持。cAdvisor能夠獲取當前節點上運行的所有容器的資源使用情況,通過訪問kubelet的/metrics/cadvisor地址可以獲取到cadvisor的監控指標,因此和獲取kubelet監控指標類似,這里同樣通過node模式自動發現所有的kubelet信息,并通過適當的relabel過程,修改監控采集任務的配置。 與采集kubelet自身監控指標相似,這里也有兩種方式采集cadvisor中的監控指標:

方式一:直接訪問kubelet的/metrics/cadvisor地址,需要跳過ca證書認證:

- job_name: 'kubernetes-cadvisor'scheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtinsecure_skip_verify: truebearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: noderelabel_configs:- source_labels: [__meta_kubernetes_node_name]regex: (.+)target_label: __metrics_path__replacement: metrics/cadvisor- action: labelmapregex: __meta_kubernetes_node_label_(.+)

方式二:通過api-server提供的代理地址訪問kubelet的/metrics/cadvisor地址:

- job_name: 'kubernetes-cadvisor'scheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenkubernetes_sd_configs:- role: noderelabel_configs:- target_label: __address__replacement: kubernetes.default.svc:443- source_labels: [__meta_kubernetes_node_name]regex: (.+)target_label: __metrics_path__replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor- action: labelmapregex: __meta_kubernetes_node_label_(.+)

4.3使用NodeExporter監控集群資源使用情況

為了能夠采集集群中各個節點的資源使用情況,我們需要在各節點中部署一個Node Exporter實例。在本章的“部署Prometheus”小節,我們使用了Kubernetes內置的控制器之一Deployment。Deployment能夠確保Prometheus的Pod能夠按照預期的狀態在集群中運行,而Pod實例可能隨機運行在任意節點上。而與Prometheus的部署不同的是,對于Node Exporter而言每個節點只需要運行一個唯一的實例,此時,就需要使用Kubernetes的另外一種控制器Daemonset。顧名思義,Daemonset的管理方式類似于操作系統中的守護進程。Daemonset會確保在集群中所有(也可以指定)節點上運行一個唯一的Pod實例。

創建node-exporter-daemonset.yml文件,并寫入以下內容:

apiVersion: apps/v1 kind: DaemonSet metadata:name: node-exporter spec:selector:matchLabels:app: node-exportertemplate:metadata:annotations:prometheus.io/scrape: 'true'prometheus.io/port: '9100'prometheus.io/path: 'metrics'labels:app: node-exportername: node-exporterspec:containers:- image: prom/node-exporterimagePullPolicy: IfNotPresentname: node-exporterports:- containerPort: 9100hostPort: 9100name: scrapehostNetwork: truehostPID: true

由于Node Exporter需要能夠訪問宿主機,因此這里指定了hostNetwork和hostPID,讓Pod實例能夠以主機網絡以及系統進程的形式運行。同時YAML文件中也創建了NodeExporter相應的Service。這樣通過Service就可以訪問到對應的NodeExporter實例。

[root@master-1 prometheus]# kubectl create -f node-exporter-daemonset.yml daemonset.apps/node-exporter created

查看Daemonset以及Pod的運行狀態

[root@master-1 prometheus]# kubectl get daemonsets NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE node-exporter 1 1 1 1 1 <none> 74s[root@master-1 prometheus]# kubectl get pods NAME READY STATUS RESTARTS AGE node-exporter-brh9d 1/1 Running 0 79s prometheus-b487b9dfc-4xf65 1/1 Running 0 9m28s

由于Node Exporter是以主機網絡的形式運行,因此直接訪問MiniKube的虛擬機IP加上Pod的端口即可訪問當前節點上運行的Node Exporter實例:

[root@master-1 ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES node-exporter-brh9d 1/1 Running 0 104m 192.168.5.21 worker-1 <none> <none> prometheus-b487b9dfc-4xf65 1/1 Running 0 113m 10.244.3.50 worker-1 <none> <none>[root@master-1 ~]# curl http://192.168.5.21:9100/metrics # HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 3.3862e-05 go_gc_duration_seconds{quantile="0.25"} 4.1737e-05 go_gc_duration_seconds{quantile="0.5"} 4.5937e-05 go_gc_duration_seconds{quantile="0.75"} 5.1647e-05 go_gc_duration_seconds{quantile="1"} 0.003094938 go_gc_duration_seconds_sum 0.020962164 go_gc_duration_seconds_count 353

目前為止,通過Daemonset的形式將Node Exporter部署到了集群中的各個節點中。接下來,我們只需要通過Prometheus的pod服務發現模式,找到當前集群中部署的Node Exporter實例即可。 需要注意的是,由于Kubernetes中并非所有的Pod都提供了對Prometheus的支持,有些可能只是一些簡單的用戶應用,為了區分哪些Pod實例是可以供Prometheus進行采集的,這里我們為Node Exporter添加了注解:

prometheus.io/scrape: 'true'

由于Kubernetes中Pod可能會包含多個容器,還需要用戶通過注解指定用戶提供監控指標的采集端口:

prometheus.io/port: '9100'

而有些情況下,Pod中的容器可能并沒有使用默認的/metrics作為監控采集路徑,因此還需要支持用戶指定采集路徑:

prometheus.io/path: 'metrics'

為Prometheus創建監控采集任務kubernetes-pods,如下所示:

- job_name: 'kubernetes-pods'kubernetes_sd_configs:- role: podrelabel_configs:- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]action: keepregex: true- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]action: replacetarget_label: __metrics_path__regex: (.+)- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]action: replaceregex: ([^:]+)(?::\d+)?;(\d+)replacement: $1:$2target_label: __address__- action: labelmapregex: __meta_kubernetes_pod_label_(.+)- source_labels: [__meta_kubernetes_namespace]action: replacetarget_label: kubernetes_namespace- source_labels: [__meta_kubernetes_pod_name]action: replacetarget_label: kubernetes_pod_name

通過以上relabel過程實現對Pod實例的過濾,以及采集任務地址替換,從而實現對特定Pod實例監控指標的采集。需要說明的是kubernetes-pods并不是只針對Node Exporter而言,對于用戶任意部署的Pod實例,只要其提供了對Prometheus的支持,用戶都可以通過為Pod添加注解的形式為其添加監控指標采集的支持。

4.4從kube-apiserver獲取集群運行監控指標

在開始正式內容之前,我們需要先了解一下Kubernetes中Service是如何實現負載均衡的,如下圖所示,一般來說Service有兩個主要的使用場景:

代理對集群內部應用Pod實例的請求:當創建Service時如果指定了標簽選擇器,Kubernetes會監聽集群中所有的Pod變化情況,通過Endpoints自動維護滿足標簽選擇器的Pod實例的訪問信息;

代理對集群外部服務的請求:當創建Service時如果不指定任何的標簽選擇器,此時需要用戶手動創建Service對應的Endpoint資源。例如,一般來說,為了確保數據的安全,我們通常講數據庫服務部署到集群外。 這是為了避免集群內的應用硬編碼數據庫的訪問信息,這是就可以通過在集群內創建Service,并指向外部的數據庫服務實例。

kube-apiserver扮演了整個Kubernetes集群管理的入口的角色,負責對外暴露Kubernetes API。kube-apiserver組件一般是獨立部署在集群外的,為了能夠讓部署在集群內的應用(kubernetes插件或者用戶應用)能夠與kube-apiserver交互,Kubernetes會默認在命名空間下創建一個名為kubernetes的服務,如下所示:

[root@master-1 prometheus]# kubectl get svc kubernetes -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d4h <none>

而該kubernetes服務代理的后端實際地址通過endpoints進行維護,如下所示:

[root@master-1 prometheus]# kubectl get endpoints kubernetes NAME ENDPOINTS AGE kubernetes 192.168.5.11:6443,192.168.5.12:6443,192.168.5.13:6443 3d4h

通過這種方式集群內的應用或者系統主機就可以通過集群內部的DNS域名kubernetes.default.svc訪問到部署外部的kube-apiserver實例。

因此,如果我們想要監控kube-apiserver相關的指標,只需要通過endpoints資源找到kubernetes對應的所有后端地址即可。

如下所示,創建監控任務kubernetes-apiservers,這里指定了服務發現模式為endpoints。Promtheus會查找當前集群中所有的endpoints配置,并通過relabel進行判斷是否為apiserver對應的訪問地址:

- job_name: 'kubernetes-apiservers'kubernetes_sd_configs:- role: endpointsscheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]action: keepregex: default;kubernetes;https- target_label: __address__replacement: kubernetes.default.svc:443

在relabel_configs配置中第一步用于判斷當前endpoints是否為kube-apiserver對用的地址。第二步,替換監控采集地址到kubernetes.default.svc:443即可。重新加載配置文件,重建Promthues實例,得到以下結果。

5.Kubernetes 中部署 Grafana

grafana 是一個可視化面板,有著非常漂亮的圖表和布局展示,功能齊全的度量儀表盤和圖形編輯器,支持 Graphite、zabbix、InfluxDB、Prometheus、OpenTSDB、Elasticsearch 等作為數據源,比 Prometheus 自帶的圖表展示功能強大太多,更加靈活,有豐富的插件,功能更加強大。

通過Deployment部署grafana 創建grafana-deployment-5.0.0.yml文件,并寫入以下內容:

apiVersion: apps/v1 kind: Deployment metadata:name: grafana-corelabels:app: grafanacomponent: core spec:replicas: 1selector:matchLabels:app: grafanatemplate:metadata:labels:app: grafanaspec:containers:- image: grafana/grafana:5.0.0name: grafana-coreimagePullPolicy: IfNotPresentresources:limits:cpu: 100mmemory: 100Mirequests:cpu: 100mmemory: 100Mienv:- name: GF_AUTH_BASIC_ENABLEDvalue: "true"- name: GF_AUTH_ANONYMOUS_ENABLEDvalue: "false"readinessProbe:httpGet:path: /loginport: 3000volumeMounts:- name: grafana-persistent-storagemountPath: /varvolumes:- name: grafana-persistent-storageemptyDir: {}--- apiVersion: v1 kind: Service metadata:name: grafanalabels:app: grafana spec:type: NodePortports:- port: 3000selector:app: grafana

部署grafana

[root@master-1 prometheus]# kubectl apply -f grafana-deployment-5.0.0.yml deployment.apps/grafana-core created

注意:

如果是用的grafana 5.0.0以上版本, 會報錯 GF_PATHS_DATA='/var/lib/grafana' is not writable. You may have issues with file permissions, more information here: http://docs.grafana.org/installation/docker/#migration-from-a-previous-version-of-the-docker-container-to-5-1-or-later mkdir: cannot create directory '/var/lib/grafana/plugins': No such file or directory解決辦法:securityContext:fsGroup: 472runAsUser: 472完整的grafana-deployment-5.3.4.yml文件如下: apiVersion: apps/v1 kind: Deployment metadata:name: grafananamespace: kube-opslabels:app: grafana spec:revisionHistoryLimit: 10selector:matchLabels:app: grafanatemplate:metadata:labels:app: grafanaspec:containers:- name: grafanaimage: grafana/grafana:5.3.4imagePullPolicy: IfNotPresentports:- containerPort: 3000name: grafanaenv:- name: GF_SECURITY_ADMIN_USERvalue: admin- name: GF_SECURITY_ADMIN_PASSWORDvalue: admin321readinessProbe:failureThreshold: 10httpGet:path: /api/healthport: 3000scheme: HTTPinitialDelaySeconds: 60periodSeconds: 10successThreshold: 1timeoutSeconds: 30livenessProbe:failureThreshold: 3httpGet:path: /api/healthport: 3000scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 1resources:limits:cpu: 100mmemory: 256Mirequests:cpu: 100mmemory: 256MivolumeMounts:- mountPath: /var/lib/grafanasubPath: grafananame: storagesecurityContext:fsGroup: 472runAsUser: 472volumes:- name: storageemptyDir: {} --- apiVersion: v1 kind: Service metadata:name: grafanalabels:app: grafana spec:type: NodePortports:- port: 3000selector:app: grafana

查看pod svc 狀態

[root@master-1 prometheus]# kubectl get pod,svc NAME READY STATUS RESTARTS AGE pod/grafana-569d774b85-8244q 1/1 Running 0 7m20s pod/node-exporter-brh9d 1/1 Running 0 21h pod/prometheus-b487b9dfc-gvkd4 1/1 Running 0 17hNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/blackbox-exporter ClusterIP 10.106.168.178 <none> 9115/TCP 18h service/grafana NodePort 10.100.91.140 <none> 3000:30674/TCP 7m20s service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d23h service/nginx-svc NodePort 10.104.88.55 <none> 80:30523/TCP 3d23h service/prometheus NodePort 10.100.208.234 <none> 9090:32053/TCP 3d

這里,grafana的部署就完成了,接下來我們訪問grafana并配置Prometheus數據源。

Grafana配置

訪問grafana所在節點的的地址 http://192.168.5.21:30674/

grafana 默認用戶名 admin 密碼 admin

如果是grafana-deployment-5.3.4.yml生成的, 密碼是 admin321

添加數據源


顯示下面截圖,說明數據源可用。

導入模板

grafana 的官方網站https://grafana.com/grafana/dashboards/上還有很多公共的 Dashboard 可以供我們使用,我們這里可以使用Kubernetes cluster monitoring (via Prometheus)(dashboard id 為162)這個 Dashboard 來展示 Kubernetes 集群的監控信息。



就會顯示下面的界面,表示grafana配置成功。

仔細看看,這個dashboard是監控pod的,發現pod的數據有,但是cluster的數據沒有。這時候我們就需要去檢查一下https://grafana.com/grafana/dashboards/162 相關的配置是不是有漏掉的。

經過對grafana模板的監控字段進行修改,dashboard已經是下面這個樣子

比如,cluster memory usage 點擊edit, 修改metrics 為

(sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached_bytes) ) / sum(node_memory_MemTotal_bytes) * 100

然后點擊Save,可以添加備注。

cluster_cpu_usage改為
sum(sum by (name)( rate(container_cpu_usage_seconds_total{image!=“”}[1m] ) )) / count(node_cpu_seconds_total{mode=“system”}) * 100

cluster_file_system改為
(sum(node_filesystem_size_bytes{device=“/dev/mapper/centos_centos7-root”}) - sum(node_filesystem_free_bytes{device=“/dev/mapper/centos_centos7-root”}) ) / sum(node_filesystem_size_bytes{device=“/dev/mapper/centos_centos7-root”}) * 100

其中{device=“xxx”}過濾條件,根據os的FS類型來決定。

附錄:

我已將需要的yml文件上傳至GitHub ,有需要的可以直接下載。
https://github.com/JasonYLong/prometheus-on-kubernetes.git

參考該文章,我只是做了新版本的修改,并加上了grafana的部分。
https://yunlzheng.gitbook.io/prometheus-book/part-iii-prometheus-shi-zhan/readmd

總結

以上是生活随笔為你收集整理的Prometheus监控kubernetes的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。