Skip to content

Redis Docker/K8s 部署指南

Docker 部署 Redis

使用 Docker 部署 Redis 是一种轻量级、快速的部署方式,适合开发环境和小规模生产环境。以下是几种常见的 Docker 部署方案。

单实例部署

单实例部署是最简单的 Redis 部署方式,适合开发测试或对高可用性要求不高的场景。

  1. 基本部署 这是 Redis 单实例的最基础部署方式,使用默认配置启动 Redis 服务。

    bash
    # 拉取 Redis 镜像(使用轻量级的 Alpine 版本)
    docker pull redis:7.2-alpine
    
    # 启动 Redis 容器,映射主机 6379 端口到容器 6379 端口
    docker run -d \
      --name redis \
      -p 6379:6379 \
      redis:7.2-alpine
  2. 带密码的部署 为了提高安全性,建议为 Redis 设置密码。使用 --requirepass 参数可以在启动时设置密码。

    bash
    docker run -d \
      --name redis \
      -p 6379:6379 \
      redis:7.2-alpine \
      redis-server --requirepass "your_strong_password"
  3. 使用自定义配置文件 对于需要复杂配置的生产环境,建议使用自定义配置文件。这种方式可以更灵活地调整 Redis 的各项参数。

    bash
    # 创建配置文件目录
    mkdir -p /data/redis/config
    
    # 创建 redis.conf 文件,配置绑定地址、端口、密码和持久化等参数
    cat > /data/redis/config/redis.conf << EOF
    bind 0.0.0.0      # 允许所有IP访问
    port 6379         # 监听端口
    requirepass your_strong_password  # 设置访问密码
    appendonly yes    # 开启 AOF 持久化
    dir /data         # 数据存储目录
    EOF
    
    # 启动容器,挂载配置文件和数据目录
    docker run -d \
      --name redis \
      -p 6379:6379 \
      -v /data/redis/config/redis.conf:/etc/redis/redis.conf \
      -v /data/redis/data:/data \
      redis:7.2-alpine \
      redis-server /etc/redis/redis.conf

主从复制部署

主从复制是 Redis 实现高可用性的基础,通过将主节点的数据复制到从节点,可以实现读写分离,提高系统的吞吐量和可用性。

  1. 创建主节点 首先创建主节点,主节点负责处理写请求,并将数据同步到从节点。

    bash
    docker run -d \
      --name redis-master \
      -p 6379:6379 \
      -v /data/redis/master/data:/data \
      redis:7.2-alpine \
      redis-server --requirepass "master_password" --masterauth "master_password"
  2. 创建从节点 然后创建从节点,从节点通过 --replicaof 参数指定主节点的 IP 和端口,实现数据同步。

    bash
    # 获取主节点的 IP 地址
    MASTER_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-master)
    
    # 启动从节点,指定主节点地址和端口
    docker run -d \
      --name redis-slave \
      -p 6380:6379 \
      -v /data/redis/slave/data:/data \
      redis:7.2-alpine \
      redis-server --requirepass "master_password" --masterauth "master_password" --replicaof $MASTER_IP 6379
  3. 验证主从关系 使用 info replication 命令可以查看 Redis 的主从复制状态,验证主从关系是否正常建立。

    bash
    # 连接主节点,查看复制状态
    docker exec -it redis-master redis-cli -a "master_password" info replication
    
    # 连接从节点,查看复制状态
    docker exec -it redis-slave redis-cli -a "master_password" info replication

持久化配置

Redis 持久化是指将内存中的数据保存到磁盘,以防止数据丢失。Redis 支持两种持久化方式:RDB(快照)和 AOF(追加文件),以及混合持久化方式。

  1. RDB 持久化 RDB 持久化是将 Redis 在某个时间点的数据生成快照并保存到磁盘。适合用于备份和灾难恢复。

    bash
    docker run -d \
      --name redis \
      -p 6379:6379 \
      -v /data/redis/data:/data \
      redis:7.2-alpine \
      redis-server --save 900 1 --save 300 10 --save 60 10000
    • --save 900 1:900秒内至少有1个键被修改,生成快照
    • --save 300 10:300秒内至少有10个键被修改,生成快照
    • --save 60 10000:60秒内至少有10000个键被修改,生成快照
  2. AOF 持久化 AOF 持久化是将 Redis 执行的每个写命令追加到文件末尾。适合用于需要更高数据安全性的场景。

    bash
    docker run -d \
      --name redis \
      -p 6379:6379 \
      -v /data/redis/data:/data \
      redis:7.2-alpine \
      redis-server --appendonly yes --appendfsync everysec
    • --appendonly yes:开启 AOF 持久化
    • --appendfsync everysec:每秒将缓冲区内容写入磁盘
  3. 混合持久化 混合持久化结合了 RDB 和 AOF 的优点,AOF 文件的前半部分是 RDB 格式的快照,后半部分是 AOF 格式的命令。

    bash
    docker run -d \
      --name redis \
      -p 6379:6379 \
      -v /data/redis/data:/data \
      redis:7.2-alpine \
      redis-server --appendonly yes --appendfsync everysec --aof-use-rdb-preamble yes
    • --aof-use-rdb-preamble yes:开启混合持久化

Docker Compose 部署

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Docker Compose 可以更方便地管理 Redis 及其相关服务。

  1. 单实例部署 使用 Docker Compose 部署单实例 Redis,便于管理配置和数据卷。

    yaml
    version: '3'  # 使用 Compose 文件格式版本 3
    services:
      redis:  # 服务名称
        image: redis:7.2-alpine  # 使用的 Redis 镜像
        container_name: redis  # 容器名称
        ports:
          - "6379:6379"  # 端口映射,主机端口:容器端口
        volumes:
          - ./data:/data  # 数据卷,主机目录:容器目录
          - ./redis.conf:/etc/redis/redis.conf  # 配置文件映射
        command: redis-server /etc/redis/redis.conf  # 启动命令
        restart: always  # 总是重启策略
        environment:
          - TZ=Asia/Shanghai  # 设置时区
  2. 主从复制部署 使用 Docker Compose 可以快速部署 Redis 主从复制架构,简化了多节点的管理。

    yaml
    version: '3'
    services:
      redis-master:  # 主节点服务
        image: redis:7.2-alpine
        container_name: redis-master
        ports:
          - "6379:6379"
        volumes:
          - ./master/data:/data  # 主节点数据目录
        command: redis-server --requirepass "master_password" --masterauth "master_password"
        restart: always
        environment:
          - TZ=Asia/Shanghai
    
      redis-slave1:  # 第一个从节点
        image: redis:7.2-alpine
        container_name: redis-slave1
        ports:
          - "6380:6379"
        volumes:
          - ./slave1/data:/data  # 从节点1数据目录
        command: redis-server --requirepass "master_password" --masterauth "master_password" --replicaof redis-master 6379
        restart: always
        depends_on:
          - redis-master  # 依赖主节点,主节点启动后再启动从节点
        environment:
          - TZ=Asia/Shanghai
    
      redis-slave2:  # 第二个从节点
        image: redis:7.2-alpine
        container_name: redis-slave2
        ports:
          - "6381:6379"
        volumes:
          - ./slave2/data:/data  # 从节点2数据目录
        command: redis-server --requirepass "master_password" --masterauth "master_password" --replicaof redis-master 6379
        restart: always
        depends_on:
          - redis-master  # 依赖主节点
        environment:
          - TZ=Asia/Shanghai

Kubernetes 部署 Redis

Kubernetes 是一个容器编排平台,适合部署大规模、高可用性的 Redis 集群。以下是几种常见的 Kubernetes 部署方案。

单实例部署(Deployment)

单实例部署适合开发测试环境或对高可用性要求不高的场景。使用 Deployment 可以方便地管理 Redis 实例的生命周期。

  1. 创建 ConfigMap ConfigMap 用于存储 Redis 的配置信息,便于集中管理和更新配置。

    yaml
    apiVersion: v1  # API 版本
    kind: ConfigMap  # 资源类型
    metadata:
      name: redis-config  # ConfigMap 名称
      namespace: default  # 命名空间
    data:
      redis.conf: |  # 配置文件内容
        bind 0.0.0.0        # 允许所有 IP 访问
        port 6379           # 监听端口
        requirepass your_strong_password  # 设置访问密码
        appendonly yes      # 开启 AOF 持久化
        appendfsync everysec  # 每秒将缓冲区内容写入磁盘
        dir /data           # 数据存储目录
  2. 创建 Deployment Deployment 用于管理 Pod 的创建、更新和删除,确保指定数量的副本运行。

    yaml
    apiVersion: apps/v1  # API 版本
    kind: Deployment  # 资源类型
    metadata:
      name: redis  # Deployment 名称
      namespace: default  # 命名空间
    spec:
      replicas: 1  # 副本数量
      selector:
        matchLabels:  # 标签选择器,用于匹配 Pod
          app: redis
      template:
        metadata:
          labels:
            app: redis  # Pod 标签
        spec:
          containers:
          - name: redis  # 容器名称
            image: redis:7.2-alpine  # 容器镜像
            ports:
            - containerPort: 6379  # 容器内端口
            volumeMounts:  # 卷挂载
            - name: redis-config  # 引用卷名称
              mountPath: /etc/redis/redis.conf  # 挂载路径
              subPath: redis.conf  # 子路径,用于指定挂载 ConfigMap 中的特定文件
            - name: redis-data  # 引用数据卷
              mountPath: /data  # 数据挂载路径
            args:  # 容器启动参数
            - redis-server
            - /etc/redis/redis.conf
            resources:  # 资源限制
              requests:  # 请求资源
                memory: "256Mi"
                cpu: "100m"
              limits:  # 限制资源
                memory: "512Mi"
                cpu: "500m"
            livenessProbe:  # 存活探针,用于检测容器是否存活
              exec:  # 执行命令进行检测
                command:
                - redis-cli
                - -a
                - your_strong_password
                - ping
              initialDelaySeconds: 30  # 启动后 30 秒开始检测
              periodSeconds: 10  # 每 10 秒检测一次
            readinessProbe:  # 就绪探针,用于检测容器是否就绪
              exec:
                command:
                - redis-cli
                - -a
                - your_strong_password
                - ping
              initialDelaySeconds: 5  # 启动后 5 秒开始检测
              periodSeconds: 10  # 每 10 秒检测一次
          volumes:  # 卷定义
          - name: redis-config  # 卷名称
            configMap:  # 使用 ConfigMap 作为卷源
              name: redis-config  # 引用上面创建的 ConfigMap
          - name: redis-data  # 数据卷名称
            emptyDir: {}  # 使用临时目录作为数据卷,适合开发测试环境
  3. 创建 Service Service 用于暴露 Redis 服务,使集群内或外部的客户端可以访问 Redis。

    yaml
    apiVersion: v1  # API 版本
    kind: Service  # 资源类型
    metadata:
      name: redis  # Service 名称
      namespace: default  # 命名空间
    spec:
      selector:  # 标签选择器,用于匹配 Pod
        app: redis
      ports:
      - port: 6379  # Service 端口
        targetPort: 6379  # 目标 Pod 端口
        nodePort: 30379  # NodePort 类型,暴露到节点的端口
      type: NodePort  # Service 类型,NodePort 表示暴露到节点端口

主从复制部署

主从复制是Redis实现高可用性的基础,通过将主节点的数据复制到从节点,可以实现读写分离,提高系统的吞吐量和可用性。在Kubernetes中,可以使用Deployment和StatefulSet来部署主从复制架构。

  1. 创建主节点 ConfigMap 首先创建主节点的配置文件,包括绑定地址、端口、密码和持久化等配置:

    yaml
    apiVersion: v1  # API 版本
    kind: ConfigMap  # 资源类型
    metadata:
      name: redis-master-config  # ConfigMap 名称
      namespace: default  # 命名空间
    data:
      redis.conf: |  # 配置文件内容
        bind 0.0.0.0        # 允许所有 IP 访问
        port 6379           # 监听端口
        requirepass your_strong_password  # 设置访问密码
        masterauth your_strong_password  # 主从复制认证密码
        appendonly yes      # 开启 AOF 持久化
        appendfsync everysec  # 每秒将缓冲区内容写入磁盘
        dir /data           # 数据存储目录
  2. 创建从节点 ConfigMap 然后创建从节点的配置文件,从节点的配置与主节点基本相同,但会通过命令行参数指定主节点地址:

    yaml
    apiVersion: v1  # API 版本
    kind: ConfigMap  # 资源类型
    metadata:
      name: redis-slave-config  # ConfigMap 名称
      namespace: default  # 命名空间
    data:
      redis.conf: |  # 配置文件内容
        bind 0.0.0.0        # 允许所有 IP 访问
        port 6379           # 监听端口
        requirepass your_strong_password  # 设置访问密码
        masterauth your_strong_password  # 主从复制认证密码
        appendonly yes      # 开启 AOF 持久化
        appendfsync everysec  # 每秒将缓冲区内容写入磁盘
        dir /data           # 数据存储目录
  3. 创建主节点 Deployment 使用Deployment部署主节点,确保主节点稳定运行:

    yaml
    apiVersion: apps/v1  # API 版本
    kind: Deployment  # 资源类型
    metadata:
      name: redis-master  # Deployment 名称
      namespace: default  # 命名空间
    spec:
      replicas: 1  # 主节点只需要1个副本
      selector:
        matchLabels:  # 标签选择器,用于匹配 Pod
          app: redis-master
      template:
        metadata:
          labels:
            app: redis-master  # Pod 标签
        spec:
          containers:
          - name: redis  # 容器名称
            image: redis:7.2-alpine  # 容器镜像
            ports:
            - containerPort: 6379  # 容器内端口
            volumeMounts:  # 卷挂载
            - name: redis-master-config  # 引用主节点配置
              mountPath: /etc/redis/redis.conf  # 挂载路径
              subPath: redis.conf  # 子路径
            - name: redis-master-data  # 引用主节点数据卷
              mountPath: /data  # 数据挂载路径
            args:  # 启动参数
            - redis-server
            - /etc/redis/redis.conf
            resources:  # 资源限制
              requests:  # 请求资源
                memory: "256Mi"
                cpu: "100m"
              limits:  # 限制资源
                memory: "512Mi"
                cpu: "500m"
          volumes:  # 卷定义
          - name: redis-master-config  # 配置卷
            configMap:
              name: redis-master-config  # 引用上面创建的主节点 ConfigMap
          - name: redis-master-data  # 数据卷
            persistentVolumeClaim:  # 使用持久卷声明
              claimName: redis-master-pvc  # 持久卷声明名称
  4. 创建从节点 StatefulSet 使用StatefulSet部署从节点,StatefulSet适合需要稳定网络标识和持久存储的应用:

    yaml
    apiVersion: apps/v1  # API 版本
    kind: StatefulSet  # 资源类型
    metadata:
      name: redis-slave  # StatefulSet 名称
      namespace: default  # 命名空间
    spec:
      serviceName: redis-slave  # 关联的 Headless Service 名称
      replicas: 2  # 从节点数量
      selector:
        matchLabels:  # 标签选择器
          app: redis-slave
      template:
        metadata:
          labels:
            app: redis-slave  # Pod 标签
        spec:
          containers:
          - name: redis  # 容器名称
            image: redis:7.2-alpine  # 容器镜像
            ports:
            - containerPort: 6379  # 容器内端口
            volumeMounts:  # 卷挂载
            - name: redis-slave-config  # 引用从节点配置
              mountPath: /etc/redis/redis.conf  # 挂载路径
              subPath: redis.conf  # 子路径
            - name: redis-slave-data  # 引用从节点数据卷
              mountPath: /data  # 数据挂载路径
            args:  # 启动参数,指定主节点地址
            - redis-server
            - /etc/redis/redis.conf
            - --replicaof  # 指定为从节点
            - redis-master.default.svc.cluster.local  # 主节点的 DNS 名称
            - "6379"  # 主节点端口
            resources:  # 资源限制
              requests:  # 请求资源
                memory: "256Mi"
                cpu: "100m"
              limits:  # 限制资源
                memory: "512Mi"
                cpu: "500m"
          volumes:  # 卷定义
          - name: redis-slave-config  # 配置卷
            configMap:
              name: redis-slave-config  # 引用上面创建的从节点 ConfigMap
          - name: redis-slave-data  # 数据卷
            persistentVolumeClaim:  # 使用持久卷声明
              claimName: redis-slave-pvc  # 持久卷声明名称
  5. 创建 Services 为了让主从节点之间能够通信,需要创建对应的Service:

    yaml
    # 主节点 Service,用于主从节点之间的通信
    apiVersion: v1  # API 版本
    kind: Service  # 资源类型
    metadata:
      name: redis-master  # Service 名称
      namespace: default  # 命名空间
    spec:
      selector:  # 标签选择器,匹配主节点 Pod
        app: redis-master
      ports:
      - port: 6379  # Service 端口
        targetPort: 6379  # 目标 Pod 端口
    
    # 从节点 Service,用于客户端访问从节点
    apiVersion: v1  # API 版本
    kind: Service  # 资源类型
    metadata:
      name: redis-slave  # Service 名称
      namespace: default  # 命名空间
    spec:
      selector:  # 标签选择器,匹配从节点 Pod
        app: redis-slave
      ports:
      - port: 6379  # Service 端口
        targetPort: 6379  # 目标 Pod 端口

Redis Sentinel 部署

Redis Sentinel 是 Redis 的高可用性解决方案,用于监控 Redis 主从集群,并在主节点故障时自动进行故障转移。在 Kubernetes 中部署 Sentinel 可以确保 Redis 集群的高可用性。

  1. 创建 Sentinel ConfigMap 首先创建 Sentinel 的配置文件,包括监控的主节点信息、认证密码、故障转移参数等:

    yaml
    apiVersion: v1  # API 版本
    kind: ConfigMap  # 资源类型
    metadata:
      name: redis-sentinel-config  # ConfigMap 名称
      namespace: default  # 命名空间
    data:
      sentinel.conf: |  # Sentinel 配置文件内容
        port 26379  # Sentinel 监听端口
        dir /tmp  # 工作目录
        # 监控名为 mymaster 的主节点,指定主节点的 DNS 名称、端口和法定人数(需要2个Sentinel同意才能进行故障转移)
        sentinel monitor mymaster redis-master.default.svc.cluster.local 6379 2
        sentinel auth-pass mymaster your_strong_password  # 主节点的认证密码
        sentinel down-after-milliseconds mymaster 5000  # 认为主节点宕机的超时时间(毫秒)
        sentinel failover-timeout mymaster 10000  # 故障转移超时时间(毫秒)
        sentinel parallel-syncs mymaster 1  # 故障转移时,同时同步数据的从节点数量
  2. 创建 Sentinel Deployment 使用 Deployment 部署 Sentinel 集群,通常需要至少3个 Sentinel 实例来确保高可用性:

    yaml
    apiVersion: apps/v1  # API 版本
    kind: Deployment  # 资源类型
    metadata:
      name: redis-sentinel  # Deployment 名称
      namespace: default  # 命名空间
    spec:
      replicas: 3  # Sentinel 实例数量,建议至少3个
      selector:
        matchLabels:  # 标签选择器,用于匹配 Pod
          app: redis-sentinel
      template:
        metadata:
          labels:
            app: redis-sentinel  # Pod 标签
        spec:
          containers:
          - name: redis-sentinel  # 容器名称
            image: redis:7.2-alpine  # 容器镜像,使用与 Redis 相同版本的 Sentinel
            ports:
            - containerPort: 26379  # Sentinel 监听端口
            volumeMounts:  # 卷挂载
            - name: redis-sentinel-config  # 引用 Sentinel 配置
              mountPath: /etc/redis/sentinel.conf  # 挂载路径
              subPath: sentinel.conf  # 子路径
            args:  # 启动参数,指定运行 Sentinel 并使用配置文件
            - redis-sentinel
            - /etc/redis/sentinel.conf
            resources:  # 资源限制
              requests:  # 请求资源
                memory: "128Mi"
                cpu: "50m"
              limits:  # 限制资源
                memory: "256Mi"
                cpu: "200m"
          volumes:  # 卷定义
          - name: redis-sentinel-config  # 配置卷
            configMap:
              name: redis-sentinel-config  # 引用上面创建的 Sentinel ConfigMap
  3. 创建 Sentinel Service 为了让应用能够访问 Sentinel 集群,需要创建对应的 Service:

    yaml
    apiVersion: v1  # API 版本
    kind: Service  # 资源类型
    metadata:
      name: redis-sentinel  # Service 名称
      namespace: default  # 命名空间
    spec:
      selector:  # 标签选择器,匹配 Sentinel Pod
        app: redis-sentinel
      ports:
      - port: 26379  # Service 端口
        targetPort: 26379  # 目标 Pod 端口
  4. 验证 Sentinel 状态 部署完成后,需要验证 Sentinel 集群是否正常工作,包括监控主节点和从节点的状态:

    bash
    # 连接到一个 Sentinel Pod,查看监控的主节点信息
    kubectl exec -it redis-sentinel-<pod-name> -- redis-cli -p 26379 sentinel masters
    
    # 查看 Sentinel 监控的从节点信息
    kubectl exec -it redis-sentinel-<pod-name> -- redis-cli -p 26379 sentinel slaves mymaster

通过以上步骤,我们在 Kubernetes 中部署了一个完整的 Redis Sentinel 集群,它可以监控 Redis 主从集群,并在主节点故障时自动进行故障转移,确保 Redis 服务的高可用性。

Redis Cluster 部署

Redis Cluster 是 Redis 官方提供的分布式解决方案,可以自动分片、故障转移和水平扩展。在 Kubernetes 中部署 Redis Cluster 可以获得高可用性和可扩展性,适合大规模应用场景。

  1. 创建 ConfigMap 首先创建 Redis Cluster 的配置文件,启用集群模式并配置相关参数:

    yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: redis-cluster-config
      namespace: default
    data:
      redis.conf: |
        bind 0.0.0.0
        port 6379
        cluster-enabled yes
        cluster-config-file nodes.conf
        cluster-node-timeout 5000
        cluster-require-full-coverage no
        appendonly yes
        appendfsync everysec
        requirepass your_strong_password
        masterauth your_strong_password
        dir /data
  2. 创建 StatefulSet 使用 StatefulSet 部署 Redis Cluster 节点,StatefulSet 提供稳定的网络标识和持久存储,非常适合 Redis Cluster:

    yaml
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: redis-cluster
      namespace: default
    spec:
      serviceName: redis-cluster
      replicas: 6
      selector:
        matchLabels:
          app: redis-cluster
      template:
        metadata:
          labels:
            app: redis-cluster
        spec:
          containers:
          - name: redis
            image: redis:7.2-alpine
            ports:
            - containerPort: 6379
              name: client
            - containerPort: 16379
              name: gossip
            command:
            - redis-server
            - /etc/redis/redis.conf
            volumeMounts:
            - name: redis-cluster-config
              mountPath: /etc/redis/redis.conf
              subPath: redis.conf
            - name: redis-cluster-data
              mountPath: /data
            resources:
              requests:
                memory: "256Mi"
                cpu: "100m"
              limits:
                memory: "512Mi"
                cpu: "500m"
          volumes:
          - name: redis-cluster-config
            configMap:
              name: redis-cluster-config
          - name: redis-cluster-data
            persistentVolumeClaim:
              claimName: redis-cluster-pvc
  3. 创建 Headless Service 创建 Headless Service 用于 Redis Cluster 节点之间的通信,Headless Service 提供稳定的 DNS 解析:

    yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: redis-cluster
      namespace: default
    spec:
      clusterIP: None
      selector:
        app: redis-cluster
      ports:
      - name: client
        port: 6379
      - name: gossip
        port: 16379
  4. 初始化集群 部署完成后,需要初始化 Redis Cluster,分配槽位并建立主从关系:

    bash
    # 获取所有 Redis 节点的 IP
    kubectl get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 '{\n}'' > redis-nodes.txt
    
    # 连接到一个 Redis 节点
    kubectl exec -it redis-cluster-0 -- redis-cli -a your_strong_password --cluster create --cluster-replicas 1 $(cat redis-nodes.txt)
    
    # 验证集群状态
    kubectl exec -it redis-cluster-0 -- redis-cli -a your_strong_password cluster info
    kubectl exec -it redis-cluster-0 -- redis-cli -a your_strong_password cluster nodes

通过以上步骤,我们在 Kubernetes 中部署了一个完整的 Redis Cluster 集群,包含3个主节点和3个从节点,实现了数据的自动分片和高可用性。Redis Cluster 可以根据业务需求水平扩展,提高系统的吞吐量和容量,适合处理大规模数据和高并发请求。

持久化配置

持久化配置是确保Redis数据在容器重启或故障时不丢失的重要保障。在Kubernetes中,可以使用Persistent Volume (PV)和Persistent Volume Claim (PVC)来实现持久化存储。

Persistent Volume (PV) 和 Persistent Volume Claim (PVC)

PV是集群级别的存储资源,由管理员配置或动态创建;PVC是Pod级别的存储请求,由用户创建,用于申请PV资源。以下是在Kubernetes中配置Redis持久化存储的方法:

  1. 创建 PV Persistent Volume (PV) 是集群中的存储资源,以下示例创建一个基于hostPath的PV,适用于开发和测试环境:

    yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: redis-pv
      namespace: default
    spec:
      capacity:
        storage: 1Gi
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy:
        Retain
      hostPath:
        path: /data/redis
        type: DirectoryOrCreate
  2. 创建 PVC Persistent Volume Claim (PVC) 是对PV资源的请求,以下示例创建两个PVC,分别用于Redis主节点和从节点:

    yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: redis-master-pvc
      namespace: default
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    
    ---
    
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: redis-slave-pvc
      namespace: default
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
  3. 使用 StorageClass StorageClass 用于动态创建PV,适合生产环境,可以根据需求自动分配存储资源:

    yaml
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: redis-storage-class
    provisioner: kubernetes.io/gce-pd
    parameters:
      type: pd-standard
    reclaimPolicy: Retain
    allowVolumeExpansion: true
    
    ---
    
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: redis-pvc
      namespace: default
    spec:
      storageClassName: redis-storage-class
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

配置管理

配置管理是Kubernetes中管理应用配置的重要部分,通过配置管理可以实现配置的集中管理、版本控制和动态更新。Redis的配置管理可以使用ConfigMap和Secret来实现。

使用 ConfigMap 管理配置

ConfigMap用于存储非敏感的配置信息,如Redis的配置文件、环境变量等。以下是使用ConfigMap管理Redis配置的方法:

  1. 创建 ConfigMap

    yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: redis-config
      namespace: default
    data:
      redis.conf: |
        bind 0.0.0.0
        port 6379
        daemonize no
        requirepass your_strong_password
        appendonly yes
        appendfsync everysec
        dir /data
        maxmemory 512mb
        maxmemory-policy allkeys-lru
  2. 在 Deployment 中使用 ConfigMap

    yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis
      namespace: default
    spec:
      # ...
      template:
        spec:
          containers:
          - name: redis
            image: redis:7.2-alpine
            volumeMounts:
            - name: redis-config
              mountPath: /etc/redis/redis.conf
              subPath: redis.conf
            args:
            - redis-server
            - /etc/redis/redis.conf
          volumes:
          - name: redis-config
            configMap:
              name: redis-config
      # ...
  3. 更新 ConfigMap

    bash
    # 编辑 ConfigMap
    kubectl edit configmap redis-config -n default
    
    # 或者使用 kubectl apply
    kubectl apply -f redis-config.yaml
    
    # 重启 Pod 以应用新配置
    kubectl rollout restart deployment redis -n default

使用 Secret 管理敏感信息

Secret用于存储敏感的配置信息,如Redis的密码、证书等。使用Secret可以避免将敏感信息直接存储在配置文件中,提高安全性。

  1. 创建 Secret 可以通过文件或直接命令创建Secret,以下是两种常见的创建方式:

    bash
    # 从文件创建 Secret
    echo -n "your_strong_password" > password.txt
    kubectl create secret generic redis-secret --from-file=password.txt
    
    # 或者直接创建,更方便快捷
    kubectl create secret generic redis-secret --from-literal=redis-password=your_strong_password
  2. 在 Deployment 中使用 Secret 创建Secret后,可以在Deployment中通过环境变量或卷挂载的方式使用Secret中的敏感信息:

    yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis
      namespace: default
    spec:
      # ...
      template:
        spec:
          containers:
          - name: redis
            image: redis:7.2-alpine
            env:
            - name: REDIS_PASSWORD  # 定义环境变量名
              valueFrom:  # 从Secret获取值
                secretKeyRef:
                  name: redis-secret  # Secret名称
                  key: redis-password  # Secret中的键名
            command:  # 使用环境变量作为启动参数
            - redis-server
            - --requirepass
            - $(REDIS_PASSWORD)
      # ...

监控和日志

监控和日志是Redis运维的重要组成部分,通过监控可以实时了解Redis的运行状态和性能指标,通过日志可以排查和分析问题。

Docker 监控和日志

在Docker环境中,可以使用Docker自带的命令来监控Redis容器和查看日志:

  1. 查看 Docker 日志 Docker日志包含了Redis的所有输出信息,可以帮助排查问题:

    bash
    # 查看 Redis 容器日志
    docker logs redis
    
    # 实时查看日志,跟踪最新的日志输出
    docker logs -f redis
    
    # 查看最近 100 行日志,避免输出过多内容
    docker logs --tail 100 redis
  2. 使用 Docker Stats Docker Stats 可以实时查看容器的资源使用情况,包括CPU、内存、网络和磁盘I/O:

    bash
    # 查看 Redis 容器的资源使用情况
    docker stats redis

Kubernetes 监控

在Kubernetes环境中,可以使用多种工具来监控Redis,包括kubectl命令、Prometheus和Grafana等。

  1. 使用 kubectl 查看日志 kubectl 是Kubernetes的命令行工具,可以用来查看Pod日志:

    bash
    # 查看单个 Pod 的日志
    kubectl logs redis-<pod-name>
    
    # 实时查看 Pod 日志
    kubectl logs -f redis-<pod-name>
    
    # 查看 Deployment 下所有 Pod 的日志
    kubectl logs deployment/redis
  2. 使用 Prometheus 和 Grafana Prometheus 和 Grafana 是一套强大的监控解决方案,可以实现Redis的全面监控:

    yaml
    # Redis Exporter Deployment,用于采集Redis指标
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-exporter
      namespace: default
    spec:
      replicas: 1  # 只需要1个副本
      selector:
        matchLabels:
          app: redis-exporter
      template:
        metadata:
          labels:
            app: redis-exporter
        spec:
          containers:
          - name: redis-exporter
            image: oliver006/redis_exporter:latest  # 使用最新版本的Redis Exporter
            ports:
            - containerPort: 9121  # Exporter 监听端口
            env:
            - name: REDIS_ADDR
              value: redis://redis:6379  # Redis 服务地址
            - name: REDIS_PASSWORD
              valueFrom:  # 从Secret获取密码
                secretKeyRef:
                  name: redis-secret
                  key: redis-password
    
    # Redis Exporter Service,用于Prometheus采集指标
    apiVersion: v1
    kind: Service
    metadata:
      name: redis-exporter
      namespace: default
      annotations:
        prometheus.io/scrape: "true"  # 启用Prometheus自动发现
        prometheus.io/port: "9121"  # 告诉Prometheus采集的端口
    spec:
      selector:
        app: redis-exporter
      ports:
      - port: 9121
        targetPort: 9121
  3. Grafana 仪表盘 Grafana 用于可视化监控数据,可以通过导入现成的Redis仪表盘来快速实现监控:

    • 导入 Redis 仪表盘(ID: 763),这是一个成熟的Redis监控仪表盘
    • 配置 Prometheus 数据源,将Grafana连接到Prometheus
    • 监控 Redis 关键指标,如内存使用、连接数、命中率、命令执行速度等

最佳实践

最佳实践是在生产环境中部署和管理Redis的重要指导原则,遵循这些实践可以提高Redis的安全性、性能和可靠性。

安全配置

安全配置是保护Redis实例免受未授权访问和攻击的关键措施:

  1. 设置强密码

    • 使用至少 16 位的强密码,包含大小写字母、数字和特殊字符
    • 避免使用容易猜测的密码,如"password"、"redis"等
    • 在Kubernetes环境中使用Secret管理密码,避免直接明文存储
  2. 限制网络访问

    • 在Docker中使用自定义网络,避免Redis实例暴露在公共网络中
    • 在Kubernetes中使用Network Policies,只允许特定的Pod访问Redis
    • 示例 Network Policy,限制只有带有app=allowed-app标签的Pod可以访问Redis:
      yaml
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: redis-network-policy
        namespace: default
      spec:
        podSelector:
          matchLabels:
            app: redis
        policyTypes:
          - Ingress
        ingress:
        - from:
          - podSelector:
              matchLabels:
                app: allowed-app
          ports:
          - protocol: TCP
            port: 6379
  3. 启用 SSL/TLS

    • Redis 6.0+ 原生支持 SSL/TLS,可以加密客户端和服务器之间的通信
    • 在Kubernetes中使用TLS证书,保护数据在传输过程中的安全性
    • 示例配置,创建用于Redis的TLS Secret:
      yaml
      apiVersion: v1
      kind: Secret
      metadata:
        name: redis-tls
      type: kubernetes.io/tls
      data:
        tls.crt: <base64-encoded-cert>
        tls.key: <base64-encoded-key>

性能优化

  1. 资源限制

    • 合理设置 CPU 和内存限制
    • 根据实际负载调整资源请求
    • 示例:
      yaml
      resources:
        requests:
          memory: "256Mi"
          cpu: "100m"
        limits:
          memory: "512Mi"
          cpu: "500m"
  2. 使用 Alpine 镜像

    • Alpine 镜像体积小,启动快
    • 减少攻击面
    • 示例:redis:7.2-alpine
  3. 调整持久化策略

    • 根据业务需求选择合适的持久化方式
    • 平衡性能和数据安全性
    • 示例:
      yaml
      command:
      - redis-server
      - --appendonly
      - "yes"
      - --appendfsync
      - everysec

高可用性

  1. 部署多副本

    • 在 Kubernetes 中使用 StatefulSet 部署 Redis Cluster
    • 配置合适的副本数
    • 示例:
      yaml
      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: redis-cluster
      spec:
        serviceName: redis-cluster
        replicas: 6
        # ...
  2. 配置健康检查

    • 配置 livenessProbe 和 readinessProbe
    • 确保 Pod 健康状态准确反映 Redis 服务状态
    • 示例:
      yaml
      livenessProbe:
        exec:
          command:
          - redis-cli
          - -a
          - your_strong_password
          - ping
        initialDelaySeconds: 30
        periodSeconds: 10
      readinessProbe:
        exec:
          command:
          - redis-cli
          - -a
          - your_strong_password
          - ping
        initialDelaySeconds: 5
        periodSeconds: 10
  3. 自动扩缩容

    • 使用 Horizontal Pod Autoscaler (HPA) 根据负载自动调整副本数
    • 示例:
      yaml
      apiVersion: autoscaling/v2
      kind: HorizontalPodAutoscaler
      metadata:
        name: redis-hpa
      spec:
        scaleTargetRef:
          apiVersion: apps/v1
          kind: Deployment
          name: redis
        minReplicas: 1
        maxReplicas: 3
        metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 80
        - type: Resource
          resource:
            name: memory
            target:
              type: Utilization
              averageUtilization: 80

常见问题(FAQ)

问题 1: Redis 容器启动失败,提示 "Address already in use"

原因: 端口已被占用。

解决方案:

bash
# 检查端口占用情况
kubectl get pods -o wide
# 或者
docker ps

# 修改 Service 的 NodePort
# 或者修改容器的 hostPort

问题 2: Redis 主从复制失败

原因: 网络问题、密码错误或配置不当。

解决方案:

bash
# 检查主从节点网络连接
kubectl exec -it redis-slave-0 -- ping redis-master

# 检查密码配置
kubectl logs redis-slave-0

# 验证主从配置
kubectl exec -it redis-slave-0 -- redis-cli -a your_strong_password info replication

问题 3: Redis Cluster 节点无法加入集群

原因: 网络通信问题、gossip 端口未开放或配置错误。

解决方案:

bash
# 检查 gossip 端口
kubectl get services

# 检查集群配置
kubectl exec -it redis-cluster-0 -- redis-cli -a your_strong_password cluster nodes

# 重启集群初始化
kubectl exec -it redis-cluster-0 -- redis-cli -a your_strong_password cluster reset

问题 4: 持久化数据丢失

原因: 使用了 emptyDir 或 hostPath 在错误的节点上。

解决方案:

yaml
# 使用 Persistent Volume Claim
volumeMounts:
- name: redis-data
  mountPath: /data
volumes:
- name: redis-data
  persistentVolumeClaim:
    claimName: redis-pvc

问题 5: Redis 性能不佳

原因: 资源限制不足、配置不当或查询优化问题。

解决方案:

bash
# 检查资源使用情况
kubectl top pods

# 优化配置
kubectl edit configmap redis-config

# 分析慢查询
kubectl exec -it redis-0 -- redis-cli -a your_strong_password slowlog get