這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
預設安裝後的Kubernetes dashboard如所示,是無法圖形化展現叢集度量指標資訊的:
圖形化展示度量指標的實現需要整合k8s的另外一個Addons組件:Heapster。
Heapster原生支援K8s(v1.0.6及以後版本)和CoreOS,並且支援多種儲存後端,比如:InfluxDB、Elasticsearch、Kafka等,這個風格和k8s的確很像:功能先不管完善與否,先讓自己在各個平台能用起來再說^0^。這裡我們使用的資料存放區後端是InfluxDB。
一、安裝步驟
我們的Heapster也是要放在pod裡啟動並執行。當前,Heapster的最新stable版本是v1.2.0,我們可以下載其源碼包到K8s cluster上的某個Node上。解壓後,我們得到一個名為”heapster-1.2.0″的目錄,進入該目錄,我們可以看到如下內容:
root@node1:~/k8stest/dashboardinstall/heapster-1.2.0# lscode-of-conduct.md CONTRIBUTING.md docs Godeps hooks integration LICENSE metrics riemann versioncommon deploy events grafana influxdb kafka Makefile README.md vendor
以InfluxDB為儲存後端的Heapster部署yaml在deploy/kube-config/influxdb下面:
root@node1:~/k8stest/dashboardinstall/heapster-1.2.0# ls -l deploy/kube-config/influxdb/total 28-rw-r--r-- 1 root root 414 Sep 14 12:47 grafana-service.yaml-rw-r--r-- 1 root root 942 Jan 20 15:15 heapster-controller.yaml-rw-r--r-- 1 root root 249 Sep 14 12:47 heapster-service.yaml-rw-r--r-- 1 root root 1465 Jan 19 21:39 influxdb-grafana-controller.yaml-rw-r--r-- 1 root root 259 Sep 14 12:47 influxdb-service.yaml
這裡有五個yaml(注意:與heapster源碼庫中最新的代碼已經有所不同,最新代碼將influxdb和grafana從influxdb-grafana-controller.yaml拆分開了)。其中的一些docker image在牆外,如果你有加速器,那麼你可以直接執行create命令;否則最好找到一些替代品: 比如:用signalive/heapster_grafana:2.6.0-2替換gcr.io/google_containers/heapster_grafana:v2.6.0-2。
建立pod的操作很簡單:
~/k8stest/dashboardinstall/heapster-1.2.0# kubectl create -f deploy/kube-config/influxdb/service "monitoring-grafana" createdreplicationcontroller "heapster" createdservice "heapster" createdreplicationcontroller "influxdb-grafana" createdservice "monitoring-influxdb" created
如果image pull順利的話,那麼這些pod和service的啟動是會很正常的。
//kube get pods -n kube-system... ...kube-system heapster-b1dwa 1/1 Running 0 1h 172.16.57.9 10.46.181.146 k8s-app=heapster,version=v6kube-system influxdb-grafana-8c0e0 2/2 Running 0 1h 172.16.57.10 10.46.181.146 name=influxGrafana... ...
我們用瀏覽器開啟kubernetes的Dashboard,期待中的圖形化和叢集度量指標資訊到哪裡去了呢?Dashboard還是一如既往的如上面圖示中那樣“簡樸”,顯然我們遇到問題了!
二、TroubleShooting
問題在哪?我們需要逐個檢視相關Pod的日誌:
# kubectl logs -f pods/influxdb-grafana-xxxxxx influxdb -n kube-system# kubectl logs -f pods/influxdb-grafana-xxxxxx grafana -n kube-system# kubectl logs -f pods/heapster-xxxxx -n kube-system
在heapster-xxxxx這個pod中,我們發現了大量失敗日誌:
E0119 13:14:37.838900 1 reflector.go:203] k8s.io/heapster/metrics/heapster.go:319: Failed to list *api.Pod: the server has asked for the client to provide credentials (get pods)E0119 13:14:37.838974 1 reflector.go:203] k8s.io/heapster/metrics/processors/node_autoscaling_enricher.go:100: Failed to list *api.Node: the server has asked for the client to provide credentials (get nodes)E0119 13:14:37.839516 1 reflector.go:203] k8s.io/heapster/metrics/processors/namespace_based_enricher.go:84: Failed to list *api.Namespace: the server has asked for the client to provide credentials (get namespaces)
heapster無法串連apiserver,擷取不要想要的資訊。從kube-apiserver的日誌(/var/log/upstart/kube-apiserver.log)也印證了這一點:
E0120 09:15:30.833928 12902 handlers.go:54] Unable to authenticate the request due to an error: crypto/rsa: verification errorE0120 09:15:30.834032 12902 handlers.go:54] Unable to authenticate the request due to an error: crypto/rsa: verification errorE0120 09:15:30.835324 12902 handlers.go:54] Unable to authenticate the request due to an error: crypto/rsa: verification error
從apiserver的日誌來看,heapster是通過apiserver的secure port串連的,由於我們的API server設定有https client端認證校正機制,因此兩者串連失敗。
三、通過insecure-port串連kube-apiserver
現在我們就來解決上述問題。
首先,我們會想到:能否讓heapster通過kube APIServer的insecure-port串連呢?在《Kubernetes叢集的安全配置》一文中我們提到過,kube-apiserver針對insecure-port接入的請求沒有任何限制機制,這樣heapster就可以擷取到它所想擷取到的所有有用資訊。
在heapster doc中的“Configuring Source”中,我們找到了串連kube-apiserver insecure-port的方法。不過在修改yaml之前,我們還是要先來看看當前heapster的一些啟動配置的含義:
//deploy/kube-config/influxdb/heapster-controller.yamlcommand: - /heapster - --source=kubernetes:https://kubernetes.default - --sink=influxdb:http://monitoring-influxdb:8086
我們看到heapster啟動時有兩個啟動參數:
–source指示資料來源,heapster是支援多種資料來源的,這裡用的是“kubernetes”類型的資料來源,地址是:kubernetes.default。這個網域名稱的全名是:kubernetes.default.svc.cluster.local,就是service “kubernetes”在cluster中的網域名稱,而”kubernetes”服務就是kube-apiserver,它的資訊如下:
# kubectl get servicesNAME CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes 192.168.3.1 443/TCP 99d... ...# kubectl describe svc/kubernetesName: kubernetesNamespace: defaultLabels: component=apiserver provider=kubernetesSelector: Type: ClusterIPIP: 192.168.3.1Port: https 443/TCPEndpoints: xxx.xxx.xxx.xxx:6443Session Affinity: ClientIPNo events.
因此,該網域名稱在k8s DNS中會被resolve為clusterip:192.168.3.1。外加https的預設連接埠是443,因此實際上heapster試圖訪問的apiserver地址是:https://192.168.3.1:443。
heapster啟動的另外一個參數是–sink,這個傳入的就是儲存後端,我們使用了InfluxDB,這裡傳入的就是上面建立的InfluxDB service的網域名稱和連接埠號碼,我們在cluster中也能尋找到該Service的資訊:
# kubectl get services -n kube-systemNAME CLUSTER-IP EXTERNAL-IP PORT(S) AGEmonitoring-influxdb 192.168.3.228 8083/TCP,8086/TCP 1h... ...
前面提到過,我們的APIServer在secure port上是有client端認證校正的,那麼以這樣的啟動參數啟動的heapster串連不上kube-apiserver就“合情合理”了。
接下來,我們按照”Configuring Source”中的方法,將heapster與kube-apiserver之間的串連方式改為通過insecure port進行:
// kube-config/influxdb/heapster-controller.yaml... ...command: - /heapster - --source=kubernetes:http://10.47.136.60:8080?inClusterConfig=false - --sink=influxdb:http://monitoring-influxdb:8086
修改後重新create。重新啟動後的heapster pod的日誌輸出如下:
# kubectl logs -f pod/heapster-hco5i -n kube-systemI0120 02:03:46.014589 1 heapster.go:71] /heapster --source=kubernetes:http://10.47.136.60:8080?inClusterConfig=false --sink=influxdb:http://monitoring-influxdb:8086I0120 02:03:46.014975 1 heapster.go:72] Heapster version v1.3.0-beta.0I0120 02:03:46.015080 1 configs.go:60] Using Kubernetes client with master "http://10.47.136.60:8080" and version v1I0120 02:03:46.015175 1 configs.go:61] Using kubelet port 10255E0120 02:03:46.025962 1 influxdb.go:217] issues while creating an InfluxDB sink: failed to ping InfluxDB server at "monitoring-influxdb:8086" - Get http://monitoring-influxdb:8086/ping: dial tcp 192.168.3.239:8086: getsockopt: connection refused, will retry on useI0120 02:03:46.026090 1 influxdb.go:231] created influxdb sink with options: host:monitoring-influxdb:8086 user:root db:k8sI0120 02:03:46.026214 1 heapster.go:193] Starting with InfluxDB SinkI0120 02:03:46.026286 1 heapster.go:193] Starting with Metric SinkI0120 02:03:46.051096 1 heapster.go:105] Starting heapster on port 8082I0120 02:04:05.211382 1 influxdb.go:209] Created database "k8s" on influxDB server at "monitoring-influxdb:8086"
之前的錯誤消失了!
我們再次開啟Dashboard查看pod資訊(這裡需要等上一小會兒,因為採集cluster資訊也是需要時間的),我們看到叢集度量指標資訊以圖形化的方式展現在我們面前了(可對比本文開頭那幅圖示):
四、通過secure port串連kube-apiserver
kube-apiserver的–insecure-port更多用來調試,生產環境下可是說關就關的,因此通過kube-apiserver的secure port才是“長治久安”之道。但要如何做呢?在heapster的”Configure Source”中給了一種使用serviceaccount的方法,但感覺略有些複雜啊。這裡列出一下我自己探索到的方法: 使用kubeconfig檔案!在《Kubernetes叢集Dashboard外掛程式安裝》一文中,我們已經配置好了kubeconfig檔案(預設位置:~/.kube/config),對於kubeconfig配置項還不是很瞭解的童鞋可以詳細參考那篇文章,這裡就不贅述了。
接下來,我們來修改heapster-controller.yaml:
// deploy/kube-config/influxdb/heapster-controller.yaml... ...spec: containers: - name: heapster image: kubernetes/heapster:canary volumeMounts: - mountPath: /srv/kubernetes name: auth - mountPath: /root/.kube name: config imagePullPolicy: Always command: - /heapster - --source=kubernetes:https://kubernetes.default?inClusterConfig=false&insecure=true&auth=/root/.kube/config - --sink=influxdb:http://monitoring-influxdb:8086 volumes: - name: auth hostPath: path: /srv/kubernetes - name: config hostPath: path: /root/.kube... ...
從上述檔案內容中–source的值我們可以看到,我們又恢複到初始kubernetes service的地址:https://kubernetes.default,但後面又跟了幾個參數:
inClusterConfig=false : 不使用service accounts中的kube config資訊;insecure=true:這裡偷了個懶兒:選擇對kube-apiserver發過來的服務端認證做信任處理,即不校正;auth=/root/.kube/config:這個是關鍵!在不使用serviceaccount時,我們使用auth檔案中的資訊來對應kube-apiserver的校正。
上述yaml中,我們還掛載了兩個path,以便pod可以訪問到相應的設定檔(~/.kube/config)和/srv/kubernetes下的認證。
儲存並重新建立相關pod後,Dashboard下的叢集度量指標資訊依然能以圖形化的方式展現出來,可見這種方法是ok的!
2017, bigwhite. 著作權.