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來實作。本文通過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已部署完成。
檢視targets目标,目前除了監控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已自動擷取到節點資訊并監控。
kubernetes各節點的kubelet除包含自身的監控名額資訊以外,還内置了對cadviosr的支援。在前面的容器監控篇章中,我們知道可以通過安裝cadviosr來監控節點上的容器狀态。而在kuberentes叢集中,通過kubelet可實作類似的效果,不需要再額外安裝cadviosr。
prometheus-config.yml檔案中添下如下任務,并執行生效。
注解:該任務通過node角色發現動态擷取節點位址資訊。由于直接通路kubelet位址會有證書驗證問題,這裡使用标簽重寫(relabeling)功能重寫targets目标位址和位址,通過api server提供的代理位址通路kubelet的/metrics/cadvisor。
任務生效後,可看到prometheus已自動生成相關目标資訊。
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已自動生成相關目标資訊。
kubelet元件運作在叢集中每個worker節點上,用于處理master下發到本節點的任務,包括管理pod和其中的容器。kubelet會在kube api server上注冊節點資訊,并定期向叢集彙報節點資源使用情況。kubelet的運作狀态關乎着該節點的是否可以正常工作,基于該元件的重要性,我們有必要對各個節點的kubelet進行監控。
注解:該任務通過node角色發現動态擷取節點位址資訊。由于直接通路kubelet位址會有證書驗證問題,這裡使用标簽重寫(relabeling)功能重寫targets目标位址和位址,通過api server提供的代理位址通路kubelet的/metrics路徑。
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已自動生成相關目标資訊。