Redis 容器化部署:Docker 与 Kubernetes 中的最佳实践

各位观众老爷们,大家好!今天咱们来聊聊 Redis 的容器化部署,也就是怎么把这小家伙儿塞进 Docker 和 Kubernetes 这两个大盒子里,让它跑得更稳、更快、更省心。

第一部分:Redis 容器化部署的必要性,以及 Docker 的基础操作

为啥要把 Redis 塞进容器里?原因很简单,就像把你的宝贝手办放进展示柜一样,好处多多:

  • 环境一致性: 告别“在我电脑上跑得好好的”的玄学问题。容器确保开发、测试、生产环境 Redis 的配置完全一致。
  • 隔离性: 容器就像一个独立的小房间,Redis 在里面跑,不会被其他应用干扰,也不会干扰其他应用。
  • 可移植性: 容器可以在任何支持 Docker 的机器上运行,妈妈再也不用担心我换电脑了。
  • 弹性伸缩: 配合 Kubernetes,可以根据负载自动增加或减少 Redis 实例,像孙悟空一样能大能小。

好了,废话不多说,咱们先来了解一下 Docker 的基本操作。Docker 就是一个能创建和管理容器的神奇工具。

Docker 基础操作

  1. 镜像拉取 (Docker Pull): 想象一下从应用商店下载软件,docker pull 就是从 Docker Hub(一个公共的镜像仓库)下载 Redis 镜像。

    docker pull redis:latest  # 拉取最新版本的 Redis 镜像
    docker pull redis:6.2     # 拉取 6.2 版本的 Redis 镜像
  2. 容器运行 (Docker Run): 就像启动下载好的软件,docker run 就是基于 Redis 镜像创建一个 Redis 容器并运行它。

    docker run --name my-redis -d -p 6379:6379 redis:latest

    解释一下上面的命令:

    • --name my-redis: 给容器起个名字,叫 my-redis,方便管理。
    • -d: 让容器在后台运行 (detached mode)。
    • -p 6379:6379: 将宿主机的 6379 端口映射到容器的 6379 端口,这样你就可以通过宿主机的 6379 端口访问 Redis 服务了。
    • redis:latest: 指定使用的镜像。
  3. 容器管理 (Docker Stop/Start/Restart/Rm): 这些命令就像控制软件的开关一样。

    docker stop my-redis   # 停止容器
    docker start my-redis  # 启动容器
    docker restart my-redis # 重启容器
    docker rm my-redis      # 删除容器
  4. 容器状态查看 (Docker Ps): 看看你的 Redis 容器是不是活蹦乱跳。

    docker ps  # 查看正在运行的容器
    docker ps -a # 查看所有容器,包括已停止的
  5. 进入容器 (Docker Exec): 就像进入一个房间,你可以在容器内部执行命令。

    docker exec -it my-redis redis-cli  # 进入 Redis 容器,并启动 redis-cli 客户端

    这个命令可以让你直接操作 Redis 数据库。

持久化存储:别让数据丢了

Redis 默认情况下会将数据存储在内存中,容器重启后数据就没了。所以,我们需要使用 Docker 的 Volume 来持久化存储 Redis 的数据。

docker run --name my-redis -d -p 6379:6379 -v redis_data:/data redis:latest
  • -v redis_data:/data: 将宿主机上的 redis_data 卷 (Volume) 挂载到容器的 /data 目录,Redis 会将数据存储在这个目录中。即使容器重启,数据也不会丢失。

你可以使用 docker volume ls 命令查看创建的卷。

第二部分:Docker Compose:化繁为简

如果你的应用依赖多个服务,比如 Redis、MySQL、Web 应用等等,一个个运行 Docker 命令就太麻烦了。这时,Docker Compose 就派上用场了。它可以让你用一个 YAML 文件定义多个服务,然后一键启动所有服务。

Docker Compose 文件 (docker-compose.yml)

version: "3.8"
services:
  redis:
    image: redis:latest
    container_name: my-redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: always

volumes:
  redis_data:

解释一下:

  • version: "3.8": 指定 Docker Compose 文件的版本。
  • services: 定义服务列表。
  • redis: 定义一个名为 redis 的服务。
    • image: 使用的镜像。
    • container_name: 容器名
    • ports: 端口映射。
    • volumes: 数据卷挂载。
    • restart: always: 容器退出后自动重启。
  • volumes: 定义数据卷。

使用 Docker Compose

  1. 启动所有服务:

    docker-compose up -d  # 在后台启动所有服务
  2. 停止所有服务:

    docker-compose down  # 停止并删除所有服务
  3. 查看服务状态:

    docker-compose ps  # 查看所有服务状态

第三部分:Kubernetes:集群管理大师

Docker 很好,但如果你需要管理大量的 Redis 实例,或者需要自动伸缩、故障转移等高级功能,Kubernetes (K8s) 就是你的不二之选。Kubernetes 是一个容器编排系统,它可以自动化部署、扩展和管理容器化应用程序。

Kubernetes 核心概念

  • Pod: Kubernetes 中最小的部署单元,可以包含一个或多个容器。你可以把 Pod 想象成一个豪华公寓,里面可以住多个租客 (容器)。
  • Deployment: 用于管理 Pod 的副本集,确保指定数量的 Pod 始终在运行。如果某个 Pod 挂了,Deployment 会自动创建一个新的 Pod。
  • Service: 为 Pod 提供一个稳定的网络接口,即使 Pod 的 IP 地址发生变化,Service 的 IP 地址也不会变。你可以把 Service 想象成一个前台接待员,负责将请求转发给后端的 Pod。
  • ConfigMap: 用于存储配置信息,比如 Redis 的配置文件。
  • Secret: 用于存储敏感信息,比如 Redis 的密码。

Kubernetes 部署 Redis

  1. 创建 ConfigMap: 存储 Redis 的配置文件。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: redis-config
    data:
      redis.conf: |
        # redis.conf 内容
        # 可以根据需要修改配置
        maxmemory 256mb
        maxmemory-policy allkeys-lru

    将上面的内容保存为 redis-config.yaml,然后执行以下命令创建 ConfigMap:

    kubectl apply -f redis-config.yaml
  2. 创建 Deployment: 部署 Redis 实例。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-deployment
    spec:
      replicas: 1  # 运行一个 Redis 实例
      selector:
        matchLabels:
          app: redis
      template:
        metadata:
          labels:
            app: redis
        spec:
          containers:
            - name: redis
              image: redis:latest
              ports:
                - containerPort: 6379
              volumeMounts:
                - name: redis-data
                  mountPath: /data
                - name: redis-config
                  mountPath: /usr/local/etc/redis
                  readOnly: true
              command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
          volumes:
            - name: redis-data
              emptyDir: {}  # 使用 emptyDir 作为临时存储
            - name: redis-config
              configMap:
                name: redis-config

    解释一下:

    • replicas: 1: 运行一个 Redis 实例。
    • selector: 用于选择 Pod。
    • template: 定义 Pod 的模板。
      • containers: 定义容器列表。
        • image: 使用的镜像。
        • ports: 端口映射。
        • volumeMounts: 数据卷挂载。
          • redis-data: 将 redis-data 这个volume挂载到容器的/data目录,redis的数据存储在这里。
          • redis-config: 将 redis-config 这个configmap 挂载到容器的/usr/local/etc/redis目录,redis的配置文件放在这里。
        • command: 启动 Redis 服务的命令,指定使用 ConfigMap 中的配置文件。
      • volumes: 定义数据卷。
        • emptyDir: {}: 使用 emptyDir 作为临时存储,容器重启后数据会丢失。 在生产环境中,你应该使用持久卷 (Persistent Volume) 来持久化存储 Redis 的数据。
        • configMap: 指定configMap的名字为 redis-config

    将上面的内容保存为 redis-deployment.yaml,然后执行以下命令创建 Deployment:

    kubectl apply -f redis-deployment.yaml
  3. 创建 Service: 为 Redis 提供一个稳定的网络接口。

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-service
    spec:
      selector:
        app: redis
      ports:
        - protocol: TCP
          port: 6379
          targetPort: 6379
      type: ClusterIP  # 使用 ClusterIP 类型,只能在集群内部访问

    解释一下:

    • selector: 用于选择 Pod。
    • ports: 端口映射。
    • type: ClusterIP: 使用 ClusterIP 类型,只能在集群内部访问。如果你需要从集群外部访问 Redis,可以使用 NodePortLoadBalancer 类型。

    将上面的内容保存为 redis-service.yaml,然后执行以下命令创建 Service:

    kubectl apply -f redis-service.yaml
  4. 查看部署状态:

    kubectl get pods  # 查看 Pod 状态
    kubectl get deployments  # 查看 Deployment 状态
    kubectl get services  # 查看 Service 状态

持久卷 (Persistent Volume)

使用 emptyDir 作为临时存储,容器重启后数据会丢失。在生产环境中,你应该使用持久卷 (Persistent Volume) 来持久化存储 Redis 的数据。

持久卷是 Kubernetes 中用于持久化存储的资源。你需要先创建一个持久卷,然后创建一个持久卷声明 (Persistent Volume Claim),将持久卷声明绑定到持久卷上。最后,在 Deployment 中使用持久卷声明。

  1. 创建持久卷 (Persistent Volume):

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: redis-pv
    spec:
      capacity:
        storage: 1Gi  # 存储容量为 1GB
      accessModes:
        - ReadWriteOnce  # 只允许单个节点读写
      persistentVolumeReclaimPolicy: Retain  # 保留数据,即使 PVC 被删除
      storageClassName: manual  # 使用 manual StorageClass
      hostPath:
        path: /data/redis  # 宿主机上的目录

    将上面的内容保存为 redis-pv.yaml,然后执行以下命令创建持久卷:

    kubectl apply -f redis-pv.yaml

    注意: 在生产环境中,你应该使用云厂商提供的存储服务,而不是 hostPath

  2. 创建持久卷声明 (Persistent Volume Claim):

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: redis-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: manual

    将上面的内容保存为 redis-pvc.yaml,然后执行以下命令创建持久卷声明:

    kubectl apply -f redis-pvc.yaml
  3. 修改 Deployment: 使用持久卷声明。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: redis
      template:
        metadata:
          labels:
            app: redis
        spec:
          containers:
            - name: redis
              image: redis:latest
              ports:
                - containerPort: 6379
              volumeMounts:
                - name: redis-data
                  mountPath: /data
                - name: redis-config
                  mountPath: /usr/local/etc/redis
                  readOnly: true
              command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
          volumes:
            - name: redis-data
              persistentVolumeClaim:
                claimName: redis-pvc  # 使用持久卷声明
            - name: redis-config
              configMap:
                name: redis-config

    修改 redis-deployment.yaml 文件,将 emptyDir 替换为 persistentVolumeClaim,然后执行以下命令更新 Deployment:

    kubectl apply -f redis-deployment.yaml

第四部分:Redis Sentinel:高可用保障

单节点的 Redis 容易挂掉,所以我们需要使用 Redis Sentinel 来实现高可用。Redis Sentinel 是 Redis 的一个监控和故障转移系统,它可以自动监控 Redis 实例的状态,并在主节点挂掉后自动将一个从节点提升为新的主节点。

部署 Redis Sentinel

  1. 创建 Redis 主节点和从节点的 Deployment 和 Service: 和前面类似,只是需要创建多个 Deployment 和 Service。

  2. 创建 Redis Sentinel 的 Deployment 和 Service:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-sentinel-deployment
    spec:
      replicas: 3  # 运行 3 个 Sentinel 实例
      selector:
        matchLabels:
          app: redis-sentinel
      template:
        metadata:
          labels:
            app: redis-sentinel
        spec:
          containers:
            - name: redis-sentinel
              image: redis:latest
              ports:
                - containerPort: 26379
              command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]
              volumeMounts:
                - name: sentinel-config
                  mountPath: /usr/local/etc/redis
                  readOnly: true
          volumes:
            - name: sentinel-config
              configMap:
                name: sentinel-config
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: redis-sentinel-service
    spec:
      selector:
        app: redis-sentinel
      ports:
        - protocol: TCP
          port: 26379
          targetPort: 26379
      type: ClusterIP

    解释一下:

    • replicas: 3: 运行 3 个 Sentinel 实例,形成一个 Sentinel 集群。
    • command: 启动 Redis Sentinel 服务的命令,指定使用 ConfigMap 中的配置文件。
  3. 创建 Sentinel 的 ConfigMap:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: sentinel-config
    data:
      sentinel.conf: |
        sentinel monitor mymaster redis-master-service 6379 2
        sentinel down-after-milliseconds mymaster 5000
        sentinel failover-timeout mymaster 10000
        sentinel parallel-syncs mymaster 1

    解释一下:

    • sentinel monitor mymaster redis-master-service 6379 2: 监控名为 mymaster 的 Redis 主节点,主节点的 Service 名称为 redis-master-service,端口为 6379,quorum 为 2。quorum 指的是 Sentinel 集群中至少需要有多少个 Sentinel 认为主节点挂了,才会进行故障转移。

第五部分:最佳实践与总结

  • 镜像选择: 选择官方的 Redis 镜像,或者基于官方镜像构建自己的镜像。
  • 配置管理: 使用 ConfigMap 和 Secret 来管理配置信息和敏感信息。
  • 持久化存储: 使用持久卷来持久化存储 Redis 的数据。
  • 高可用: 使用 Redis Sentinel 来实现高可用。
  • 监控: 监控 Redis 的性能指标,比如 CPU 使用率、内存使用率、连接数等等。可以使用 Prometheus 和 Grafana 来进行监控。
  • 安全: 设置 Redis 的密码,限制访问权限,防止未经授权的访问。

表格总结

技术点 描述
Docker 用于创建和管理容器,提供环境一致性和隔离性。
Docker Compose 用于定义和管理多容器应用,简化部署流程。
Kubernetes 用于自动化部署、扩展和管理容器化应用程序,提供弹性伸缩和高可用。
Redis Sentinel Redis 的监控和故障转移系统,用于实现高可用。
ConfigMap 用于存储配置信息。
Secret 用于存储敏感信息。
PersistentVolume Kubernetes 中用于持久化存储的资源。

总结

Redis 容器化部署是一个复杂的过程,需要考虑很多因素。但只要掌握了 Docker 和 Kubernetes 的基本概念,并遵循最佳实践,就可以轻松地将 Redis 部署到容器中,并获得更好的性能、可靠性和可维护性。

好了,今天的讲座就到这里,希望对大家有所帮助!谢谢大家!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注