【Kubernetes】使用kube-prometheus-stack快速在k8s内搭建Prometheus全家桶

前言

最近因为需要做一些redis-cluster-operator的故障演练,新搭建了一个k8s集群,新的k8s集群需要搭建一套监控告警系统,对于Prometheus,之前自己在虚拟机上练过手,比较麻烦,需要先后安装Prometheus、Grafana、AlertManager,还需要修改各种配置,今天一想,现在都2202年了,肯定有更简单的方法,于是在社区找到了kube-prometheus-stack

部署

GitHub地址:https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack

简单看了下,有两种方法进行部署:

第一种方法是下载manifests包里的yaml,再通过kubectl部署;

第二种方法是通过Helm打包部署;

依次执行下面的命令:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

helm repo update

helm install prometheus-community/kube-prometheus-stack --generate-name

我使用的是第一种方法,因为用helm时,拉取镜像timeout,试了几次都没有成功,第一种方法需要先下载yaml文件,上传到服务器再部署,虽然麻烦点,但是相较于手动创建,可以节省很多时间,而且所有相关的资源都是自动创建关联,可以很省心,最主要的是试了一次就成功了。

下载好的代码包解压后,将manifests文件夹打包,上传到k8s服务器,解压之后就是下面这一堆yaml文件:

再根据GitHub上的指示,执行代码即可

执行命令:

kubectl apply --server-side -f manifests/setup
until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
kubectl apply -f manifests/

稍作等待之后,查看k8s集群内,创建了一个新的namespace:monitoring,还有所需的CRD、service、StatefulSet、Deployment、Secret、ConfigMap等等…

需要注意的是,这一套是基于operator去管理的,通过创建CRD定义各类资源,Operator会监听CRD的创建、修改,去管理对应的资源。

我在部署的时候,有两个pod拉取镜像一直失败,替换了镜像地址之后部署成功(圈红的为替换后的,之前的镜像应该是内网下载不了,需要魔法,我就找了个之前用的镜像)

kube-state-metrics:kubesphere/kube-state-metrics:v1.9.7

prometheus-adapter:directxman12/k8s-prometheus-adapter:v0.7.0

在部署过程中就没遇到其他问题了,通过Service的ClusterIP就可以访问了:

可以看到部署完成之后,所有相关的组件,都自动部署了exportor,并配置好了,还有各个组件的告警规则,也配置好了

不得不说,很方便,一气呵成,后续可以根据自己的需要,进行增减。

实践

添加告警规则

可以看到,告警规则也是一个CRD,所以只需要创建一个类型为Prometheus Rule的资源就行:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  labels:
    app.kubernetes.io/component: alert-router
    app.kubernetes.io/instance: main
    app.kubernetes.io/name: redis
    app.kubernetes.io/part-of: kube-prometheus
    app.kubernetes.io/version: 0.24.0
    prometheus: k8s
    role: alert-rules
  managedFields:
    - apiVersion: monitoring.coreos.com/v1
      fieldsType: FieldsV1
  name: redis-rules
  namespace: monitoring
spec:
  groups:
    - name: redis-rules
      rules:
      - alert: slowlog
        annotations:
          description: 一分钟内共出现 {{ printf "%.2f" $value }} 次慢查询
          summary: 发现慢查询
        expr: delta(redis_slowlog_last_id [5m]) >= 5
        labels:
          severity: critical
      - alert: used memory increase too fast
        annotations:
          description: 按照最近10分钟的内存使用增长速度计算,预计20分钟后将会达到配置上限
          summary: 发现内存使用量增长过快
        expr: predict_linear(redis_memory_used_bytes [10m], 60 * 20) > redis_memory_max_bytes
        labels:
          severity: critical
      - alert: used memory larger than history peak
        annotations:
          description: 当前内存使用量为 {{ printf "%.2f" $value }} GB
          summary: 内存使用量超过历史峰值
        expr: (redis_memory_used_bytes / (1024 * 1024 * 1024)) >= (redis_memory_used_peak_bytes / (1024 * 1024 * 1024)) and (redis_memory_used_bytes / redis_memory_max_bytes) > 0.8
        labels:
          severity: critical
      - alert: option-memory usage in hight ratio
        annotations:
          description: 内存使用超过90%,将开启自动扩容
          summary: 内存使用超过redis最大设置内存的90%
        expr: (redis_memory_used_bytes / redis_memory_max_bytes) * 100 > 90 and redis_memory_max_bytes >= (1024 * 1024 * 1024)
        labels:
          severity: critical
      - alert: memory usage in high fragmentation ratio
        annotations:
          description: 当前内存碎片率为 {{ printf "%.2f" $value }},理想值为1至1.4之间
          summary: 内存碎片率高
        expr: redis_memory_used_rss_bytes / redis_memory_used_bytes > 1.4 and redis_memory_used_bytes >= 1024 * 1024 * 1024
        for: 1w
        labels:
          severity: warning
      - alert: memory usage in low fragmentation ratio
        annotations:
          description: 当前内存碎片率为 {{ printf "%.2f" $value }},理想值为1至1.4之间
          summary: 内存碎片率小于1,redis-server进程可能正在使用swap区,导致响应速度降低
        expr: redis_memory_used_rss_bytes / redis_memory_used_bytes < 1 and redis_memory_used_bytes >= 512 * 1024 * 1024
        for: 1w
        labels:
          severity: warning
      - alert: rdb bgsave too slow
        annotations:
          description: 最近一次持久化时间为 {{ $value }} 秒,建议降低该节点内存使用量至4GB以内
          summary: rdb持久化时间过长
        expr: redis_rdb_last_bgsave_duration_sec > 120 and time() - redis_rdb_last_save_timestamp_seconds < 3600
        labels:
          severity: critical
      - alert: redis instance maybe down
        annotations:
          description: redis实例可能出现故障
          summary: redis实例宕机
        expr: redis_up == 0
        for: 5m
        labels:
          severity: critical
      - alert: redis master slave failover
        annotations:
          description: redis集群发生主从切换
          summary: redis主从切换
        expr: changes(redis_instance_info[5m]) > 1
        labels:
          severity: critical
      - alert: state of cluster is unnormal
        annotations:
          description: 集群中发现节点的状态异常,并持续2分钟,触发此告警。
          summary: 检测到集群:{{$labels.redis_kun_name}}不可用,已持续2分钟。
        expr: redis_cluster_state != 1
        for: 2m
        labels:
          group: xadd-redis
          severity: critical
      - alert: slots of cluster assigned unnormally
        annotations:
          description: 发现集群槽位分配小于16384,触发此告警。
          summary: 集群:{{$labels.redis_kun_name}} 的槽位未完全分配,当前分配槽位数量为:{{value}}expr: redis_cluster_slots_assigned < 16384
        for: 2m
        labels:
          group: xadd-redis
          severity: critical
      - alert: slave lag too long
        annotations:
          description: Slave节点滞后时间超过10秒,触发此报警,集群cluster-node-timeout配置的是15秒。
          summary: 集群:{{$labels.redis_kun_name}} 中Master节点:{{$labels.kubernetes_pod_name}} 的Slave节点滞后超过10秒,Slave IP为{{$labels.slave_ip}}expr: redis_connected_slave_lag_seconds > 10
        labels:
          group: xadd-redis
          severity: warning
      - alert: cluster known nodes decreased
        annotations:
          description: 在两分钟内,集群的已知节点数量减少,触发此报警。
          summary: 集群:{{$labels.redis_kun_name}} 在两分钟内节点数减少了{{value}}个,请检查集群状态是否正常。
        expr: redis_cluster_known_nodes offset 2m - redis_cluster_known_nodes > 0
        labels:
          group: xadd-redis
          severity: critical
      - alert: redis exporter maybe down
        annotations:
          description: 3分钟内,若up状态的exporter数量减少,则认为减少的exporter存在宕机可能,触发此告警。
          summary: 集群:{{$labels.redis_kun_name}} 的exporter可能宕机,exporter实例地址为:{{$labels.instance}}expr: up{namespace="redis"} unless up{namespace="redis"} offset 6m
        for: 5m
        labels:
          group: xadd-redis
          severity: warning

保存好之后,创建成功

修改配置

有一个需求,对于k8s内新创建的pod,如果需要采集指标,希望可以自动添加到prometheus配置的target中,或者在需要手动添加采集目标时,不需要去prometheus的pod中修改的配置文件,单不说麻不麻烦,找到配置文件都比较繁琐。

基于这个需求,可以借助additionalScrapeConfigs来实现,这应该是prometheus-operator提供的能力,目的是通过维护一个外部的配置文件,来导入到prometheus内部的配置中。

先以Secret的方式创建好一个配置文件:

kind: Secret
apiVersion: v1
metadata:
  name: prometheus-additional-scrape
  namespace: monitoring
data:
  additional_pods.yaml: ''
type: Opaque

配置文件的内容先随便填,创建好之后,点击修改按钮:

填入以下内容:

- job_name: kubernetes-pods
  scrape_interval: 15s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  kubernetes_sd_configs:
  - api_server: null
    role: pod
    namespaces:
      names: []
  relabel_configs:
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    separator: ;
    regex: "true"
    replacement: $1
    action: keep
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
    separator: ;
    regex: (.+)
    target_label: __metrics_path__
    replacement: $1
    action: replace
  - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
    separator: ;
    regex: ([^:]+)(?::\d+)?;(\d+)
    target_label: __address__
    replacement: $1:$2
    action: replace
  - separator: ;
    regex: __meta_kubernetes_pod_label_(.+)
    replacement: $1
    action: labelmap
  - source_labels: [__meta_kubernetes_namespace]
    separator: ;
    regex: (.*)
    target_label: namespace
    replacement: $1
    action: replace
  - source_labels: [__meta_kubernetes_pod_name]
    separator: ;
    regex: (.*)
    target_label: kubernetes_pod_name
    replacement: $1
    action: replace
  - source_labels: [__meta_kubernetes_namespace, redis_kun_name]
    separator: /
    regex: (.*)
    target_label: alias
    replacement: $1
    action: replace
  - source_labels: [redis_cluster_size]
    separator: ;
    regex: (.*)
    target_label: cluster_size
    replacement: $1
    action: replace

我们找到prometheus的定义文件,添加additionalScrapeConfigs相关配置:

在spec下添加:

  additionalScrapeConfigs:
    key: additional_pods.yaml
    name: prometheus-additional-scrape

需要和之前创建的Secret对应上。

此时通过页面查看prometheus的配置,发现这段配置已经加上去了

在需要被prometheus自动发现的pod上,只需要添加以下注解即可:

  annotations:
    prometheus.io/path: /metrics
    prometheus.io/port: '9100'
    prometheus.io/scrape: 'true'

Prometheus Operator会自动去发现并监控具有prometheus.io/scrape=true这个annotations的pod。

如果发现以下报错:

failed to list *v1.Pod: pods is forbidden: User \"system:serviceaccount:monitoring:prometheus-k8s\" cannot list resource \"pods\" in API group \"\" at the cluster scope"
ts=2022-06-14T09:46:55.087Z caller=klog.go:116 level=error component=k8s_client_runtime func=ErrorDepth msg="pkg/mod/k8s.io/client-go@v0.24.0/tools/cache/reflector.go:167: Failed to watch *v1.Pod: failed to list *v1.Pod: pods is forbidden: User \"system:serviceaccount:monitoring:prometheus-k8s\" cannot list resource \"pods\" in API group \"\" at the cluster scope"

这是因为没有权限导致的,此时prometheus是拉取不到pod的指标的,看报错是没有对pod的list、watch权限,加上即可,需要修改名为prometheus-k8s的ClusterRole:

rules:
  - verbs:
      - get
      - list
      - watch
    apiGroups:
      - ''
    resources:
      - nodes/metrics
      - nodes/proxy
      - services
      - endpoints
      - pods
  - verbs:
      - get
    nonResourceURLs:
      - /metrics

保存之后,规则已生效:

这样一来,权限就加完了,也不再报错了,再看prometheus的web页面,相关的pod已经自动拉取到了

大功告成!

Kube-prometheus-stack 是一个用于 KubernetesPrometheus 集成栈,通常包括 Prometheus、Alertmanager 和 Grafana 等组件。为了增加身份验证,你可以按照以下步骤操作: 1. **添加基本认证**: - 修改 `values.yaml` 文件中的 `prometheus.prometheusOperator.scrapeSecrets` 或 `grafana.ini` 中的 `auth.basic` 配置,设置基本身份验证的用户名和密码。 ```yaml prometheusOperator: scrapeSecrets: # 添加或修改为需要使用的 secret 名称 - name: my-auth-secret grafana.ini: auth: basic: users: - name: admin password: <password> ``` 2. **使用 OAuth2 认证**: - 如果你想支持 OAuth2,可以配置 `prometheusOperator` 部分的 `oauth2ClientID` 和 `oauth2ClientSecret`。 - 需要在外部提供一个 OAuth2 服务,如 GitHub、Google 或 Keycloak,并创建对应的客户端配置。 3. **RBAC(Role-Based Access Control)**: - 使用 Kubernetes RBAC 来限制访问权限,只允许特定角色(Role或ClusterRole)的用户访问Prometheus和Grafana。这涉及到创建 ServiceAccount、Role 和 RoleBinding。 4. **安装额外的认证插件**: - Kube-prometheus-stack 并未直接包含认证功能,但可以考虑安装像 `prometheus-k8s` 这样的第三方Prometheus适配器,它可能内置了身份验证支持。 完成以上配置后,重启 Prometheus 和 Grafana 服务,让它们应用新的配置。记得检查相关文档,确保所选的认证方式与集群的其他安全策略兼容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值