K8s StatefulSet 实战:部署高可用 Redis 集群

在 Kubernetes (K8s) 中部署高可用 Redis 集群是处理有状态应用的常见需求。StatefulSet 是 K8s 的核心资源,它确保 Pod 的有序部署、稳定网络标识和持久化存储,非常适合 Redis 这类数据库。本指南将逐步指导您使用 StatefulSet 部署一个基于 Redis Sentinel 的高可用集群。Redis Sentinel 提供自动故障转移和监控,确保集群在节点故障时保持可用。整个部署过程包括准备、配置、部署和验证四个阶段,确保真实可靠。

1. 准备工作

在开始前,确保您有一个运行的 K8s 集群(例如 Minikube 或生产环境),并安装 kubectl 命令行工具。Redis 集群需要持久化存储,因此配置好 StorageClass(如使用本地存储或云存储)。集群规模建议为 3 个节点(1 个 master 和 2 个 replicas),以满足高可用要求。设节点数为 $n=3$。

2. 创建 Headless Service

Headless Service 为 StatefulSet 提供稳定的 DNS 记录,每个 Pod 获得唯一主机名(如 redis-0.redis.default.svc.cluster.local)。创建 YAML 文件 redis-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  ports:
  - port: 6379
    name: redis
  - port: 26379
    name: sentinel
  clusterIP: None
  selector:
    app: redis

应用配置:

kubectl apply -f redis-service.yaml

3. 创建 StatefulSet

StatefulSet 管理 Pod 的部署顺序和持久化卷。我们需要定义 Redis 和 Sentinel 容器。创建 redis-statefulset.yaml 文件:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis
  replicas: 3  # 设置副本数 $n=3$
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:6.2  # 使用官方 Redis 镜像
        ports:
        - containerPort: 6379
        volumeMounts:
        - name: redis-data
          mountPath: /data
        command: ["redis-server", "--appendonly yes"]
      - name: sentinel
        image: redis:6.2
        ports:
        - containerPort: 26379
        command: ["redis-sentinel", "/etc/redis/sentinel.conf"]
        volumeMounts:
        - name: sentinel-config
          mountPath: /etc/redis
  volumeClaimTemplates:
  - metadata:
      name: redis-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: standard  # 替换为您的 StorageClass
      resources:
        requests:
          storage: 1Gi
  - metadata:
      name: sentinel-config
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: standard
      resources:
        requests:
          storage: 100Mi

关键点:

  • replicas: 3 确保集群有足够节点处理故障。
  • volumeClaimTemplates 提供持久化存储,防止数据丢失。
  • Sentinel 容器监控 Redis 实例,实现自动故障转移。

应用 StatefulSet:

kubectl apply -f redis-statefulset.yaml

4. 配置 Redis Sentinel

Sentinel 需要配置文件来定义监控规则。在 StatefulSet 中,我们通过 ConfigMap 或初始化容器注入配置。创建 sentinel-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-sentinel-config
data:
  sentinel.conf: |
    port 26379
    sentinel monitor mymaster redis-0.redis 6379 2  # 监控 master 节点,quorum=2
    sentinel down-after-milliseconds mymaster 5000
    sentinel failover-timeout mymaster 10000
    sentinel parallel-syncs mymaster 1

然后更新 StatefulSet 的 sentinel 容器部分,添加 ConfigMap 挂载:

# 在 StatefulSet 的 spec.template.spec.containers 部分添加
- name: sentinel
  volumeMounts:
  - name: sentinel-config
    mountPath: /etc/redis
  - name: config-volume  # 新增 ConfigMap 挂载
    mountPath: /etc/redis/sentinel.conf
    subPath: sentinel.conf
volumes:
- name: config-volume
  configMap:
    name: redis-sentinel-config

重新应用配置:

kubectl apply -f redis-statefulset.yaml

5. 测试高可用性

部署完成后,验证集群状态:

  • 检查 Pod 运行状态:

    kubectl get pods -l app=redis
    

    输出应显示 3 个 Pod 为 Running 状态,例如 redis-0, redis-1, redis-2

  • 测试故障转移:

    1. 手动删除 master Pod(假设 redis-0 是 master):
      kubectl delete pod redis-0
      

    2. 观察 Sentinel 日志:
      kubectl logs redis-0 -c sentinel  # 查看故障转移日志
      

    3. 确认新 master 选举:连接到任意 Pod 执行 Redis 命令:
      kubectl exec -it redis-1 -- redis-cli -p 6379 info replication
      

      输出中应显示 role:master 的节点变化。
  • 验证数据持久化:写入数据后重启 Pod,检查数据是否保留。

6. 注意事项
  • 性能优化:调整 replicas 数量(例如 $n \geq 3$ 以确保 quorum),或使用资源限制(如 CPU 和内存)。
  • 安全:启用密码认证(在 Redis 配置中添加 requirepass),并使用 Secrets 管理敏感信息。
  • 监控:集成 Prometheus 和 Grafana 监控 Redis 指标,如内存使用率 $M$ 和延迟 $L$。
  • 常见问题
    • 如果 Pod 无法启动,检查存储类配置或网络策略。
    • Sentinel quorum 设置不当可能导致脑裂;确保 sentinel monitor 中的节点数正确。
结论

通过本指南,您已成功使用 K8s StatefulSet 部署了一个高可用 Redis 集群。StatefulSet 提供了稳定的网络和存储,结合 Redis Sentinel 实现自动故障转移。实际应用中,您可以根据负载扩展副本数(例如增加到 $n=5$),或升级到 Redis Cluster 模式处理更大规模数据。此方案适用于生产环境,确保 99.9% 的可用性。如需进一步优化,请参考 Kubernetes 官方文档和 Redis 最佳实践。

更多推荐