跳转到内容

Redis on Kubernetes 运维面试题

10 道题
分类
Kubernetes
子分类
middleware-ops
题目数
10 道
已阅读 0 / 10 题
1 Redis 在 Kubernetes 上有哪些部署模式?各自适用场景是什么?

答案:

Redis 在 Kubernetes 上的部署模式分为三种:StandaloneSentinelCluster

部署模式架构特征高可用数据分片适用场景
Standalone单实例 Deployment 或 StatefulSet开发测试、缓存场景(数据可丢失)
Sentinel一主多从 + Sentinel 哨兵集群自动故障转移读多写少、数据量在单机内存范围内
Cluster多主多从、分片架构自动故障转移 + 分片冗余16384 个 Slot数据量超过单机内存、高吞吐写入

Standalone 以 Deployment 部署 Redis 单实例,无持久化,数据丢失可接受时最简单。

Sentinel 架构在 K8s 上通常以三个独立 Deployment 部署 Sentinel 进程,Redis 主从以 StatefulSet 部署,通过 Headless Service 实现 Pod 间互相发现。

Cluster 模式需为每个节点配置 cluster-announce-ip,依赖 StatefulSet + Headless Service 提供稳定网络标识,扩容时需手动执行 Slot 迁移命令。

2 Redis Sentinel 在 Kubernetes 上如何部署?自动故障转移流程是怎样的?

答案:

Sentinel 在 K8s 上的经典部署架构:

# Sentinel Deployment(3 副本)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-sentinel
spec:
  replicas: 3
  selector:
    matchLabels:
      app: redis-sentinel
  template:
    spec:
      containers:
      - name: sentinel
        image: redis:7.2
        command: ["redis-sentinel"]
        args: ["/etc/redis/sentinel.conf"]
        ports:
        - containerPort: 26379

Redis 主从以 StatefulSet 部署:

# Redis StatefulSet(3 副本:1 主 2 从)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis-headless
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    spec:
      containers:
      - name: redis
        image: redis:7.2
        command: ["redis-server"]
        args: ["/etc/redis/redis.conf"]
        ports:
        - containerPort: 6379
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 50Gi

故障转移流程

  1. Sentinel 通过 Headless Service(redis-headless)发现所有 Redis Pod,持续 PING 检测
  2. 主观下线(SDOWN):单个 Sentinel 判定主节点不可达(down-after-milliseconds 超时)
  3. 客观下线(ODOWN):超过 quorum 数量的 Sentinel 确认主节点下线
  4. Sentinel Leader 选举:通过 Raft 协议选出执行故障转移的 Sentinel
  5. 从节点选举:按 slave-priority、复制偏移量、Run ID 排序选出新主
  6. 故障转移执行:新主执行 SLAVEOF NO ONE,其余从节点重定向到新主
  7. ConfigMap 更新:K8s 场景下 Sentinel 通过 ConfigMap 或 Operator 更新客户端连接信息

关键配置

参数说明
sentinel monitor mymaster <ip> <port> <quorum>监控主节点,quorum 设为 2
sentinel down-after-milliseconds mymaster 5000主观下线判定超时 5 秒
sentinel failover-timeout mymaster 60000故障转移超时 60 秒
sentinel parallel-syncs mymaster 1故障转移后并行同步的从节点数
6 Redis Cluster 在 Kubernetes 上部署的核心挑战是什么?

答案:

挑战说明解决方案
Pod IP 变化Pod 重启后 IP 变更,nodes.conf 中的节点地址失效使用 StatefulSet + Headless Service 提供稳定 DNS 名;配置 cluster-announce-ip 为 Pod 域名
Cluster Bus 通信Cluster Bus 端口固定 16379(6379 + 10000)需路由可达Service 暴露 Cluster Bus 端口;NetworkPolicy 放行 TCP/16379
配置持久化nodes.conf 记录集群拓扑,Pod 重启后不能丢失挂载 PVC 存储 nodes.conf;或使用 ConfigMap + Operator 管理
Slot 迁移与 Pod 生命周期直接 kubectl delete pod 会导致 Slot 丢失缩容前先执行手动 Slot 迁移;使用 PDB 防止意外驱逐
客户端重定向Redis Cluster 返回 MOVED / ASK 错误,需客户端支持客户端使用支持集群模式的驱动(JedisCluster、go-redis cluster)
跨可用区延迟跨区 Gossip 通信延迟可能触发误判 PFAIL增大 cluster-node-timeout;配置 cluster-require-full-coverage no

配置示例

# redis.conf
cluster-enabled yes
cluster-config-file /data/nodes.conf
cluster-node-timeout 15000
cluster-require-full-coverage no
cluster-announce-hostname $(hostname).redis-cluster-headless.redis.svc.cluster.local
# cluster-announce-ip $(POD_IP)  # Pod IP 在重启后会变,**推荐用 cluster-announce-hostname + DNS**
cluster-announce-port 6379
cluster-announce-bus-port 16379
7 Redis Operator 生态有哪些选择?各自优劣是什么?

答案:

Operator维护方功能特点适用场景
Redis Enterprise OperatorRedis Inc.商业版,支持 Active-Active、集群自动管理、GUI 运维企业级生产环境,需要商业支持
Spotahome Redis OperatorSpotahome开源,支持 Sentinel 和 Cluster 模式,自动故障转移社区主流选择,中小规模集群
Ot Redis OperatorOT-CONTAINER-KIT开源,支持 Cluster 和 Sentinel,Leader/Follower 模式轻量级场景,K8s 原生集成

对比详情

能力Redis EnterpriseSpotahomeOt Operator
Sentinel 模式
Cluster 模式
自动扩缩容手动手动
Active-Active 地理分布
备份恢复✅(内置 S3)手动手动
Prometheus 监控集成
许可证商业Apache 2.0Apache 2.0
K8s CRD 管理丰富基础基础

Spotahome 示例 CR

apiVersion: databases.spotahome.com/v1
kind: RedisFailover
metadata:
  name: redisfailover
spec:
  sentinel:
    replicas: 3
  redis:
    replicas: 3
    storage:
      persistentVolumeClaim:
        metadata:
          name: redis-data
        spec:
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 50Gi
8 Redis 持久化在 Kubernetes 上如何实现?

答案:

Redis 提供三种持久化策略,在 K8s 上均依赖 PVC 存储。

策略机制数据安全性性能影响K8s 实现要点
RDB定期全量内存快照可能丢失最近几分钟数据低(fork 子进程写入)PVC 存储 /data/dump.rdbsave 参数控制触发频率
AOF追加写日志最多丢 1 秒数据(everysec中(持续 IO 写入)PVC 存储 /data/appendonly.aof,配合 aof-rewrite 控制文件增长
RDB + AOF两者同时开启高(AOF 优先于 RDB 加载)较高PVC 同时存储两种文件,恢复时优先使用 AOF
No Persistence纯内存数据可丢失最优适用于纯缓存场景

RDB 配置

save 900 1       # 900 秒内至少 1 个键变更
save 300 10      # 300 秒内至少 10 个键变更
save 60 10000    # 60 秒内至少 10000 个键变更
dbfilename dump.rdb
dir /data

AOF 配置

appendonly yes
appendfsync everysec    # 每秒同步一次(推荐)
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

K8s StatefulSet 持久化配置

volumeClaimTemplates:
- metadata:
    name: data
  spec:
    accessModes: ["ReadWriteOnce"]
    storageClassName: "ssd-storage"
    resources:
      requests:
        storage: 100Gi

性能考量:RDB fork 采用 Copy-on-Write(COW) 机制,fork 后父子进程共享内存页,仅在写入时才复制新页(高写入场景下内存可能接近翻倍)。K8s 建议 memory limit >= maxmemory * 1.5(保守)或 * 2(高写入场景),并使用 redis-check-rdb 定期校验备份文件。AOF 写入需确保底层存储 IOPS 满足 appendfsync everysec 的延迟要求。

9 Redis 使用 StatefulSet 与 PVC 存储如何配置?

答案:

StatefulSet 为 Redis 提供稳定的网络标识和持久化存储,是生产部署的基础。

核心设计要点

  1. ServiceName:绑定 Headless Service,生成稳定的 Pod DNS 名(<pod-name>.<service-name>.<namespace>.svc.cluster.local
  2. volumeClaimTemplates:每个 Pod 自动创建独立 PVC,保证存储隔离
  3. Pod 顺序管理podManagementPolicy 设为 Parallel 可并行启动(Sentinel/Cluster 场景)
  4. 存储类选择:使用 SSD/high-IOPS StorageClass

完整配置

# Headless Service
apiVersion: v1
kind: Service
metadata:
  name: redis-headless
spec:
  clusterIP: None
  selector:
    app: redis
  ports:
  - name: redis
    port: 6379
  - name: cluster-bus
    port: 16379
# StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis-headless
  replicas: 6
  podManagementPolicy: Parallel
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values: ["redis"]
            topologyKey: kubernetes.io/hostname
      containers:
      - name: redis
        image: redis:7.2
        command: ["redis-server"]
        args: ["/etc/redis/redis.conf"]
        ports:
        - containerPort: 6379
          name: redis
        - containerPort: 16379
          name: cluster-bus
        resources:
          requests:
            cpu: "2"
            memory: 4Gi
          limits:
            cpu: "4"
            memory: 8Gi
        volumeMounts:
        - name: data
          mountPath: /data
        - name: config
          mountPath: /etc/redis
        readinessProbe:
          exec:
            command: ["redis-cli", "ping"]
          initialDelaySeconds: 10
          periodSeconds: 5
        livenessProbe:
          exec:
            command: ["redis-cli", "ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
      volumes:
      - name: config
        configMap:
          name: redis-config
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "ssd-storage"
      resources:
        requests:
          storage: 100Gi
10 Redis 备份与恢复在 Kubernetes 上如何实现?

答案:

备份策略

方案类型RPO实现方式
RDB 快照 + S3全量分钟级CronJob 定时执行 BGSAVE,上传 dump.rdb 至 S3/MinIO
AOF 连续备份增量秒级sidecar 容器持续同步 /data/appendonly.aof 至对象存储
混合(RDB + AOF)全量 + 增量秒级RDB 为基准备份,AOF 为增量补充
Volume Snapshot存储层取决于 CSI利用 CSI Snapshot 创建 PVC 快照

CronJob 备份示例

apiVersion: batch/v1
kind: CronJob
metadata:
  name: redis-backup
spec:
  schedule: "0 */4 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: redis:7.2
            env:
            - name: S3_BUCKET
              value: "redis-backups"
            command:
            - /bin/sh
            - -c
            - |
              redis-cli -h redis-0.redis-headless BGSAVE
              # 等待 BGSAVE 完成
              while [ $(redis-cli -h redis-0.redis-headless INFO persistence | grep rdb_bgsave_in_progress | cut -d: -f2) -eq 1 ]; do
                sleep 5
              done
              aws s3 cp /data/dump.rdb s3://$S3_BUCKET/redis-backup-$(date +%Y%m%d-%H%M).rdb
            volumeMounts:
            - name: data
              mountPath: /data
          volumes:
          - name: data
            persistentVolumeClaim:
              claimName: data-redis-0
          restartPolicy: OnFailure

恢复流程

  1. 从 S3 下载最新 RDB 文件至 PVC
  2. 恢复 AOF 文件(如有)至 /data/appendonly.aof
  3. 启动 Redis,自动加载持久化文件
  4. 验证数据一致性:redis-cli INFO keyspace
  5. 切换流量至恢复后的实例
27 Redis 跨集群复制与灾备如何实现?

答案:

方案同步方式RPORTO适用场景
异地从节点异步复制(REPLICAOF秒级分钟级同地域跨可用区
双写应用层同时写两个集群取决于应用实现秒级最终一致性容忍场景
Redis-Shake 持续同步RDB + AOF 解析同步秒级分钟级跨云迁移、异地灾备
Redis Enterprise Active-ActiveCRDT 冲突解决毫秒级秒级全球分布式,需要商业许可
RDB 定时备份 + 异地恢复全量备份 + S3 同步小时级30 分钟+低成本灾备

异地从节点配置

# 灾备集群从节点
REPLICAOF <primary-cluster-master-ip> 6379

Redis-Shake 灾备同步(持续模式)

[sync_reader]
address = "primary-cluster-redis:6379"

[redis_writer]
address = "dr-cluster-redis:6379"

[advanced]
dir = /data
ncpu = 4

灾备演练流程

  1. 停止源集群写入
  2. 确认灾备集群数据同步完成(对比 master_repl_offset
  3. 灾备集群从节点执行 REPLICAOF NO ONE 提升为主
  4. DNS/Service 切换流量至灾备集群
  5. 验证业务功能完整性
  6. 数据反向同步:灾备 → 原集群恢复后回流
29 Redis on Kubernetes 常见故障排查

答案:

故障现象可能原因排查步骤解决方案
OOM Kill内存超出 Limitkubectl describe pod 查看 OOMKilled;检查 maxmemory 配置增加 resources.limits.memory;降低 maxmemory;启用逐出策略
CPU ThrottlingCPU Limit 过低检查 container_cpu_cfs_throttled 指标提高 CPU Limit 或使用 Guaranteed QoS
启动失败RDB/AOF 损坏redis-check-rdb /data/dump.rdbredis-check-aof /data/appendonly.aof修复或删除损坏文件重新启动
复制延迟网络带宽不足、主写入量大INFO replication 查看 master_repl_offset - slave_repl_offset增大网络带宽;使用 repl-diskless-sync
脑裂Sentinel quorum 不满足;网络分区检查 Sentinel 日志;SENTINEL MASTER mymaster调整 quorum 为 N/2+1;配置 min-slaves-to-write
集群状态 fail主节点宕机且无从节点接管 SlotCLUSTER INFO 查看 cluster_state修复故障节点;CLUSTER FAILOVER 手动切换
磁盘空间满RDB/AOF 文件增长过大df -h /data调整 auto-aof-rewrite-min-size;扩展 PVC
客户端连接泄漏未正确关闭连接CLIENT LIST 查看连接数增长应用端 Connection Pool 设置 MaxLifetime
Pod 无法调度PDB + Anti-Affinity 冲突kubectl describe pod 查看 Events调整 PDB minAvailable;增加节点
慢查询阻塞KEYS *、O(N) 命令SLOWLOG GET 10替换为 SCAN;RENAME 禁用危险命令

排查常用命令

# K8s 侧
kubectl describe pod redis-0
kubectl logs redis-0 -c redis --tail=200
kubectl exec -it redis-0 -- redis-cli INFO
kubectl exec -it redis-0 -- redis-cli CLUSTER INFO
kubectl get events --field-selector involvedObject.name=redis-0

# Redis 侧
redis-cli INFO all
redis-cli CLUSTER NODES
redis-cli SLOWLOG GET 20
redis-cli CLIENT LIST
redis-cli MEMORY STATS
redis-cli --latency -h <host>
30 Redis on Kubernetes 生产环境最佳实践总结

答案:

部署架构

  1. 使用 StatefulSet 而非 Deployment,保障稳定的网络标识和持久化存储
  2. 配置 Headless ServiceclusterIP: None),为每个 Pod 提供独立 DNS 记录
  3. 设置 Pod Anti-Affinity 确保 Redis 实例分散在不同节点 / 可用区
  4. 使用 Operator(Spotahome / Ot Operator)管理 Sentinel 或 Cluster 拓扑,减少运维复杂度
  5. 配置 PodDisruptionBudget 防止节点维护时批量驱逐

资源配置

  1. resources.limits.memory >= maxmemory * 1.5,为 RDB fork 和系统开销留余量
  2. resources.requests.memory = resources.limits.memory(Guaranteed QoS),避免被 OOM Kill
  3. resources.requests.cpu >= 2,生产环境不共享 CPU
  4. 使用 SSD / NVMe StorageClass 且 IOPS >= 3000
  5. PVC 大小按 maxmemory * 1.5(RDB)或 maxmemory * 3(AOF)预估

高可用与可靠性

  1. Sentinel 部署 3 个或 5 个(奇数),quorum = N/2 + 1
  2. 配置 min-replicas-to-write 1min-replicas-max-lag 10,防止主节点脑裂后写入丢失
  3. Cluster 模式每个主节点至少配 1 个从节点,跨可用区分布
  4. 配置 cluster-require-full-coverage no,允许部分 Slot 不可用时集群继续服务
  5. 定期执行备份演练和故障转移演练

持久化与备份

  1. 生产环境开启 AOF(everysec)+ RDB 混合持久化
  2. 配置 auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb
  3. 使用 CronJob 定时执行 RDB 备份并上传至对象存储(S3/MinIO)
  4. 定期执行 redis-check-rdbredis-check-aof 验证备份文件完整性
  5. 备份数据跨区域复制(S3 Cross-Region Replication)

安全

  1. 为每个应用创建独立 ACL 用户,最小权限原则(+@read -@write -@dangerous
  2. 启用 TLS 加密通信(tls-port),使用 cert-manager 自动管理证书
  3. 重命名或禁用危险命令:rename-command FLUSHALL ""rename-command CONFIG ""
  4. 配置 protected-mode yesbind 限制访问网段
  5. 不暴露 Redis 端口至公网,使用 NetworkPolicy 限制入站流量

监控与告警

  1. 部署 redis_exporter 作为 Sidecar 容器,通过 Prometheus PodMonitor 采集指标
  2. 配置关键告警:内存 > 80%、连接数 > 80%、命中率 < 90%、复制延迟 > 10MB
  3. 使用 Grafana Dashboard(如 763)集中展示 Redis 集群状态
  4. 集成日志采集(Filebeat/Fluentd → Elasticsearch/Loki),结构化解析 Redis 日志
  5. 设置慢查询告警:SLOWLOG 增长速率异常时触发通知