一、概述
1、上集中我們說到,官方文檔提示說從k8s 1.11版本開始,將監控體系指標數據獲取機制移向新一代的監控模型。也就意味着對於我們的k8s來講現在應該有這樣兩種資源指標被使用。一種是資源指標,另一種是自定義指標。意思是說HeapSter提供了指標數據的收集,存儲和監控的基本功能。並支持多個數據接收器。比如influxdb來存儲指標數據,而后每個存儲后端的代碼本身都駐留在HeapSter倉庫中。意思是HeapSter為了能夠支持各種各樣的存儲后端他就不得不去適配驅動每一個存儲后端,這其中包含我們剛剛說的inflxdb,更悲慘的是這每一個適配器都是由第三方組織研發的,第三方萬一哪一天沒興趣了也就不維護了。以至於HeapSter中為了適配很多的存儲后端,整合了近十幾個后端存儲的適配器。有些適配器自從整合至HeapSter以后再也沒有修改過。但是HeapSter為此卻不得不付出代碼量很龐大的代價。所以這就意味着HeapSter的設計架構不適用於這種所謂雲原生的監控體系。因為他會假設數據存儲是一個原始的時間序列存儲數據庫。而且每個接收器都作為HeapSter核心代碼的一部分。使得我們整個監控結構定義和使用起來越來越麻煩。而且維護起來代價也越來越大。所以這樣子他開始去支持新一代的監控架構。這就是我們嘗試着廢棄HeapSter的原因。
2、當然k8s本身如此強大,一個核心原因在於他的靈活擴展性,他的很多功能使用addon來實現。所以也就意味着他們的替換不是一件難事。而且現在的版本中的k8s還支持開發人員自己輕松定義自己的API服務器來擴展核心API服務。什么意思呢?如果用戶覺得我們系統內置的這些資源類型不夠用,比如svc,pod等等不能解決我們的問題的時候我們要把特殊應用程序的特殊使用方式的維護技巧維護步驟柔和到我們對應的資源中去。那么我們應該怎么去擴展自己的k8s系統所支持的資源類型呢?一般來說我們有三種方式:
a、直接使用CRD(自制資源定義)
b、我們自己去修改代碼,開發一個新的apiserver。里面提供其它API並通過所謂的API聚合器和自己的k8s的ApiServer二者建立起一個聚合關系把他們聚合在一處去使用。
c、如果有需要的話直接修改k8s的源代碼去新增一些資源定義。
3、剛剛說過有一種方式就是允許由開發人員輕松使用自己的API服務器來擴展附加到已有的k8s之上來實現聚合進更多的API功能來。比如我們k8s自己有個APIserver,他的apiserver支持哪些API組件應該都是事先定義好的。如果我們需要的api這里面沒有怎么辦呢?你可以自己去開發一個apiserver單獨運行,甚至還可以托管在k8s上運行,然后在k8s自己的服務器和你的apiserver前端加一個代理服務,而后所有的對api的請求就直接對這個代理服務請求,它既能獲取到k8s自己已有的api也能使用你定義的api,這種就叫聚合器。k8s從1.8開始引入了資源指標API,我們把資源的內容也當做api接口中的數據直接進行獲取而不像早期的HeapSter中是靠HeapSter來提供,和apiserver沒什么關系。有單獨自己的獲取路徑,意思是傳統時代HeapSter時代我們大多數功能都是通過ApiServer來獲取的,但有一個功能不是,我們要想獲取資源指標數據得專門部署一個addon,即HeapSter,因此我們系統上的很多組件如果獲取資源指標得到你的addon上來,這個addon沒部署就沒用。或者其它指標數據的獲取都應該通過apiserver來獲取。有兩路方式來獲取資源。
4、那我們能不能干脆把資源指標中的這些數據也直接整合進apiserver呢?意思是任何客戶端通過apiserver能夠獲取到他的所有數據,包括指標。即能夠監控到每一個pod到底使用了多少cpu多少內存,此前這些apiserver是不負責的,所以從1.8以后他們就引入了資源指標api,就用api這種接口方式去輸出每一個資源對象的指標。另外,k8s從1.6開始引入自定義指標。這個功能挺早了。其實我們有很多系統級的組件都是依賴於這些指標api的功能的。比如我們的kubectl top,如果沒有資源指標的api接口或者有一個專門的資源指標供給他是沒辦法運行的。另外,像HPA(水平pod自動伸縮器),這些也是需要根據獲取當前pod的cpu比如已經到達80%,說明負載已經很高了,這個時候就給你加一個或者加幾個pod。如果我們pod的cpu使用率一直低於%5,我們可以刪幾個,這樣騰出來一些資源和空間。讓其它pod所使用。大家知道你的pod無論運行與否他只要有request,只要被調度到這個節點上這個節點上的資源就要預留給pod使用。pod一直在這兒放着又不用又不運行就很可惜,我們可以把它移除,多騰出一些資源空間以給其它Pod運行和使用。因此這些組件都是要依賴於資源指標才能工作的。早期他們都是要依賴於HeapSter來實現。
5、早期的k8s之上你必須部署了HeapSter才能使用top命令,另外才能使用HPA,就是剛剛所說的能水平自動伸縮你的Depolyment之下的pod的應用規模。但是我們說過這些指標之前只能通過HeapSter來提供,而且他所能提供的指標還是有限的。尤其其伸縮只能根據cpu的用量來伸縮。假如我想根據io,內存等其它指標伸縮在這個時代借助HeapSter還是做不到的。所以他們期望能夠根據越來越多的指標進行伸縮。比如cpu利用率很低但是這個pod的並發訪問量很大了。這個時候我們也應該加些pod但是他不會根據這個指標進行添加,僅僅只是根據cpu的使用量。因此僅根據cpu不足以反饋出我們應用規模所需要伸縮的所有場景,他只能反饋出來一個很小很小的場景。這個時候我們就需要引入更多的能夠支撐HPA工作能力的資源指標。早期HeapSter不支持。就是在這種情況下我們就有了新的資源指標api的模型以及我們需要整合自定義指標的模型。
二、新一代的指標
1、資源指標:新一代的資源指標API的獲取的主要方式是靠metrics-server來實現的。他主要是定義資源指標的。
2、自定義指標:另外用戶也允許開始去使用很多的自定義指標。比如說有一些監控系統,比如普羅米修斯,他已經被直接收錄進CNCF。他已經是CNCF旗下的一個直接的項目。也就是雲原生計算基金會下第一個是k8s,第二個就是普羅米修斯了。可以看出其強大的江湖地位。普羅米修斯可以收集各種維度的指標。比如他不但能收集你的cpu利用率還能收集你的網絡連接的數量,網絡報文的速率,內存,進程的新建和回收的速率等等。而這個指標早期k8s是不支持的。所以我們需要把普羅米修斯所能夠監控采集到的很多指標數據直接整合進k8s中,讓k8s能用,能拿來作為HPA判斷是否需要伸縮pod規模的一個基本標准。因此后來自定義指標就通過prometheus來實現。他自己即作為一個監控系統使用也作為一些特殊的資源指標的提供者來提供,不過這個指標他不是內建的標准核心指標。我們把它稱為自定義指標。但是如果prometheus想要把其監控的采集數據轉成指標格式需要一個特殊的組件來實現。叫k8s-prometheus-adapter,這是早期時候的版本。
三、新一代監控架構:我們目前來講新一代的k8s的監控系統的架構主要有兩部分組成
1、核心指標流水線:由kubelet、metrics-server以及由API server提供的api組成;這里面主要是提供最核心的指標的,他主要是讓各位通過k8s自身的組件去了解內部組件和核心使用程序的指標;目前主要包含cpu的累積使用率和內存的實時使用率,以及Pod的資源占用率及容器的磁盤占用率。除了這些指標有可能還需要去評估網絡連接數量,可用網絡帶寬之類的。這些度量標准一般而言就需要第三方監控組件使用了,因為核心指標是不適合委托給第三方的,因為這些核心指標將會被我們系統中的很多組件使用,kubectl top,dashboard等等,因此我們稱之為核心指標。
2、監控流水線:簡單來講就是我們在系統之上部署一個監控系統,監控系統收集各種各樣監控系統本身所感興趣的指標數據。所以他的功能是用於從系統收集各種指標數據並提供終端用戶、存儲系統以及HPA。我們也稱之為非核心指標。但他通常包含核心指標。即包含上面所描述的指標。除此之外又包含很多非核心指標。
3、但是既然不是核心指標那么他就沒法被k8s所解釋,即k8s不理解他是什么東西。比如prometheus采集的數據是prometheus語境中保存的,prometheus可以理解他沒問題,但是k8s理解不了,這就是為什么需要一個k8s-prometheus-adapter的原因,他需要把prometheus采集到的數據轉換成k8s可以理解的格式。
4、另外,k8s自身肯定不會提供這樣的組件。通常就算是要用也會使用第三方的。如果用戶自己不打算使用他你甚至可以不用部署。但是核心指標流水線是必須要部署的。核心指標流水線早期是由HeapSter提供的,而他在1.11上開始要廢棄了。目前來講替代他的就是metrics-server,它是由metrics-server來聚合提供的。他是一個第三方開發的API server服務器,這個服務器是用來服務資源指標服務API,不是服務k8s的API,而是僅僅用於服務於我們cpu利用率內存使用率等這些對象的,但是他本身又不是k8s的組成部分,他是托管運行在k8s之上的一個pod,所以為了能夠讓用戶可以使用metrics-server中的API在k8s上可以無縫的使用,因此我們不得不在新一代的結構中這么去組織他們。第一,k8s的API server正常運行。第二,又metrics-server提供另外一組API,我們需要把兩組API合並成一個使用,因此我們需要在兩個之間加一個代理,這個代理我們稱之為聚合器。相當於把來自多個不同地方的api聚合成一個來使用,不光能聚合metrics-server,還能聚合很多其它的第三方或者用戶自定義的api server,即kube-aggregator(聚合器),而這個聚合器所提供的資源指標我們將通過/apis/metrics.k8s.io/v1beta1的版本來獲取。說白了就是默認是沒有這個對應的群組的,他是由metrics-server提供的。
5、另外HeapSter被廢了,因此metrics-server已經成為了k8s多個核心組件的先決條件,沒有他就沒法運行了,比如kubectl top,HPA等等,所以我們現在就不得不去部署我們的metrics-server以便能提供這些資源指標數據。
四、部署metrics-server
1、首先我們卸載前面部署的HeapSter各個組件。
2、接下來我們去部署metrics-server,對應鏈接為https://github.com/kubernetes/kubernetes/tree/release-1.11/cluster/addons/metrics-server。找到v1.11版本下載即可
[root@k8smaster metrics-server]# pwd && ls /root/manifests/metrics/metrics-server auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml [root@k8smaster metrics-server]# kubectl apply -f . clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator configured rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader unchanged apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io configured serviceaccount/metrics-server unchanged configmap/metrics-server-config unchanged deployment.extensions/metrics-server-v0.2.1 unchanged service/metrics-server unchanged clusterrole.rbac.authorization.k8s.io/system:metrics-server configured clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server configured
可以看到已經有metrics的api群組了,這個群組其實不是k8s的api提供的,而是由我們剛剛提供的metrics-server提供的。
[root@k8smaster metrics-server]# kubectl get pods -n kube-system |grep me metrics-server-v0.2.1-fd596d746-44k9k 2/2 Running 0 1m [root@k8smaster metrics-server]# kubectl api-versions |grep me metrics.k8s.io/v1beta1
3、我們確認metrics-server已經部署而且對應的pod已經正常運行起來以后接下來就可以獲取他的監控的數據。如果他已經收集到數據了我們就可以看看有沒有了,可以使用curl命令直接獲取
a、首先我們使用kubectl proxy打開一個反代接口
[root@k8smaster metrics-server]# kubectl proxy --port=8080 Starting to serve on 127.0.0.1:8080
b、使用curl來訪問api中數據。可以看到我們有node和pod的數據。
[root@k8smaster metrics-server]# curl http://localhost:8080/apis/metrics.k8s.io/v1beta1 { "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "metrics.k8s.io/v1beta1", "resources": [ { "name": "nodes", "singularName": "", "namespaced": false, "kind": "NodeMetrics", "verbs": [ "get", "list" ] }, { "name": "pods", "singularName": "", "namespaced": true, "kind": "PodMetrics", "verbs": [ "get", "list" ] } ] }
查看node的數據或pod的數據
[root@k8smaster metrics-server]# curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/nodes { "kind": "NodeMetricsList", "apiVersion": "metrics.k8s.io/v1beta1", "metadata": { "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes" }, "items": [] }[root@k8smaster metrics-server]# curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/pods { "kind": "PodMetricsList", "apiVersion": "metrics.k8s.io/v1beta1", "metadata": { "selfLink": "/apis/metrics.k8s.io/v1beta1/pods" }, "items": [] }
中間會有一些小問題,參照https://www.cnblogs.com/dingbin/p/9728458.html這位大佬博客即可。
c、此時我們的kubectl top 即可使用
[root@k8smaster ~]# kubectl top nodes NAME CPU(cores) CPU% MEMORY(bytes)(內存已用空間) MEMORY%(內存已用空間所占百分比) k8smaster 648m 16% 1166Mi 67% k8snode1 145m 7% 888Mi 51% k8snode2 114m 5% 782Mi 45% [root@k8smaster ~]# kubectl top pods NAME CPU(cores) MEMORY(bytes) myapp-deploy-5d9c6985f5-46rtw 0m 3Mi myapp-deploy-5d9c6985f5-7nhwq 0m 2Mi myapp-deploy-5d9c6985f5-p8gsg 0m 2Mi
五、prometheus
1、此時核心指標我們通過metrics-server已經可以獲取到了,但是自定義指標,尤其是除了節點和pod cpu,內存之外的其它指標我們依然無法獲取,還需要借助於prometheus,但是prometheus提供的資源指標數據是不能被k8s解析的,要想在k8s上使用 prometheus我們還得額外去加一個k8s的關於prometheus的組件。
2、簡單來講我們prometheus自己就是一個監控系統,他也通過自己的監控代理插件就像我們的zabbix在每一個組件上都要部署一個zabbix-agent,prometheus也是類似的監控軟件,所以他自己有一個prometheus server,我們姑且稱之為Prometheus,這個server端不停的通過數據采集的方式從每一個被監控主機那里來獲取數據,這個被監控主機如果是一個正常的節點而不是Pod那么我們就應該在這個節點上部署一個專門的軟件,這個軟件就是prometheus的agent,他們通常稱為node_exporter,他是一個能夠讓prometheus server通過它來采集指標數據的一個組件,但這個組件只是用來去暴露輸出采集當前節點的節點級指標數據的,如果要采集其它的數據,比如mysql的,你還需要去部署mysql的exporter,他有很多重量級服務的專用exporter。我們要去采集pod的話,pod在k8s上本身就有獲取采集數據的接口api。也不一定非要去額外部署,更何況節點的每一個容器的日志都在節點上。在/var/log/containers/中。因此,簡單來講我們prometheus就是通過一個專門的metrics-url到各pod獲取數據的。把它部署到k8s上之后能到每一個pod上直接采集你定義需要采集的各種各樣的指標數據。采集完以后我們用戶怎么看呢?prometheus提供了一個非常強大的接口叫 PromQL,即prometheus的查詢語句,他支持非常非常強大的restful接口的查詢條件表達式。能通過PromQL查詢他所監控到的各種指標數據,當然這個指標數據不能被api server所解析,因此如果期望能夠通過k8s的apiserver像在api中獲取數據一樣來獲取指標數據,而且是prometheus所采集的指標數據。那么我們必須把這個PromQL所實現的功能數據格式轉為k8s的api的查詢接口的格式。所以假如上面這個是我們k8s的apiserver,甚至是我們自定義的apiserver,即Custom Metrics API,即我們自定義指標API,而不再是我們剛剛所提到的核心指標API了。那怎么能把它轉為自定義指標API以后能通過這些指標接口獲取到我們監控數據呢?我需要在下面再嵌套進來一個組件,這個組件我們稱之為kube-state-metrics,轉換后還不能通過apiserver獲取,獲取需要k8s-prometheus-adpater組件,這是由第三方人員研發的,說不定哪天又用不成了。即這個組件能夠用PromQL的語句完成從Prometheus這里查詢到一些指標數據,並把它轉為k8s的API上的指標格式的數據,並支持能通過APIserver能獲取。只需要把Custom Metrics API聚合到我們的APIserver上去,正常就能通過我們的api-versions看到我們的api了。
3、所以我們要想部署這個功能首先我們需要部署Prometheus,然后還需要配置prometueus能從pod上抓取到數據,還得在當前系統上部署一個k8s-prometheus-adpater這個pod,接着這個pod輸出以后我們還要把它整合到我們對應的apiserver上去。
六、部署prometheus
1、部署步驟大體上包含了。第一,最好使用一個單獨的名稱空間,當然也可以使用kube-system。不過建議使用單獨的名稱空間去放我們的prometheus,而后在這個目錄中我們去用prometheus的各種各樣的配置文件。對應鏈接為https://github.com/kubernetes/kubernetes/tree/release-1.11/cluster/addons/prometheus。
2、部署prometheus時需要注意:
a、我們在k8s上去部署prometheus時因為其是有狀態應用因此我們需要使用statefulset去控制他。如果一個副本的話到底是statefulset或deployment就不重要了。
3、為了簡化過程,我們將部署的statefulset改為deployment,不然的話還要准備pv和pvc才行。因此,我們在馬哥的https://github.com/iKubernetes/k8s-prom這個項目的對應路徑下可以看到有相應的准備文件。我們可以將其克隆到本地。
4、首先部署名稱空間
root@k8smaster k8s-prom-master]# pwd /root/manifests/metrics/k8s-prom-master [root@k8smaster k8s-prom-master]# ls k8s-prometheus-adapter kube-state-metrics namespace.yaml node_exporter podinfo prometheus README.md [root@k8smaster k8s-prom-master]# kubectl apply -f namespace.yaml namespace/prom created
5、部署node_exporter
[root@k8smaster node_exporter]# pwd /root/manifests/metrics/k8s-prom-master/node_exporter [root@k8smaster node_exporter]# ls node-exporter-ds.yaml node-exporter-svc.yaml [root@k8smaster node_exporter]# kubectl apply -f . daemonset.apps/prometheus-node-exporter created service/prometheus-node-exporter created
[root@k8smaster node_exporter]# kubectl get pods -n prom -o wide NAME READY STATUS RESTARTS AGE IP NODE prometheus-node-exporter-fd499 1/1 Running 0 5m 192.168.10.10 k8smaster prometheus-node-exporter-k547l 1/1 Running 0 5m 192.168.10.11 k8snode1 prometheus-node-exporter-mjwjf 1/1 Running 0 5m 192.168.10.12 k8snode2
6、部署prometheus,此處prometheus-deploy.yaml中定義的內存Limit為2G,因為虛擬機一共給的才2G因此不夠,所以不滿足調度條件,我們將限制項注釋掉即可
[root@k8smaster prometheus]# pwd && ls /root/manifests/metrics/k8s-prom-master/prometheus prometheus-cfg.yaml prometheus-deploy.yaml prometheus-rbac.yaml prometheus-svc.yaml [root@k8smaster prometheus]# kubectl apply -f . configmap/prometheus-config unchanged deployment.apps/prometheus-server unchanged clusterrole.rbac.authorization.k8s.io/prometheus configured serviceaccount/prometheus unchanged clusterrolebinding.rbac.authorization.k8s.io/prometheus configured service/prometheus unchanged [root@k8smaster prometheus]# kubectl get all -n prom NAME READY STATUS RESTARTS AGE pod/prometheus-node-exporter-fd499 1/1 Running 0 1h pod/prometheus-node-exporter-k547l 1/1 Running 0 1h pod/prometheus-node-exporter-mjwjf 1/1 Running 0 1h pod/prometheus-server-7c8554cf-j6qgg 1/1 Running 0 4m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/prometheus NodePort 10.110.192.191 <none> 9090:30090/TCP 11m service/prometheus-node-exporter ClusterIP None <none> 9100/TCP 1h NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/prometheus-node-exporter 3 3 3 3 3 <none> 1h NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/prometheus-server 1 1 1 1 11m NAME DESIRED CURRENT READY AGE replicaset.apps/prometheus-server-65f5d59585 0 0 0 11m replicaset.apps/prometheus-server-7c8554cf 1 1 1 4m
此時prometheus已經正常運行起來了。我們可以通過30090端口來訪問。
7、部署kube-state-metrics
[root@k8smaster kube-state-metrics]# pwd && ls /root/manifests/metrics/k8s-prom-master/kube-state-metrics kube-state-metrics-deploy.yaml kube-state-metrics-rbac.yaml kube-state-metrics-svc.yaml [root@k8smaster kube-state-metrics]# kubectl apply -f . deployment.apps/kube-state-metrics unchanged serviceaccount/kube-state-metrics unchanged clusterrole.rbac.authorization.k8s.io/kube-state-metrics configured clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics configured service/kube-state-metrics unchanged [root@k8smaster kube-state-metrics]# kubectl get pods -n prom NAME READY STATUS RESTARTS AGE kube-state-metrics-58dffdf67d-l2cml 1/1 Running 0 6m prometheus-node-exporter-fd499 1/1 Running 0 2h prometheus-node-exporter-k547l 1/1 Running 0 2h prometheus-node-exporter-mjwjf 1/1 Running 0 2h prometheus-server-7c8554cf-cgldt 1/1 Running 0 37m
8、接下來我們部署k8s-prometheus-adapter,他需要基於https提供服務,因為我們整個k8s的apiserver都是基於https提供服務的。而默認情況下他是http協議的,需要給其提供證書以確保其能工作為https協議,並且這個證書還必須是此k8s服務器認可的CA簽署的才行,所以這個證書只能自制。於是我們先去給其創建一個證書,而后把這個證書創建為一個secret。而后在部署k8s-prometheus-adapter的時候加載這個證書。加載這個證書的secret有一個特定的名稱,我們把它放在特定的名稱空間下,就可以自動加載了。cat custom-metrics-apiserver-deployment.yaml 最后一行即可看到,名稱為cm-adapter-serving-certs
a、首先我們去生成一個私鑰serving.key
[root@k8smaster ~]# cd /etc/kubernetes/pki/ [root@k8smaster pki]# ls apiserver.crt apiserver.key ca.crt dashboard.crt etcd front-proxy-client.crt sa.pub wohaoshuai.key apiserver-etcd-client.crt apiserver-kubelet-client.crt ca.key dashboard.csr front-proxy-ca.crt front-proxy-client.key wohaoshuai.crt apiserver-etcd-client.key apiserver-kubelet-client.key ca.srl dashboard.key front-proxy-ca.key sa.key wohaoshuai.csr [root@k8smaster pki]# (umask 077; openssl genrsa -out serving.key 2048) Generating RSA private key, 2048 bit long modulus .................+++ .......................................+++ e is 65537 (0x10001)
b、接下來我們去生成一個證書簽署請求
[root@k8smaster pki]# openssl req -new -key serving.key -out serving.csr -subj "/CN=serving"
c、接下來我們給其簽證
[root@k8smaster pki]# openssl x509 -req -in serving.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out serving.crt -days 3650 Signature ok subject=/CN=serving Getting CA Private Key
d、接下來我們將其創建為一個secret,名稱需要與custom-metrics-apiserver-deployment.yaml 中描述的一致。為cm-adapter-serving-certs.
[root@k8smaster pki]# kubectl create secret generic cm-adapter-serving-certs --from-file=serving.crt=./serving.crt --from-file=serving.key=./serving.key -n prom secret/cm-adapter-serving-certs created [root@k8smaster pki]# kubectl get secret -n prom NAME TYPE DATA AGE cm-adapter-serving-certs Opaque 2 10s default-token-j4x4m kubernetes.io/service-account-token 3 2h kube-state-metrics-token-q7pfw kubernetes.io/service-account-token 3 36m prometheus-token-9r5v4 kubernetes.io/service-account-token 3 1h
e、接下來我們就可以開始部署了。(到此為之吧,這個版本的部署我沒時間去研究了)
9、部署完成以后我們可以看到在api-versions中會有一個custom.metrics.k8s.io/v1beta1,這樣我們又有了很多新的api指標。通過這些新指標我們就可以創建我們的HPA了,即水平pod自動伸縮控制器。功能用起來也不麻煩。
10、接下來我們需要部署granfana,然后將數據源設置為prometheus即可。
七、HPA
1、HPA是我們k8s非常強大的一個功能,支持應用規模的自動伸縮。當我們pod中資源壓力過大時他會自動修改對應的deployment中的副本值。並且是由計算結果得到相應的值。HPA至2018年9月有兩個版本:
a、V1版本只支持核心指標進行定義。核心指標只有cpu和內存,但是內存又是非可壓縮性資源所以不支持彈性縮放。因此我們只能使用cpu指標進行伸縮。
b、若使用v2版本那么我們v2版本有哪些指標可以用於作為伸縮數據時的基本標准呢?我們可以在官網查看到。
2、HPA的使用。我們可以在kubectl api-versions 中看到有一個autoscaling的api版本,接下來我們演示兩種不同的控制器是怎么工作的。
3、HPA V1測試:我們接下來重新創建一個deployment,因為這個新的我們要做資源限制,不做資源限制就沒法說這個pod需要伸縮。因為我們定義說一個pod最多只能使用多少多少CPU,最多只能使用多少多少內存,現在我們需要評估他使用的百分比了。
a、首先我們創建一個deployment
[root@k8smaster manifests]# kubectl run myapp --image=ikubernetes/myapp:v1 --replicas=1 --requests='cpu=50m,memory=256Mi' --limits='cpu=50m,memory=256Mi' --labels='app=myapp' --expose --por t=80service/myapp created deployment.apps/myapp created
b、接下來我們需要他能自動伸縮,我們可以用命令定義
[root@k8smaster manifests]# kubectl autoscale deployment myapp --min=1 --max=8 --cpu-percent=60(創建一個最小副本數為1,最大副本數為8,cpu最多使用百分比為60%的hpa) horizontalpodautoscaler.autoscaling/myapp autoscaled
c、接下來我們嘗試發起壓力測試請求看看效果。
首先我們通過ab來訪問
[root@k8smaster ~]# ab -c 100 -n 500000 http://192.168.10.10:30456/index.html This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.10.10 (be patient) apr_pollset_poll: The timeout specified has expired (70007) Total of 9502 requests completed
壓測過程中我們可以查看hpa,發現cpu增長時hpa能感應到,並計算出副本需求
[root@k8smaster manifests]# kubectl describe hpa Name: myapp Namespace: default Labels: <none> Annotations: <none> CreationTimestamp: Fri, 30 Aug 2019 10:31:19 +0800 Reference: Deployment/myapp Metrics: ( current / target ) resource cpu on pods (as a percentage of request): 70% (35m) / 60% Min replicas: 1 Max replicas: 8 Deployment pods: 2 current / 2 desired #計算出需要兩個pod Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale False BackoffBoth the time since the previous scale is still within both the downscale and upscale forbidden windows ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request) ScalingLimited False DesiredWithinRange the desired count is within the acceptable range Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulRescale 48s horizontal-pod-autoscaler New size: 2; reason: cpu resource utilization (percentage of request) above target
此時我們看到我們的副本自動增加了一個
[root@k8smaster ~]# kubectl get pods -w NAME READY STATUS RESTARTS AGE myapp-6985749785-mj64t 1/1 Running 0 15m myapp-6985749785-ppwbl 0/1 Pending 0 0s myapp-6985749785-ppwbl 0/1 Pending 0 0s myapp-6985749785-ppwbl 0/1 ContainerCreating 0 0s myapp-6985749785-ppwbl 0/1 ContainerCreating 0 5s myapp-6985749785-ppwbl 1/1 Running 0 6s
壓測完畢后我們可以看到我們hpa計算出我們只需要1個pod了
[root@k8smaster manifests]# kubectl describe hpa Name: myapp Namespace: default Labels: <none> Annotations: <none> CreationTimestamp: Fri, 30 Aug 2019 10:31:19 +0800 Reference: Deployment/myapp Metrics: ( current / target ) resource cpu on pods (as a percentage of request): 0% (0) / 60% Min replicas: 1 Max replicas: 8 Deployment pods: 1 current / 1 desired #需要一個pod Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True ReadyForNewScale the last scale time was sufficiently old as to warrant a new scale ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request) ScalingLimited True TooFewReplicas the desired replica count is increasing faster than the maximum scale rate Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulRescale 15m horizontal-pod-autoscaler New size: 2; reason: cpu resource utilization (percentage of request) above target Normal SuccessfulRescale 10m horizontal-pod-autoscaler New size: 1; reason: All metrics below target
可以看到又回退到一個pod
[root@k8smaster ~]# kubectl get pods -w NAME READY STATUS RESTARTS AGE myapp-6985749785-mj64t 1/1 Running 0 15m myapp-6985749785-ppwbl 0/1 Pending 0 0s myapp-6985749785-ppwbl 0/1 Pending 0 0s myapp-6985749785-ppwbl 0/1 ContainerCreating 0 0s myapp-6985749785-ppwbl 0/1 ContainerCreating 0 5s myapp-6985749785-ppwbl 1/1 Running 0 6s myapp-6985749785-ppwbl 1/1 Terminating 0 5m myapp-6985749785-ppwbl 0/1 Terminating 0 5m myapp-6985749785-ppwbl 0/1 Terminating 0 5m myapp-6985749785-ppwbl 0/1 Terminating 0 5m
4、HPA V2測試。HPA v2控制器表示你可以使用別的指標當做我們資源對應的資源評估擴展時使用的指標。此處只看一下定義的配置文件即可
[root@k8smaster metrics-server]# cat hpa-v2-demo.yaml apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata: name: myapp-hpa-v2 spec: scaleTargetRef: apiVersion: apps/v1 #對誰來進行擴展 kind: Deployment name: myapp #Deployment name叫myapp minReplicas: 1 #最小副本數 maxReplicas: 10 #最大副本數 metrics: #依據哪些指標進行評估 - type: Resource #基於資源評估 resource: name: cpu targetAuerageUtilization: 55 #根據cpu的資源使用率進行評估 v1版本只支持cpu,v2版本還支持內存 - type: Resource resource: name: memory targetAverageValue: 50Mi #內存不能超過50%