自從 上次 介紹了 Prometheus 以後,就想到要在 k8s 中使用了,不過,在這以前,先介紹下 k8s 的監控。node
k8s 默認以及推薦的監控體系是它本身的一套東西:Heapster + cAdvisor + Influxdb + Grafana,具體能夠看 這裏 。git
包括 k8s 自身的 HPA (Horizontal Pod Autoscaler),默認從 Heapster 中獲取數據進行自動伸縮。(順便提一句,當你部署完 k8s 集羣以後,若是從 Dashboard 中看不到監控數據,每每就是由於你沒有部署 Heapster,或者網絡層有問題, Dashboard 沒法訪問 Heapster。)github
那,這跟咱們介紹的 Prometheus 有什麼關係?後端
首先,它們都是一套監控解決方案,而 k8s 沒有把 Prometheus 做爲默認監控,所以,若是你想直接使用 HPA,你仍是須要部署 Heapster。api
其次,kubelet 中的 cAdvisor 實際上是支持 Prometheus 做爲存儲的後端的,只是相對於 Prometheus 本身的 SD 解決方案來講,太弱了點。網絡
最後,k8s 1.6 以後,在 annotations 中配置 custom metrics 的方式已經被移除了,而根據
Prometheus 的監控數據來進行自動伸縮仍是頗有可操做性的。app
其實部署很簡單,關鍵是配置,所以這裏着重介紹下,如何配置。spa
首先,先來了解下,什麼是 relabel_config。debug
就如字面意思而言,它的做用是 Prometheus 抓取 metrics 以前,就將對象相關的 labels 重寫。下面是它幾個重要的 label:對象
其次,上次提到,咱們能夠用到 Service Discovery 這個功能,其中就包含 Kubernetes SD。
它包含四種角色:
因爲篇幅所限,這裏只是簡單介紹下其中的 node 還有 pod 角色:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
- job_name: 'kubernetes-nodes' scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token kubernetes_sd_configs: - role: node relabel_configs: # 即從 __meta_kubernetes_node_label_<labelname> 這個配置中取出 labelname 以及 value - action: labelmap regex: __meta_kubernetes_node_label_(.+) # 配置 address 爲 k8s api 的地址,相關的 ca 證書以及 token 在上面配置 - target_label: __address__ replacement: kubernetes.default.svc:443 # 取出全部的 node,而後設置 /api/v1/nodes/<node_name>/proxy/metrics 爲 metrics path - source_labels: - __meta_kubernetes_node_name regex: (.+) target_label: __metrics_path__ replacement: /api/v1/nodes/${1}/proxy/metrics |
接下來的這個 pod 角色挺重要:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
- job_name: 'kubernetes-pods' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] action: replace regex: ([^:]+)(?::\d+)?;(\d+) replacement: $1:$2 target_label: __address__ - action: labelmap regex: __meta_kubernetes_pod_label_(.+) - source_labels: [__meta_kubernetes_namespace] action: replace target_label: kubernetes_namespace - source_labels: [__meta_kubernetes_pod_name] action: replace target_label: kubernetes_pod_name |
在定義了這個角色以後,你只要在你部署的應用 Pod 描述中,加入如下 annotations 就能讓 Prometheus 自動發現此 Pod 並採集監控數據了:
1 2 3 |
annotations: prometheus.io/scrape: "true" prometheus.io/port: "<your app port>" |
其它詳細配置請看 這裏。
最後,部署 Prometheus,須要注意的是,咱們已經在 k8s 以外單獨部署了一套,爲了統一處理,在這裏是打算做爲中轉的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
apiVersion: v1 kind: ConfigMap metadata: name: prometheus namespace: kube-system labels: app: prometheus data: prometheus.yml: |- # 省略,在這裏定義你須要的配置 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: prometheus namespace: kube-system spec: replicas: 1 template: metadata: labels: app: prometheus spec: containers: - name: prometheus image: prom/prometheus:latest args: - '-config.file=/prometheus-data/prometheus.yml' # 顯然,這裏沒有用 `Stateful Sets`,存儲時間不用太長 - '-storage.local.retention=48h0m0s' ports: - name: prometheus containerPort: 9090 volumeMounts: - name: data-volume mountPath: /prometheus-data volumes: - name: data-volume configMap: name: prometheus --- # 簡單處理,直接使用 NodePort 暴露服務,你也可使用 Ingress apiVersion: v1 kind: Service metadata: name: prometheus namespace: kube-system spec: selector: app: prometheus ports: - name: prometheus protocol: TCP port: 9090 nodePort: 30090 type: NodePort |
而在咱們外部單獨的 Prometheus 中,須要配置 Federate,將 k8s 中 Prometheus 採集的 metrics 所有同步出來。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- job_name: 'federate' scrape_interval: 15s honor_labels: true metrics_path: '/federate' params: 'match[]': - '{job=~".+"}' # 取 k8s 裏面部署的 Prometheus 中全部的 job 數據 static_configs: - targets: - '<k8s-node1>:30090' - '<k8s-node2>:30090' - '<k8s-node3>:30090' |