【基于 Prometheus Operator 实现 K8s 环境下 Redis Cluster 集群监控部署】

提示:本文原创作品,良心制作,干货为主,简洁清晰,一看就会

文章目录

  • 前言
  • 一、流程概述
    • [1.1 实验环境介绍](#1.1 实验环境介绍)
    • [1.2 整体流程概述](#1.2 整体流程概述)
  • 二、Redis集群搭建
  • 三、监控Redis
    • [3.1 创建redis-exporter](#3.1 创建redis-exporter)
    • [3.2 创建redis-exporter-svc](#3.2 创建redis-exporter-svc)
    • [3.3 创建scrapeconfig](#3.3 创建scrapeconfig)
    • [3.4 grafana添加dashboard](#3.4 grafana添加dashboard)

前言

在云原生环境中,Redis Cluster 作为高性能分布式缓存,其稳定运行至关重要。然而,面对动态调度的 Kubernetes 集群,传统的监控方案往往难以灵活适配。借助 Prometheus Operator,我们可以声明式地定义监控目标,利用 ScrapeConfig自动采集指标,并结合 Grafana 实现可视化与告警。本文将从部署 Redis Cluster 到配置 Exporter、编写 ScrapeConfig 资源,完整阐述如何以 Operator 原生方式构建生产级的 Redis 集群监控体系,帮助运维人员快速发现瓶颈、保障数据服务可靠性。

一、流程概述

1.1 实验环境介绍

我的实验环境:

主机名 ip 作用
K8s-master1 192.168.13.136 k8s控制节点
K8s-master2 192.168.13.137 k8s控制节点
K8s-master3 192.168.13.138 k8s控制节点
k8s-node1 192.168.13.139 k8s工作节点
k8s-node2 192.168.13.140 k8s工作节点
NFS 192.168.13.141 NFS服务端,提供存储

当前,我的高可用 Kubernetes 集群已部署完毕,Prometheus Operator 也已完成安装配置。接下来,我将开始实操,对集群内运行的 Redis Cluster 进行监控配置

1.2 整体流程概述

  1. 部署 Redis 集群

    使用 StatefulSet + Headless Service 创建多节点 Redis 实例

    目的:为每个 Redis Pod 分配稳定的网络标识,便于 Prometheus 精确抓取每个实例

  2. 部署单实例 Redis Exporter

    monitoring 命名空间启动一个 Exporter Deployment

    目的:开启多目标模式,让一个 Exporter 代理采集所有 Redis 实例的指标

  3. 创建 Exporter Service

    为 Exporter 创建 ClusterIP Service

    目的 :提供固定域名(redis-exporter.monitoring.svc),作为 Prometheus 抓取的统一入口

  4. 配置 ScrapeConfig

    编写 ScrapeConfig 资源,列出所有 Redis 地址,并通过 relabelings 将 __address__ 改写为 Exporter 的 Service 地址,同时将原始 Redis 地址存入 __param_target

    目的 :让 Prometheus 每次抓取时请求 Exporter 的 /scrape?target=<某个Redis地址>,从而轮询采集所有 Redis 节点

  5. 验证与可视化

    检查 Prometheus Targets 页面确认所有 Redis 实例 UP,并导入 Grafana 仪表盘

二、Redis集群搭建

yaml 复制代码
root@k8s-master1:~# mkdir /k8s/redis
root@k8s-master1:~# cd /k8s/redis/
root@k8s-master1:/k8s/redis# vim redis-cm-svc-pod.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-conf
data:
  redis.conf: |
    port 6379
    # 启用集群模式
    cluster-enabled yes
    # 集群节点状态持久化文件路径
    cluster-config-file /var/lib/redis/nodes.conf
    # 集群节点超时时间
    cluster-node-timeout 5000
    # 开启AOF持久化
    appendonly yes
    # 数据存放目录
    dir /var/lib/redis
    # 关闭保护模式
    protected-mode no
    # 不以守护进程方式进行
    daemonize no
    pidfile /var/run/redis.pid
    # 日志输出到标准输出
    logfile ""
    # RDB持久化规则
    save 900 1
    save 300 10
    save 60 10000

---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
  labels:
    app: redis
spec:
  ports:
    - name: redis-port
      port: 6379
    - name: cluster
      port: 16379
  clusterIP: None
  selector:
    app: redis
    appCluster: redis-cluster

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis-service
  replicas: 6
  selector:
    matchLabels:
      app: redis
      appCluster: redis-cluster
  template:
    metadata:
      labels:
        app: redis
        appCluster: redis-cluster
    spec:
      # 初始化容器(在主容器启动前执行)
      initContainers:
      - name: fix-permissions
      # 使用busybox镜像执行权限修复
        image: busybox:latest
        command:
        - sh
        - -c
        - chown -R 999:999 /var/lib/redis
        volumeMounts:
        - name: redis-data
          mountPath: /var/lib/redis
      containers:
      - name: redis
        image: redis:latest
        command:
        - /bin/sh
        - -c
        - |
          # 将基础配置文件复制到临时位置
          cat /etc/redis/redis.conf.base > /tmp/redis.conf
          # 注入集群广播地址(使用pod的dns名称)
          echo "cluster-announce-ip ${HOSTNAME}.redis-service.${NAMESPACE}.svc" >> /tmp/redis.conf
          # 注入客户端通信端口
          echo "cluster-announce-port 6379" >> /tmp/redis.conf
          # 注入集群总线端口
          echo "cluster-announce-bus-port 16379" >> /tmp/redis.conf
          # 启动redis服务并使用生产的配置文件
          exec redis-server /tmp/redis.conf
        env:
         # 获取pod名称
        - name: HOSTNAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
          # 获取pod所在命名空间
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        ports:
        - containerPort: 6379
          name: redis
        - containerPort: 16379
          name: cluster
        volumeMounts:
        - name: redis-config
          mountPath: /etc/redis/redis.conf.base
          subPath: redis.conf
        - name: redis-data
          mountPath: /var/lib/redis
      volumes:
      - name: redis-config
        configMap:
          name: redis-conf
  volumeClaimTemplates:
  - metadata:
      name: redis-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
      storageClassName: "nfs-client"
yaml 复制代码
root@k8s-master1:/k8s/redis# kubectl apply -f redis-cm-svc-pod.yaml
root@k8s-master1:~# kubectl get svc
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)              AGE
kubernetes      ClusterIP   10.96.0.1    <none>        443/TCP              63d
redis-service   ClusterIP   None         <none>        6379/TCP,16379/TCP   4m58s
root@k8s-master1:~# kubectl get pod -o wide
NAME      READY   STATUS      RESTARTS        AGE     IP               NODE        NOMINATED NODE   READINESS GATES
redis-0   1/1     Running     0               5m5s    10.244.169.172   k8s-node2   <none>           <none>
redis-1   1/1     Running     0               4m18s   10.244.36.104    k8s-node1   <none>           <none>
redis-2   1/1     Running     0               3m30s   10.244.169.160   k8s-node2   <none>           <none>
redis-3   1/1     Running     0               2m41s   10.244.36.98     k8s-node1   <none>           <none>
redis-4   1/1     Running     0               110s    10.244.169.145   k8s-node2   <none>           <none>
redis-5   1/1     Running     0               61s     10.244.36.95     k8s-node1   <none>           <none>
yaml 复制代码
## 创建三主三从的集群
root@k8s-master1:~# kubectl exec -it redis-0 -- redis-cli --cluster create \
  redis-0.redis-service.default.svc:6379 \
  redis-1.redis-service.default.svc:6379 \
  redis-2.redis-service.default.svc:6379 \
  redis-3.redis-service.default.svc:6379 \
  redis-4.redis-service.default.svc:6379 \
  redis-5.redis-service.default.svc:6379 \
  --cluster-replicas 1
yaml 复制代码
## 随意进入一个pod中查看集群信息
root@k8s-master1:~# kubectl exec -it redis-0 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
Defaulted container "redis" out of: redis, fix-permissions (init)
root@redis-0:/data# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> cluster nodes
c3d5a88f71633dbefbbbc625f25b27847a0bec55 redis-2.redis-service.default.svc:6379@16379 master - 0 1781071190000 3 connected 10923-16383
c92a766749dc30edd3c2e1727f853849649150cc redis-4.redis-service.default.svc:6379@16379 slave 3a7f6997df5cf28a4de91888c1fe9559f4767a91 0 1781071191581 1 connected
76a6873936f5f14d95b0b2b0d0413699544950d4 redis-3.redis-service.default.svc:6379@16379 slave c3d5a88f71633dbefbbbc625f25b27847a0bec55 0 1781071190070 3 connected
15ecc0072b2d8001d4b39a0d9f69cb23911524c8 redis-1.redis-service.default.svc:6379@16379 master - 0 1781071191585 2 connected 5461-10922
3a7f6997df5cf28a4de91888c1fe9559f4767a91 redis-0.redis-service.default.svc:6379@16379 myself,master - 0 0 1 connected 0-5460
c90bb3d1e4d5760c7abff207f924b9bfad999cc8 redis-5.redis-service.default.svc:6379@16379 slave 15ecc0072b2d8001d4b39a0d9f69cb23911524c8 0 1781071190575 2 connected

三、监控Redis

3.1 创建redis-exporter

redis-exporter是一个独立的程序,负责连接redis cluster集群,采集各种监控指标并翻译成Prometheus能识别的metrics格式,并通过9121端口/metrics暴露出来

没有redis-exporter,Prometheus根本看不懂redis的数据

yaml 复制代码
root@k8s-master1:~/kube-prometheus/manifests# vim redis-exporter.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-exporter
  namespace: monitoring
  labels:
    app: redis-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis-exporter
  template:
    metadata:
      labels:
        app: redis-exporter
    spec:
      containers:
      - name: redis-exporter
        image: oliver006/redis_exporter:latest   # 必须使用完整镜像名
        ports:
        - containerPort: 9121
          name: metrics
        # 不加任何 args,先测试基础运行
root@k8s-master1:~/kube-prometheus/manifests# kubectl apply -f  redis-exporter.yaml 

3.2 创建redis-exporter-svc

由于K8S里的pod ip是会变的,所以我们需要创建一个svc给redis-exporter提供一个稳定的clusterip+dns域名redis-exporter.monitoring:9121

redis-exporter-svc用来保证Prometheus总能稳定连接到redis-exporter

yaml 复制代码
root@k8s-master1:~/kube-prometheus/manifests# vim redis-exporter-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: redis-exporter
  namespace: monitoring
  labels:
    app: redis-exporter
spec:
  selector:
    app: redis-exporter
  ports:
  - name: metrics
    port: 9121
    targetPort: 9121
root@k8s-master1:~/kube-prometheus/manifests# kubectl apply -f  redis-exporter-svc.yaml

3.3 创建scrapeconfig

scrapeconfig作用是告诉Prometheus怎么监控redis集群,它定义了三件事:

1,要监控6个redis节点;2,通过redis-exporter去采集;3,每个redis节点都是一个独立监控目标

scrapeconfig要监控6个redis域名,但是不直接连接redis,它是通过redis-exporter.monitoring:9121这个地址去采集,svc把请求转给redis-exporter,然后exporter去连接6个redis节点,拿到指标返回给Prometheus

yaml 复制代码
root@k8s-master1:~/kube-prometheus/manifests# vim redis-scrapeconfig.yaml 
apiVersion: monitoring.coreos.com/v1alpha1
kind: ScrapeConfig
metadata:
  name: redis-exporter
  namespace: monitoring
spec:
  scrapeInterval: 30s
  jobName: redis-exporter
  metricsPath: /scrape
  scheme: HTTP
  staticConfigs:
  - targets:
      # Prometheus逐个把redis地址传给exporter;exporter用地址去连接对应redis pod,拿到指标 → 返回给 Prometheus
      - redis://redis-0.redis-service.default.svc.cluster.local:6379
      - redis://redis-1.redis-service.default.svc.cluster.local:6379
      - redis://redis-2.redis-service.default.svc.cluster.local:6379
      - redis://redis-3.redis-service.default.svc.cluster.local:6379
      - redis://redis-4.redis-service.default.svc.cluster.local:6379
      - redis://redis-5.redis-service.default.svc.cluster.local:6379
  relabelings:
    # 将原始目标地址(__address__)提取到 __param_target 参数中
    - sourceLabels: [__address__]
      targetLabel: __param_target
    # 将 __param_target 的值复制到 instance 标签,便于区分
    - sourceLabels: [__param_target]
      targetLabel: instance
    # 修改 __address__ 为 Exporter 的地址,使 Prometheus 抓取 Exporter 的 /scrape 端点
    - targetLabel: __address__
      replacement: redis-exporter.monitoring:9121
root@k8s-master1:~/kube-prometheus/manifests# kubectl apply -f  redis-scrapeconfig.yaml

浏览器访问Prometheus,可以看到6个redis实例已经被添加

3.4 grafana添加dashboard

grafana官网:https://grafana.com/grafana/dashboards/

登录grafana,添加redis的dashboard

这里我选择了一个常用的dashboard,大家也可以去grafana官网自行挑选

redis dashboard:https://grafana.com/grafana/dashboards/17507-1-redis-exporter-dashboard/

至此,基于 Prometheus Operator 监控 Redis Cluster 集群的配置全部完成!


注:

文中若有疏漏,欢迎大家指正赐教。

本文为100%原创,转载请务必标注原创作者,尊重劳动成果。

求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~

相关推荐
bmjIjFNC81 小时前
Redis分布式锁进第九十一篇
数据库·redis·分布式
维尔康2 小时前
【无标题】
redis
是一个Bug2 小时前
Docker 与 Kubernetes:从“集装箱”到“远洋舰队”
docker·容器·kubernetes
java_cj2 小时前
阅读 k8s 源码的准备工作
云原生·容器·kubernetes
AOwhisky2 小时前
Redis 学习笔记(第二期):核心数据类型与消息队列实战
运维·数据库·redis·笔记·学习·云计算
呦呦鹿鸣Rzh2 小时前
Redis Lua 脚本:从入门到避坑指南
redis·junit·lua
开发者联盟league2 小时前
使用Jenkins整合Sonarqube/Gitlab/Harbor/Kubernetes实现CICD
kubernetes·gitlab·jenkins
Harvy_没救了2 小时前
【云计算】华为公有云构建高可用Redis集群
数据库·redis·云计算
Ze3G90nYt2 小时前
Redis 分布式锁进阶第一百三十一篇
数据库·redis·分布式