K8s 云原生應用如何接入監(jiān)控.md
前段時間有朋友問我如何在 kubernetes 里搭建監(jiān)控系統,恰好在公司也在維護內部的可觀測平臺,正好借這個機會整理下目前常見的自建監(jiān)控方案。
一個完整的監(jiān)控系統通常包含以下的內容:
- 指標暴露:將系統內部需要關注的指標暴露出去
- 指標采集:收集并存儲暴露出來的指標
- 指標展示:以各種圖表展示和分析收集到的數據
- 監(jiān)控告警:當某些關鍵指標在一定時間周期內出現異常時,可以及時通知相關人員
圖片
對于 k8s 的監(jiān)控通常分為兩個部分:
- k8s 自帶的系統組建
- 業(yè)務 Pod 暴露出來的監(jiān)控指標
系統組建
對于 kubernetes 系統組建可以由 cAdvisor 提供監(jiān)控能力,默認情況下這個功能是開箱即用的,我們只需要在 Prometheus 中配置相關的任務抓取即可:
- job_name: nodeScrape/monitoring/cadvisor-scrape/0
scrape_interval: 30s
scrape_timeout: 15s
scheme: https
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
tls_config:
insecure_skip_verify: true
relabel_configs:
- source_labels: [__meta_kubernetes_node_name]
target_label: node
- action: replace
source_labels: [__meta_kubernetes_node_name]
separator: ;
target_label: __address__
regex: (.*)
replacement: kubernetes.default.svc:443
- action: replace
source_labels: [__meta_kubernetes_node_name]
separator: ;
target_label: __metrics_path__
regex: (.+)
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
kubernetes_sd_configs:
- role: node
圖片
這樣的話就可以監(jiān)控 k8s 的內存、CPU 之類的數據。
具體提供了哪些指標可以參考這里:https://github.com/google/cadvisor/blob/master/docs/storage/prometheus.md#prometheus-container-metrics
也可以找一些常用的監(jiān)控面板:https://grafana.com/grafana/dashboards/13077-kubernetes-monitoring-dashboard-kubelet-cadvisor-node-exporter/
k8s 不但提供了 cAdvisor 的數據,還有其他類似的 endpoint: /metrics/resource & /metrics/probes
具體暴露出來的指標可以參考官方文檔:https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/
業(yè)務指標
對于業(yè)務應用來說第一步也是需要將自己的指標暴露出去,如果是 Java 的話可以使用 Prometheus 提供的庫:
<!-- The client -->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.16.0</version>
</dependency>
<!-- Hotspot JVM metrics-->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.16.0</version>
</dependency>
它會自動將 JVM 相關的指標暴露出去,如果是在 VM 中的應用,那只需要簡單的配置下 static_configs 就可以抓取指標了:
scrape_configs:
- job_name: 'springboot'
scrape_interval: 10s
static_configs:
- targets: ['localhost:8080'] # Spring Boot ip+port
但在 kubernetes 中這個 IP 是不固定的,每次重建應用的時候都會發(fā)生變化,所以我們需要一種服務發(fā)現機制來動態(tài)的找到 Pod 的 IP。
- 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_label_component]
action: replace
target_label: job
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
Prometheus 提供了一個 kubernetes_sd_configs 的服務發(fā)現機制,他會在 kubernetes 中查找 Pod 中是否有配置以下的注解:
template:
metadata:
annotations:
prometheus.io/path: /metrics
prometheus.io/port: "8082"
prometheus.io/scrape: "true"
都配置成功后我們便可以在 Prometheus 的管理后臺查看到具體的服務信息:
圖片
狀態(tài)是 UP 則表明抓取數據成功,這樣我們就可以在 Prometheus 中查詢到數據了。
圖片
Prometheus 除了支持 k8s 的服務發(fā)現之外還支持各種各樣的服務發(fā)現,比如你已經使用了 Consul 或者是 Erueka 作為注冊中心,也可以直接配置他們的地址然后進行服務發(fā)現,這樣應用信息發(fā)生變化時 Prometheus 也能及時感知到。
當然 docker/http/docker 等都是支持的,可以按需選擇。
OpenTelemetry
隨著這兩年可觀測性標準的完善,許多廠商都在往 OpenTelemetry 上進行遷移,接入 OpenTelemetry 與直接使用 Prometheus 最大的不同是:
不再由 Prometheus 主動抓取應用指標,而是由應用給 OpenTelemetry-Collector 推送標準化的可觀測數據(包含日志、trace、指標),再由它遠程寫入 Prometheus 這類時序數據庫中。
整體流程圖如下:
圖片
對應用的最大的區(qū)別就是可以不再使用剛才提到 Prometheus 依賴,而是只需要掛載一個 javaagent 即可:
java -javaagent:opentelemetry-javaagent-2.4.0-SNAPSHOT.jar \
-Dotel.traces.exporter=otlp \
-Dotel.metrics.exporter=otlp \
-Dotel.logs.exporter=none \
-Dotel.service.name=java-demo \
-Dotel.exporter.otlp.protocol=grpc \
-Dotel.propagators=tracecontext,baggage \
-Dotel.exporter.otlp.endpoint=http://127.0.0.1:5317 -jar target/demo-0.0.1-SNAPSHOT.jar
而其中會新增的一個 OpenTelemetry-Collector項目,由它將收到的指標數據轉發(fā)給 Prometheus,所以在它的配置里會配置 Prometheus 的地址:
exporters:
otlphttp/prometheus:
endpoint: http://prometheus:9292/api/v1/otlp
tls:
insecure: true
總結
關于 Prometheus 的安裝可以參考官方的 operator 或者是 helm:https://github.com/prometheus-operator/kube-prometheus。
當然如果不想使用 Prometheus 也推薦使用 VictoriaMetrics,是一個完全兼容 Prometheus 但是資源占用更少的時序數據庫。