天天看點

Prometheus監控運維實戰十五:監控Kubernetes

kuberentes是一款開源容器編排産品,由google開發并釋出到社群,并在 2015 年将該項目捐獻給了雲原生基金會(cloud native computing foundation)。從2014年第一個版本釋出以來,kubernetes便迅速獲得開源社群的追捧,包括redhat、vmware在内的很多知名企業都加入到開發和推廣的陣營。目前,kubernets已經成為發展最快、市場占有率最高的容器編排産品。

promehteus是一款近年來非常火熱的容器監控系統,它使用go語言開發,設計思路來源于google的borgmom(一個監控容器平台的系統)。2016年,雲原生基金會将其納入麾下,成為該基金會繼kubernetes後,第二大開源項目。是以,prometheus天然具有對容器的适配性,可非常友善的滿足容器的監控需求,目前已成為監控kubernetes的主要工具。

本文将介紹如何通過prometheus監控kubernetes叢集狀态的方案。(對于kubernetes的技術細節本文不做講解,不熟悉的朋友可先自行檢視相關資料。)

Prometheus監控運維實戰十五:監控Kubernetes

prometheus通過自動發現的方式擷取kubernetes叢集的資源資訊,是以,需要在監控叢集上安裝prometheus來實作。本文通過yaml檔案的方式部署prometheus。

建立namespace.yml檔案,内容如下 

執行該yml檔案

檢視命名空間,已成功建立。

rbac為kubernetes的授權認證方式,包括 serviceaccount、clusterrole、clusterrolebinding三類yaml檔案。該規則用于授權prometheus擷取資源資訊。

建立prometheus-rbac.yml檔案,内容如下:

檢視rbac是否建立成功

我們使用configmap來管理prometheus的配置檔案,此處先使用預設的配置,用于啟動prometheus,後面再根據需要進行修改。

建立prometheus-config.yml檔案,内容如下

檢視configmap資源是否生成

在完成configmap資源建立後,我們可以開始部署prometheus的執行個體了。此處,我們使用deployment來部署prometheus,并通過volume挂載的方式,将prometheus的配置檔案挂載到pod中。另外,在正式環境中建議通過pvc的方法,将收集的監控資料挂載到外部存儲,避免因pod被删除而造成資料丢失。

建立prometheus-deployment.yml檔案,内容如下

檢視prometheus執行個體狀态

建立prometheus的service,用于叢集内外部通路。預設情況下,service隻能在叢集内通路,如果希望開放給叢集外部,可選方案有ingress、nodeport、externalips、loadbalancer等幾種,此處使用loadbalancer方式。

建立prometheus-service.yml,内容如下:

檢視service狀态,service已建立完成,其中cluster-ip用于叢集内部通路,external-ip則是給到叢集外部通路。

浏覽器打開http://$ip:9090,可看到prometheus已部署完成。

Prometheus監控運維實戰十五:監控Kubernetes

檢視targets目标,目前除了監控prometheus自身執行個體,還未有其他kubernetes資源。

Prometheus監控運維實戰十五:監控Kubernetes

在監控kubernetes叢集的過程中,我們需要使用到針對kubernetes的服務發現功能,這個在prometheus的原生功能中已經支援。kubernetes_sd_config配置允許從kubernetes的 rest api 檢索抓取目标,并始終與叢集狀态保持同步,這點非常有用。

以下幾種類型的資源可被配置為服務發現的目标,對于叢集的監控方案有不少,關鍵是看如何靈活應用這些角色發現的功能和标簽。

該node 角色發現用于發現叢集中的節點目标資訊,其位址預設為節點kubelet的http通路端口。目标位址預設類型順序為nodeinternalip,nodeexternalip, nodelegacyhostip,和nodehostname中的第一個現有位址。​

可使用的中繼資料标簽如下:

• __meta_kubernetes_node_name:節點對象的名稱。

• __meta_kubernetes_node_label_<labelname>:節點對象所定義的各個label

• __meta_kubernetes_node_labelpresent_<labelname>:節點對象所定義的各個label,value固定為true。

• _meta_kubernetes_node_annotation_<annotationname>:來自節點對象的每個注釋

• _meta_kubernetes_node_annotationpresent_<annotationname>:來自節點對象的每個注釋,value固定為true。

• _meta_kubernetes_node_address_<address_type>:每個節點位址類型的第一個位址(如果存在)

此外,節點的執行個體标簽将被設定為從api服務檢索到的節點名稱。

該service角色發現用于發現叢集中每個服務目标,并且将該服務開放的端口做為目标端口。該位址将設定為服務的kubernetes dns名稱以及相應的服務端口。

​​__meta_kubernetes_namespace​​: 服務對象的名稱空間。

​​__meta_kubernetes_service_annotation_<annotationname>​​:服務對象的每個注釋。

​​__meta_kubernetes_service_annotationpresent_<annotationname>​​: 服務對象的每個注釋,value固定為true。

​​__meta_kubernetes_service_cluster_ip​​:  服務對象的叢集ip。 (不适用于"外部名稱"類型的服務)

​​__meta_kubernetes_service_external_name​​: 服務的dns名稱。(适用于"外部名稱"類型的服務)

​​__meta_kubernetes_service_label_<labelname>​​: 服務對象中的每個label。

​​__meta_kubernetes_service_labelpresent_<labelname>​​: 服務對象中的每個label,value固定為true。

​​__meta_kubernetes_service_name​​: 服務對象的名稱。

​​__meta_kubernetes_service_port_name​​: 目标服務端口的名稱。

​​__meta_kubernetes_service_port_protocol​​: 目标服務端口的協定。

​​__meta_kubernetes_service_type​​: 服務的類型。

該pod角色發現用于發現所有pod并将其容器做為目标通路,對于容器的每個聲明的端口,将生成一個目标。如果容器沒有指定的端口,則會為每個容器建立無端口目标,以通過标簽重寫(relabeling)手動添加端口。

​​__meta_kubernetes_namespace​​: pod對象的名稱空間。

​​__meta_kubernetes_pod_name​​: pod對象的名稱。

​​__meta_kubernetes_pod_ip​​: pod對象的pod ip。

​​__meta_kubernetes_pod_label_<labelname>​​: 來自pod對象的每個标簽。

​​__meta_kubernetes_pod_labelpresent_<labelname>​​: 來自pod對象的每個标簽,value固定為true。

​​__meta_kubernetes_pod_annotation_<annotationname>​​: 來自pod對象的每個注釋。

​​__meta_kubernetes_pod_annotationpresent_<annotationname>​​: 來自pod對象的每個注釋,value固定為true。

​​__meta_kubernetes_pod_container_init​​: 如果容器是初始化容器,則value為true。

​​__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​​: 代表pod狀态是否就緒,value為true或false。

​​__meta_kubernetes_pod_phase​​: pod的生命周期,value值為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目标,且每個endpoints的port位址會生成一個目标。如果端點由pod支援,則該pod的所有其他容器端口(包括未綁定到endpoints的端口)也将作為目标。

​​__meta_kubernetes_namespace​​: endpoints對象的命名空間

​​__meta_kubernetes_endpoints_name​​: endpoints對象的名稱

對于直接從端點清單中發現的所有目标(不包括由底層pod推斷出來的目标),将附加以下标簽:

​​__meta_kubernetes_endpoint_hostname​​: 端點的主機名

​​__meta_kubernetes_endpoint_node_name​​: 托管endpoints的節點名稱  

​​__meta_kubernetes_endpoint_ready​​:  代表endpoint 狀态是否就緒,value為true或false。

​​__meta_kubernetes_endpoint_port_name​​: endpoint 端口的名稱。

​​__meta_kubernetes_endpoint_port_protocol​​: endpoint 端口的協定。

​​__meta_kubernetes_endpoint_address_target_kind​​: endpo int位址目标的類型,如deployment、daemonset等。  

​​__meta_kubernetes_endpoint_address_target_name​​:  endpoint位址目标的名稱。

該ingress角色發現用于發現ingress的每個位址目标。該位址将設定為ingress的spec配置中指定的host。

​​__meta_kubernetes_namespace​​: ingress 對外的命名空間。

​​__meta_kubernetes_ingress_name​​: ingress 對象的名稱。

​​__meta_kubernetes_ingress_label_<labelname>​​: ingress 對象的各個标簽。

​​__meta_kubernetes_ingress_labelpresent_<labelname>​​: ingress 對象的各個标簽,value為true或false。

​​__meta_kubernetes_ingress_annotation_<annotationname>​​: ingress 對象的各個注釋。

​​__meta_kubernetes_ingress_annotationpresent_<annotationname>​​: ingress 對象的各個注釋,value為true或false。

​​__meta_kubernetes_ingress_class_name​​: ingress的spec配置中的class名稱,如果存在的話。

​​__meta_kubernetes_ingress_scheme​​: ingress使用的協定 ,http或https。

​​__meta_kubernetes_ingress_path​​:  ingress的spec配置中指定的路徑,預設為 /

建立node_exporter-daemonset.yml檔案,内容如下。在spec配置中添加了tolerations,用于污點容忍,保證master節點也會部署。

确認daemonset及pod狀态正常

在prometheus-config.yml檔案中添下如下任務,并執行生效。

注解:該任務通過node角色發現動态擷取節點位址資訊,并使用标簽重寫(relabeling)功能重寫targets目标端口為node-expoerter端口,進而實作自動監控叢集節點功能。

任務生效後,可看到prometheus已自動擷取到節點資訊并監控。

Prometheus監控運維實戰十五:監控Kubernetes

kubernetes各節點的kubelet除包含自身的監控名額資訊以外,還内置了對cadviosr的支援。在前面的容器監控篇章中,我們知道可以通過安裝cadviosr來監控節點上的容器狀态。而在kuberentes叢集中,通過kubelet可實作類似的效果,不需要再額外安裝cadviosr。

prometheus-config.yml檔案中添下如下任務,并執行生效。

注解:該任務通過node角色發現動态擷取節點位址資訊。由于直接通路kubelet位址會有證書驗證問題,這裡使用标簽重寫(relabeling)功能重寫targets目标位址和位址,通過api server提供的代理位址通路kubelet的/metrics/cadvisor。

任務生效後,可看到prometheus已自動生成相關目标資訊。

Prometheus監控運維實戰十五:監控Kubernetes

kube api server做為整個kubernetes叢集管理的入口服務,負責對外暴露kuberentes api,服務的穩定與否影響着叢集的可用性。通過對kube api server的監控,我們能夠清楚api的請求處理延遲、錯誤和可用性等參數。

kube api server元件一般獨立部署叢集外部,運作在master的主機上,為了能夠讓叢集内部的應用能夠與api進行互動,kubernetes會在default的命名空間下建立一個kubernetes的service,用于叢集内部通路。

該kubernetes服務代理的後端實際位址通過endpoints進行維護,該endpoints代理位址指向了master節點的6443端口,也即是master上運作的kube api server服務端口。

​是以,我們可通過prometheus的endpoints角色發現功能,來實作kube api server的目标發現并監控。

注解:該任務通過endpoints角色發現動态擷取endpoints資訊,并使用标簽重寫(relabeling)功能隻保留符合正規表達式比對的endpoints目标。

任務生效後,檢視prometheus已自動生成相關目标資訊。

Prometheus監控運維實戰十五:監控Kubernetes

kubelet元件運作在叢集中每個worker節點上,用于處理master下發到本節點的任務,包括管理pod和其中的容器。kubelet會在kube api server上注冊節點資訊,并定期向叢集彙報節點資源使用情況。kubelet的運作狀态關乎着該節點的是否可以正常工作,基于該元件的重要性,我們有必要對各個節點的kubelet進行監控。

​注解:該任務通過node角色發現動态擷取節點位址資訊。由于直接通路kubelet位址會有證書驗證問題,這裡使用标簽重寫(relabeling)功能重寫targets目标位址和位址,通過api server提供的代理位址通路kubelet的/metrics路徑。

Prometheus監控運維實戰十五:監控Kubernetes

kubernetes資源對象包括pod、deployment、statefulsets等,我們需要知道相關資源的使用情況和狀态,如pod是否正常運作。由于并不是所有資源都支援prometheus的監控, 是以,我們需要使用開源的kube-state-metrics方案來完成擷取監控名額。 kube-state-metrics是kubernetes組織下的一個項目,它通過監聽kube api收集相關資源和對象的最新資訊,并提供接口位址給到prometheus擷取名額。

kube-state-metrics對kubernetes有版本要求,如下圖。我們環境的kubernetes為1.18,是以需要下載下傳v2.0.0及以上版本。

Prometheus監控運維實戰十五:監控Kubernetes

下載下傳項目倉庫

​部署安裝

​檢視服務狀态

​任務生效後,檢視prometheus已自動生成相關目标資訊。

Prometheus監控運維實戰十五:監控Kubernetes

繼續閱讀