共计 5352 个字符,预计需要花费 14 分钟才能阅读完成。
这篇文章将为大家详细讲解有关使用 Prometheus 和 Thanos 怎样进行高可用 K8S 监控,文章内容质量较高,因此丸趣 TV 小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
介 绍 Prometheus 高可用的必要性
在过去的几年里,Kubernetes 的采用量增长了数倍。很明显,Kubernetes 是容器编排的不二选择。与此同时,Prometheus 也被认为是监控容器化和非容器化工作负载的绝佳选择。监控是任何基础设施的一个重要关注点,我们应该确保我们的监控设置具有高可用性和高可扩展性,以满足不断增长的基础设施的需求,特别是在采用 Kubernetes 的情况下。
因此,今天我们将部署一个集群化的 Prometheus 设置,它不仅能够弹性应对节点故障,还能保证合适的数据存档,供以后参考。我们的设置还具有很强的可扩展性,以至于我们可以在同一个监控保护伞下跨越多个 Kubernetes 集群。
当前方案
大部分的 Prometheus 部署都是使用持久卷的 pod,而 Prometheus 则是使用联邦机制进行扩展。但是并不是所有的数据都可以使用联邦机制进行聚合,在这里,当你增加额外的服务器时,你往往需要一个机制来管理 Prometheus 配置。
解决方法
Thanos 旨在解决上述问题。在 Thanos 的帮助下,我们不仅可以对 Prometheus 的实例进行多重复制,并在它们之间进行数据去重,还可以将数据归档到 GCS 或 S3 等长期存储中。
实施过程 Thanos 架构
图片来源: https://thanos.io/quick-tutorial.md/
Thanos 由以下组件构成:
Thanos sidecar:这是运行在 Prometheus 上的主要组件。它读取和归档对象存储上的数据。此外,它还管理着 Prometheus 的配置和生命周期。为了区分每个 Prometheus 实例,sidecar 组件将外部标签注入到 Prometheus 配置中。该组件能够在 Prometheus 服务器的 PromQL 接口上运行查询。Sidecar 组件还能监听 Thanos gRPC 协议,并在 gRPC 和 REST 之间翻译查询。
Thanos 存储:该组件在对象 storage bucket 中的历史数据之上实现了 Store API,它主要作为 API 网关,因此不需要大量的本地磁盘空间。它在启动时加入一个 Thanos 集群,并公布它可以访问的数据。它在本地磁盘上保存了少量关于所有远程区块的信息,并使其与 bucket 保持同步。通常情况下,在重新启动时可以安全地删除此数据,但会增加启动时间。
Thanos 查询:查询组件在 HTTP 上监听并将查询翻译成 Thanos gRPC 格式。它从不同的源头汇总查询结果,并能从 Sidecar 和 Store 读取数据。在 HA 设置中,它甚至会对查询结果进行重复数据删除。
HA 组的运行时重复数据删除
Prometheus 是有状态的,不允许复制其数据库。这意味着通过运行多个 Prometheus 副本来提高高可用性并不易于使用。简单的负载均衡是行不通的,比如在发生某些崩溃之后,一个副本可能会启动,但是查询这样的副本会导致它在关闭期间出现一个小的缺口(gap)。你有第二个副本可能正在启动,但它可能在另一个时刻(如滚动重启)关闭,因此在这些副本上面的负载均衡将无法正常工作。
Thanos Querier 则从两个副本中提取数据,并对这些信号进行重复数据删除,从而为 Querier 使用者填补了缺口(gap)。
Thanos Compact 组件将 Prometheus 2.0 存储引擎的压实程序应用于对象存储中的块数据存储。它通常不是语义上的并发安全,必须针对 bucket 进行单例部署。它还负责数据的下采样——40 小时后执行 5m 下采样,10 天后执行 1h 下采样。
Thanos Ruler 基本上和 Prometheus 的规则具有相同作用,唯一区别是它可以与 Thanos 组件进行通信。
配 置前期准备
要完全理解这个教程,需要准备以下东西:
对 Kubernetes 和使用 kubectl 有一定的了解。
运行中的 Kubernetes 集群至少有 3 个节点(在本 demo 中,使用 GKE 集群)
实现 Ingress Controller 和 Ingress 对象(在本 demo 中使用 Nginx Ingress Controller)。虽然这不是强制性的,但为了减少创建外部端点的数量,强烈建议使用。
创建用于 Thanos 组件访问对象存储的凭证(在本例中为 GCS bucket)。
创建 2 个 GCS bucket,并将其命名为 Prometheus-long-term 和 thanos-ruler。
创建一个服务账户,角色为 Storage Object Admin。
下载密钥文件作为 json 证书,并命名为 thanos-gcs-credentials.json。
使用凭证创建 Kubernetes sercret
kubectl create secret generic thanos-gcs-credentials –from-file=thanos-gcs-credentials.json
部署各类组件
部署 Prometheus 服务账户、Clusterroler 和 Clusterrolebinding
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
apiVersion: v1
kind: ServiceAccount
metadata:
name: monitoring
namespace: monitoring
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: monitoring
namespace: monitoring
rules:
- apiGroups: [ ]
resources:
- nodes
- nodes/proxy
- services
- endpoints
- pods
verbs: [get , list , watch]
- apiGroups: [ ]
resources:
- configmaps
verbs: [get]
- nonResourceURLs: [/metrics]
verbs: [get]
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: monitoring
subjects:
- kind: ServiceAccount
name: monitoring
namespace: monitoring
roleRef:
kind: ClusterRole
Name: monitoring
apiGroup: rbac.authorization.k8s.io
---
以上 manifest 创建了 Prometheus 所需的监控命名空间以及服务账户、clusterrole 以及 clusterrolebinding。
部署 Prometheues 配置 configmap
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-server-conf
labels:
name: prometheus-server-conf
namespace: monitoring
data:
prometheus.yaml.tmpl: |-
global:
scrape_interval: 5s
evaluation_interval: 5s
external_labels:
cluster: prometheus-ha
# Each Prometheus has to have unique labels.
replica: $(POD_NAME)
rule_files:
- /etc/prometheus/rules/*rules.yaml
alerting:
# We want our alerts to be deduplicated
# from different replicas.
alert_relabel_configs:
- regex: replica
action: labeldrop
alertmanagers:
- scheme: http
path_prefix: /
static_configs:
- targets: [alertmanager:9093]
scrape_configs:
- job_name: kubernetes-nodes-cadvisor
scrape_interval: 10s
scrape_timeout: 10s
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:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
# Only for Kubernetes ^1.7.3.
# See: https://github.com/prometheus/prometheus/issues/2916
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
metric_relabel_configs:
- action: replace
source_labels: [id]
regex: ^/machine\.slice/machine-rkt\\x2d([^\\]+)\\.+/([^/]+)\.service$
target_label: rkt_container_name
replacement: ${2}-${1}
- action: replace
source_labels: [id]
regex: ^/system\.slice/(.+)\.service$
target_label: systemd_service_name
replacement: ${1}
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- 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
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2