使用 Kubernetes 部署 Redis:StatefulSet, Operator 与 Helm Chart

好嘞!各位观众老爷们,欢迎来到今天的“云原生厨房”!我是你们的云原生大厨,今天咱们要烹饪一道美味的“Redis 三吃”,让你的数据在 Kubernetes 的怀抱里安全、高效地飞起来!🚀

这“三吃”呢,分别是:

  1. StatefulSet 版 Redis: 朴实无华,返璞归真,自己动手,丰衣足食!
  2. Operator 版 Redis: 智能管家,一键部署,自动运维,躺平也能赢!
  3. Helm Chart 版 Redis: 灵活定制,随心所欲,组件丰富,总有一款适合你!

准备好了吗?咱们这就开火!🔥

第一道菜:StatefulSet 版 Redis – 自己动手,丰衣足食

StatefulSet,顾名思义,是 Kubernetes 中专门用来管理有状态应用的控制器。Redis 作为一款典型的有状态应用,当然可以交给它来掌管。

优点:

  • 掌控力 max: 所有配置都由你掌控,想怎么折腾就怎么折腾,适合喜欢DIY的极客。
  • 学习成本低: 熟悉 Kubernetes 基础概念即可上手,无需额外学习 Operator 或 Helm 的复杂语法。
  • 资源占用少: 没有额外的 Operator 控制器,资源消耗更小。

缺点:

  • 运维复杂: 集群搭建、升级、故障恢复都需要手动操作,容易出错。
  • 扩展性差: 集群扩展需要手动修改配置,比较繁琐。
  • 功能简单: 缺乏自动备份、监控等高级功能。

实战演练:

咱们来一步一步搭建一个简单的 Redis 集群(主从模式)。

1. 创建 Namespace:

为了方便管理,我们先创建一个专门用于 Redis 的 Namespace。

apiVersion: v1
kind: Namespace
metadata:
  name: redis-statefulset

2. 创建 ConfigMap:

ConfigMap 用于存储 Redis 的配置文件。

apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-config
  namespace: redis-statefulset
data:
  redis.conf: |
    protected-mode no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize no
    supervised no
    loglevel notice
    logfile ""
    databases 16
    always-show-logo yes
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb
    dir ./
    masterauth your_master_password
    requirepass your_redis_password
    maxclients 10000
    maxmemory <YOUR_MAX_MEMORY> # 例如:2gb
    maxmemory-policy allkeys-lru
    maxmemory-samples 5
    appendonly no
    appendfsync everysec
    lua-time-limit 5000
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    latency-monitor-threshold 0
    notify-keyspace-events ""
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    stream-node-max-bytes 4096
    stream-node-max-entries 100
    activerehashing yes
    client-output-buffer-limit normal 0 0 0 slave 256mb 64mb 60 master 512mb 128mb 60
    hz 10
    aof-rewrite-incremental-fsync yes

3. 创建 StatefulSet:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-master
  namespace: redis-statefulset
spec:
  selector:
    matchLabels:
      app: redis
      role: master
  serviceName: redis-master
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
    spec:
      containers:
      - name: redis
        image: redis:latest
        ports:
        - containerPort: 6379
          name: redis
        volumeMounts:
        - name: redis-data
          mountPath: /data
        - name: redis-config-volume
          mountPath: /usr/local/etc/redis
          readOnly: true
        command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
        env:
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: redis-secret
              key: redis-password
  volumeClaimTemplates:
  - metadata:
      name: redis-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi # 根据实际情况调整
  initContainers:
  - name: init-redis
    image: busybox:latest
    command: ['sh', '-c', 'echo your_redis_password > /data/redis.auth']
    volumeMounts:
    - name: redis-data
      mountPath: /data

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-slave
  namespace: redis-statefulset
spec:
  selector:
    matchLabels:
      app: redis
      role: slave
  serviceName: redis-slave
  replicas: 2
  template:
    metadata:
      labels:
        app: redis
        role: slave
    spec:
      containers:
      - name: redis
        image: redis:latest
        ports:
        - containerPort: 6379
          name: redis
        volumeMounts:
        - name: redis-data
          mountPath: /data
        - name: redis-config-volume
          mountPath: /usr/local/etc/redis
          readOnly: true
        command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
        env:
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: redis-secret
              key: redis-password
        - name: REDIS_MASTER_HOST
          value: redis-master-0.redis-master.redis-statefulset.svc.cluster.local  # 根据实际情况调整
        - name: REDIS_MASTER_PASSWORD
          valueFrom:
            secretKeyRef:
              name: redis-secret
              key: redis-password
        - name: REDIS_SLAVE
          value: "true"
  volumeClaimTemplates:
  - metadata:
      name: redis-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi # 根据实际情况调整
  initContainers:
  - name: init-redis
    image: busybox:latest
    command: ['sh', '-c', 'echo your_redis_password > /data/redis.auth']
    volumeMounts:
    - name: redis-data
      mountPath: /data
---
apiVersion: v1
kind: Secret
metadata:
  name: redis-secret
  namespace: redis-statefulset
type: Opaque
data:
  redis-password: $(echo -n "your_redis_password" | base64)

---

apiVersion: v1
kind: Service
metadata:
  name: redis-master
  namespace: redis-statefulset
spec:
  selector:
    app: redis
    role: master
  ports:
    - protocol: TCP
      port: 6379
      targetPort: 6379

---

apiVersion: v1
kind: Service
metadata:
  name: redis-slave
  namespace: redis-statefulset
spec:
  selector:
    app: redis
    role: slave
  ports:
    - protocol: TCP
      port: 6379
      targetPort: 6379

---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: redis-statefulset
spec:
  selector:
    app: redis
  ports:
    - protocol: TCP
      port: 6379
      targetPort: 6379

重点解释:

  • serviceName: 指定 StatefulSet 对应的 Service 名称,用于 DNS 解析。
  • replicas: 指定副本数量,这里我们部署一个 Master 和两个 Slave。
  • template: Pod 的模板,定义了容器的配置。
  • volumeMounts: 将 ConfigMap 中的配置文件挂载到容器内部。
  • volumeClaimTemplates: 定义 PersistentVolumeClaim 的模板,用于动态创建持久化存储。
  • REDIS_PASSWORD: 使用 Secret存储Redis密码,保证安全。
  • Master的StatefulSet的initContainer用于初始化密码文件
  • Slave 的StatefulSet的initContainer用于初始化密码文件,同时配置REDIS_MASTER_HOST, REDIS_MASTER_PASSWORD, REDIS_SLAVE 等环境变量, 用于自动配置Slave节点。

4. 应用配置:

kubectl apply -f redis-statefulset.yaml -n redis-statefulset

5. 验证:

等待 Pod 启动完成,可以使用 kubectl get pods -n redis-statefulset 查看状态。

然后,进入 Redis Master Pod,使用 redis-cli -h redis-master-0.redis-master.redis-statefulset.svc.cluster.local -a your_redis_password info replication 命令查看主从复制状态。

总结:

StatefulSet 版 Redis 就像自己组装电脑,虽然过程繁琐,但可以充分了解每个组件的细节,适合对 Kubernetes 有一定经验的同学。💪

第二道菜:Operator 版 Redis – 智能管家,躺平也能赢

Operator 是一种 Kubernetes 的扩展机制,它通过自定义资源(CRD)和控制器(Controller)来自动化管理复杂的应用。Redis Operator 就像一个智能管家,可以帮你自动部署、升级、备份、恢复 Redis 集群,让你彻底解放双手!

优点:

  • 自动化运维: 一键部署、自动升级、故障自愈,告别手动操作的烦恼。
  • 扩展性强: 轻松扩展集群规模,满足业务增长的需求。
  • 高级功能: 自动备份、监控、告警,保障数据安全和可用性。

缺点:

  • 学习成本高: 需要学习 Operator 的相关概念和使用方法。
  • 资源占用高: Operator 本身需要占用一定的计算资源。
  • 定制性差: 某些高级配置可能需要修改 Operator 源码。

实战演练:

这里我们以 Redis Operator 为例,演示如何快速部署 Redis 集群。

1. 安装 Redis Operator:

不同的 Redis Operator 安装方式可能略有不同,请参考官方文档进行安装。 通常使用 Helm Chart 安装, 这里以 Bitnami 的 Redis Operator 为例.

helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-redis bitnami/redis-operator --namespace redis-operator --create-namespace

2. 创建 Redis 集群:

创建一个 YAML 文件,定义 Redis 集群的配置。

apiVersion: redis.redis.opstreelabs.in/v1beta1
kind: RedisCluster
metadata:
  name: my-redis-cluster
  namespace: redis-operator
spec:
  clusterSize: 3
  image: bitnami/redis:latest
  redisConfig:
    maxmemory: 2048m
  securityContext:
    runAsUser: 1001
    fsGroup: 1001
  storage:
    accessModes:
      - ReadWriteOnce
    class: standard
    size: 1Gi

重点解释:

  • clusterSize: 指定集群节点数量。
  • image: 指定 Redis 镜像版本。
  • redisConfig: 指定 Redis 的配置参数,例如 maxmemory
  • storage: 指定持久化存储的配置。

3. 应用配置:

kubectl apply -f redis-cluster.yaml -n redis-operator

4. 验证:

等待 Redis 集群部署完成,可以使用 kubectl get pods -n redis-operator 查看状态。

Operator 会自动创建 Redis 集群,并配置主从复制、持久化存储等。

总结:

Operator 版 Redis 就像请了一个智能管家,帮你打理一切,让你只需要关注业务逻辑,无需关心底层运维细节,适合追求高效、便捷的同学。😎

第三道菜:Helm Chart 版 Redis – 灵活定制,总有一款适合你

Helm Chart 是一种 Kubernetes 的包管理工具,它可以将复杂的应用配置打包成一个 Chart,方便部署和管理。Helm Chart 版 Redis 就像一个乐高积木,你可以根据自己的需求选择不同的组件,定制出最适合自己的 Redis 集群。

优点:

  • 灵活定制: 可以通过修改 Chart 中的参数,定制 Redis 集群的各种配置。
  • 易于管理: 使用 Helm 可以方便地升级、回滚、删除 Redis 集群。
  • 组件丰富: Helm Chart 通常包含多个组件,例如 Redis 主节点、从节点、哨兵节点等,可以根据需求选择。

缺点:

  • 学习成本较高: 需要学习 Helm 的相关概念和使用方法。
  • 配置复杂: Helm Chart 的配置参数比较多,需要仔细阅读文档。
  • 依赖 Chart 仓库: 需要依赖外部的 Chart 仓库,例如 Artifact Hub。

实战演练:

这里我们以 Bitnami 的 Redis Helm Chart 为例,演示如何部署 Redis 集群。

1. 添加 Helm Chart 仓库:

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

2. 安装 Redis Helm Chart:

helm install my-redis bitnami/redis --namespace redis-helm --create-namespace 
  --set cluster.enabled=true 
  --set cluster.slaveCount=2 
  --set master.persistence.enabled=true 
  --set slave.persistence.enabled=true 
  --set auth.enabled=true 
  --set auth.password=your_redis_password

重点解释:

  • cluster.enabled=true: 启用 Redis 集群模式。
  • cluster.slaveCount=2: 指定从节点数量。
  • master.persistence.enabled=true: 启用主节点的持久化存储。
  • slave.persistence.enabled=true: 启用从节点的持久化存储。
  • auth.enabled=true: 启用密码认证。
  • auth.password=your_redis_password: 设置 Redis 密码。

3. 验证:

等待 Redis 集群部署完成,可以使用 kubectl get pods -n redis-helm 查看状态。

Helm 会自动创建 Redis 集群,并配置主从复制、持久化存储、密码认证等。

总结:

Helm Chart 版 Redis 就像一个乐高积木,你可以根据自己的需求选择不同的组件,定制出最适合自己的 Redis 集群,适合对 Kubernetes 和 Helm 有一定经验,并且需要灵活定制 Redis 集群的同学。😎

三种方式的比较

为了更清晰地了解这三种方式的优缺点,我们来做个对比:

特性 StatefulSet Operator Helm Chart
自动化程度
学习成本
资源占用
灵活性
运维复杂度
适用场景 DIY 爱好者 追求自动化 需要定制化

美味秘诀:如何选择?

那么,到底该选择哪种方式呢?这取决于你的具体需求和技术水平。

  • 如果你是 Kubernetes 初学者,或者喜欢自己动手,追求对 Redis 集群的完全掌控,那么 StatefulSet 是个不错的选择。 就像自己炒菜,虽然辛苦,但可以掌握火候和调料。
  • 如果你追求自动化运维,希望一键部署、自动升级、故障自愈,那么 Operator 是最佳选择。 就像请了一个大厨,只需要告诉他你想吃什么,剩下的都交给他。
  • 如果你需要灵活定制 Redis 集群,例如选择不同的组件、配置不同的参数,那么 Helm Chart 是不二之选。 就像玩乐高,可以根据自己的想法搭建出各种各样的模型。

最后的温馨提示:

无论选择哪种方式,都要注意以下几点:

  • 数据安全: 定期备份 Redis 数据,防止数据丢失。
  • 性能监控: 监控 Redis 集群的性能指标,及时发现和解决问题。
  • 安全加固: 设置 Redis 密码,限制访问权限,防止恶意攻击。

好了,今天的“云原生厨房”就到这里了。希望这道“Redis 三吃”能让你在 Kubernetes 的世界里玩得更开心!🎉

记住,云原生不是终点,而是起点。让我们一起探索更多有趣的云原生技术,创造更美好的未来! Bye~ 👋

发表回复

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