operator部署redis集群

本文介绍如何使用operator部署Redis集群,包括创建命名空间、自定义资源、operator及集群YAML文件等步骤,并提供验证集群稳定性的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

operator部署redis集群

1、现在operator的redis相关包

git clone https://github.com/ucloud/redis-cluster-operator.git

yum install unzip
unzip redis-cluster-operator.git
tree看下目录结构

2、创建yaml文件

2.1 创建命名空间

CCE要在界面创建项目

[root@work-master1 operator]# kubectl create namespace redis-cluster

2.2 创建自定义资源

1、修改namespace
[root@work-master1 crds]# cat redis.kun_distributedredisclusters_crd.yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: distributedredisclusters.redis.kun
  nammespace: redis-cluster
spec:


2、创建yaml文件
[root@work-master1 crds]# pwd
/root/zhs/redis/operator/redis-cluster-operator-master/deploy/crds
[root@work-master1 crds]# tree
.
├── redis.kun_distributedredisclusters_crd.yaml
└── redis.kun_redisclusterbackups_crd.yaml

kubectl apply -f deploy/crds/

2.3 创建operator

[root@work-master1 cluster]# pwd
/root/zhs/redis/operator/redis-cluster-operator-master/deploy/cluster
[root@work-master1 cluster]# tree
.
├── cluster_role_binding.yaml
├── cluster_role.yaml
└── operator.yaml

1、修改命名空间
2、创建yanl文件
cd deploy
kubectl apply -f service_account.yaml 
cd deploy/cluster/
kubectl apply -f cluster_role.yaml 
kubectl apply -f cluster_role_binding.yaml 
kubectl apply -f operator.yaml 
kubectl get pod -n redis-cluster 

3、创建redis集群yaml文件

cat redis-cluster.yaml 
 
apiVersion: redis.kun/v1alpha1
kind: DistributedRedisCluster
metadata:
  annotations:
    # if your operator run as cluster-scoped, add this annotations
    redis.kun/scope: cluster-scoped
  name: example-distributedrediscluster
  namespace: redis-cluster
spec:
  image: redis:5.0.4-alpine
  imagePullPolicy: IfNotPresent
  masterSize: 3			#master节点数量
  clusterReplicas: 1	#每个master节点的从节点数量
  serviceName: redis-svc
  # resources config
  resources:
    limits:
      cpu: 300m
      memory: 200Mi
    requests:
      cpu: 200m
      memory: 150Mi
  # pv storage
  storage:
    type: persistent-claim
    size: 1Gi
    class: copaddon-zhanghsn-poc
    deleteClaim: true
    
kubectl apply -f redis-cluster.yaml
=============================================================
root@work-master1 deploy]# kubectl get pod -n redis-cluster
NAME                                      READY   STATUS    RESTARTS   AGE
drc-example-distributedrediscluster-0-0   1/1     Running   0          41m
drc-example-distributedrediscluster-0-1   1/1     Running   0          41m
drc-example-distributedrediscluster-1-0   1/1     Running   0          41m
drc-example-distributedrediscluster-1-1   1/1     Running   0          40m
drc-example-distributedrediscluster-2-0   1/1     Running   0          41m
drc-example-distributedrediscluster-2-1   1/1     Running   0          41m
redis-cluster-operator-764f4f9bb7-5kmnt   1/1     Running   0          41m

[root@work-master1 deploy]# kubectl get sc
NAME                    PROVISIONER               RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
ceph-csi-cephfs         cephfs.csi.ceph.com       Delete          Immediate              true                   59d
copaddon-nfs            copaddon-nfs              Delete          Immediate              false                  61d
copaddon-zhanghsn-poc   copaddon-zhanghsn-poc     Delete          Immediate              false                  24h
csi-local               everest-csi-provisioner   Delete          Immediate              false                  62d
csi-local-topology      everest-csi-provisioner   Delete          WaitForFirstConsumer   false                  62d

[root@work-master1 deploy]# kubectl get pvc -n redis-cluster
NAME                                                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS            AGE
redis-data-drc-example-distributedrediscluster-0-0   Bound    pvc-50157068-c31c-4aad-b33e-08a085a186f4   2Gi        RWO            copaddon-zhanghsn-poc   71m
redis-data-drc-example-distributedrediscluster-0-1   Bound    pvc-207d7a9a-380d-4089-9424-013aecaac497   2Gi        RWO            copaddon-zhanghsn-poc   70m
redis-data-drc-example-distributedrediscluster-1-0   Bound    pvc-8f94c04a-60af-4858-b8a4-19e7bda2b020   2Gi        RWO            copaddon-zhanghsn-poc   71m
redis-data-drc-example-distributedrediscluster-1-1   Bound    pvc-e7be9b40-4f78-4326-a33b-921ef202d13d   2Gi        RWO            copaddon-zhanghsn-poc   70m
redis-data-drc-example-distributedrediscluster-2-0   Bound    pvc-cbf0966c-b335-46b2-a8c8-21ec8a4dca92   2Gi        RWO            copaddon-zhanghsn-poc   71m
redis-data-drc-example-distributedrediscluster-2-1   Bound    pvc-851f2e41-a3e9-4da0-b4c1-98abb7efe0a4   2Gi        RWO            copaddon-zhanghsn-poc   70m

4、修改configmap文件

apiVersion: v1
data:
  fix-ip.sh: |-
    #!/bin/sh
    CLUSTER_CONFIG="/data/nodes.conf"
    if [ -f ${CLUSTER_CONFIG} ]; then
        if [ -z "${POD_IP}" ]; then
        echo "Unable to determine Pod IP address!"
        exit 1
        fi
        echo "Updating my IP to ${POD_IP} in ${CLUSTER_CONFIG}"
        sed -i.bak -e "/myself/ s/ .*:6379@16379/ ${POD_IP}:6379@16379/" ${CLUSTER_CONFIG}
    fi
    exec "$@"
  redis.conf: |-
    cluster-enabled yes
    cluster-config-file /data/nodes.conf
    cluster-node-timeout 10000
    protected-mode no
    daemonize no
    pidfile /var/run/redis.pid
    port 6379
    tcp-backlog 511
    bind 0.0.0.0
    timeout 3600
    tcp-keepalive 1
    loglevel verbose
    logfile /data/redis.log
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb
    dir /data
    #requirepass yl123456
    appendonly yes
    appendfilename "appendonly.aof"
    appendfsync everysec
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    lua-time-limit 20000
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    #rename-command FLUSHALL  ""
    latency-monitor-threshold 0
    notify-keyspace-events ""
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-entries 512
    list-max-ziplist-value 64
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit slave 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    aof-rewrite-incremental-fsync yes
  shutdown.sh: "#!/bin/sh\nCLUSTER_CONFIG=\"/data/nodes.conf\"\nfailover() {\n\techo
    \"Do CLUSTER FAILOVER\"\n\tmasterID=$(cat ${CLUSTER_CONFIG} | grep \"myself\"
    | awk '{print $1}')\n\techo \"Master: ${masterID}\"\n\tslave=$(cat ${CLUSTER_CONFIG}
    | grep ${masterID} | grep \"slave\" | awk 'NR==1{print $2}' | sed 's/:6379@16379//')\n\techo
    \"Slave: ${slave}\"\n\tpassword=$(cat /data/redis_password)\n\tif [[ -z \"${password}\"
    ]]; then\n\t\tredis-cli -h ${slave} CLUSTER FAILOVER\n\telse\n\t\tredis-cli -h
    ${slave} -a \"${password}\" CLUSTER FAILOVER\n\tfi\n\techo \"Wait for MASTER <->
    SLAVE syncFinished\"\n\tsleep 20\n}\nif [ -f ${CLUSTER_CONFIG} ]; then\n\tcat
    ${CLUSTER_CONFIG} | grep \"myself\" | grep \"master\" && \\\n\tfailover\nfi"
kind: ConfigMap
metadata:
  labels:
    managed-by: redis-cluster-operator
    redis.kun/name: example-distributedrediscluster
  name: redis-cluster-example-distributedrediscluster-bak
  namespace: redis-cluster

5、查看redis集群状态

[root@work-master1 operator]# kubectl exec -it -n redis-cluster drc-example-distributedrediscluster-2-0 -- sh
/data # redis-cli -c -h redis-svc
redis-svc:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:0
cluster_stats_messages_ping_sent:2697
cluster_stats_messages_pong_sent:2797
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:5495
cluster_stats_messages_ping_received:2797
cluster_stats_messages_pong_received:2694
cluster_stats_messages_received:5491
redis-svc:6379>

6、验证redis集群

验证方式
1、 kubectl delete pod -n redis-cluster --all
等待pod重启进入pod看集群状态是否是ok
2、kubectl delete pod -n redis-cluster <namsterpod>
查看集群是否还是正常状态
3、先set数据,再kubectl delete pod -n redis-cluster --all
恢复看数据在不在

7、pv修改策略为Retain

for pv in `kubectl get pvc -n redis-cluster |awk 'NR>=2{print $3}'` ; do kubectl  -n redis-cluster patch pv $pv  -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' ;done

8、operator注意部分

1、平时不要delete --all

在使用operator部署的redis集群,在删除集群数据会被删除包括dump.rdb文件,所以一般不用去delete --all,或者删除前进行数据备份

2、configmap问题

operator创建的cm修改后悔自动恢复原来的yaml文件

#这里的骚操作
把configmap重新创建一个,修改sts中cm的挂在

9、问题记录

问题描述

operator部署完redis,测试时候发现delete --all完pod起来,redis集群式ok,但是数据没有

问题定位

1、在用户进行delete --all时候可能operator默认用户不用了就会删除数据包括pv,但是感觉不合理,pv的数据应该不能删除
2、在查看redis的配置是发现是空文件,configmap中redis.conf是空的,修改完出现一个现象,它会恢复到以前,所以这也是个问题

问题解决

1、修改pv成都策略为Retain
for pv in `kubectl get pvc -n redis-cluster |awk 'NR>=2{print $3}'` ; do kubectl  -n redis-cluster patch pv $pv  -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' ;done
2、重新创建一个configmap,修改sts中configmap的挂载为新创建的configmap

总结

进过上面操作重新测试,delete --all完,pod为running进入pod执行keys *,发现数据在,问题解决

Redisinsight容器化部署

镜像拉取

配置阿里镜像源

cd /etc/docker
vim daemon.json
{
  "registry-mirrors": ["https://qrq6fspr.mirror.aliyuncs.com"]
}
systemctl daemon-reload
systemctl restart docker
docker pull redislabs/redisinsight
docker tag redislabs/redisinsight:latest cce.digitalchina.com/zhsn/redisinsight:latest

yaml文件准备

实际环境cce配置swr拉取镜像认证

  imagePullSecrets:
  - name: default-secret
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: redis-insight
  namespace: redis-cluster
spec:
  replicas: 1
  selector: 
    matchLabels:
      app: redis-insight
  template: 
    metadata: 
      labels: 
        app: redis-insight
    spec:
      containers:
      - name: redis-insight
        image: cce.digitalchina.com/zhsn/redisinsight:latest
        imagePullPolicy: IfNotPresent
        ports: 
        - containerPort: 8001
        volumeMounts: 
        - name: db
          mountPath:  /db
      imagePullSecrets:
      - name: default-secret
      volumes:
      - name: db
        persistentVolumeClaim:
          claimName: redisinsight-pv-claim
---
apiVersion: v1
kind: Service
metadata:
  name: redis-insight-service
  namespace: redis-cluster
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8001
    nodePort: 31888
  selector:
    app: redis-insight
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redisinsight-pv-claim
  namespace: redis-cluster
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: copaddon-nfs
  volumeMode: Filesystem
  volumeName: pvc-3a9a434f-b859-427c-a5e4-a82f713b55f4

容器启动

kubectl apply -f Redisinsight.yaml  --validate=false

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

<think>嗯,用户在生产环境中使用Operator部署Redis集群时遇到了写入数据失败的问题,怀疑和分片架构有关。首先,我需要回忆一下Redis Cluster的分片机制。Redis Cluster通过分片将数据分布到多个节点,每个节点负责一部分哈希槽。写入数据时,客户端会根据CRC16(key) mod 16384计算出对应的哈希槽,然后路由到正确的节点。如果客户端没有正确处理重定向,比如MOVED或ASK错误,就可能导致写入失败。 接下来,用户的问题可能涉及分片配置错误。比如,哈希槽分配不均或者未正确分配,导致某些节点没有处理特定槽的请求。这时候需要检查集群状态,使用redis-cli --cluster check确认所有槽是否被覆盖,没有遗漏或重复。 然后是客户端配置的问题。有些客户端可能需要显式启用集群模式,比如Jedis的JedisCluster配置。如果客户端不支持集群模式,或者版本过旧,可能无法正确处理重定向,从而写入失败。需要确认客户端库是否兼容Redis Cluster,并且配置正确。 网络分区或节点故障也可能导致写入问题。如果主节点宕机且从节点未能及时提升,或者集群处于失败状态,无法达到多数节点确认,写入操作会被拒绝。检查节点状态和日志,确认是否有故障转移发生,以及集群是否健康。 另外,键哈希标签的使用是否正确。如果用户没有使用{}来确保相关键分配到同一槽,可能导致跨槽操作错误。例如,涉及多个键的事务或Lua脚本需要所有键在同一个槽,否则会失败。需要检查键的命名是否符合哈希标签的规则。 持久化配置和资源限制也不能忽视。AOF或RDB配置错误可能导致磁盘写满或权限问题,进而影响写入。同时,内存不足、CPU过载或网络带宽限制也会导致超时或拒绝服务。检查系统资源使用情况,以及Redis的持久化配置是否正确。 安全设置方面,ACL或密码配置错误可能阻止客户端认证,导致写入被拒绝。需要确认客户端连接时使用了正确的密码,并且ACL规则允许相应的操作。 排查步骤方面,应该先检查集群状态,确认哈希槽分配和节点健康。然后查看Redis日志,寻找错误信息。验证客户端配置,确保启用了集群模式。检查键的哈希标签使用,避免跨槽操作。最后,审查资源和安全配置,排除外部因素影响。 总的来说,分片架构确实可能引起写入失败,但需要结合具体场景分析。通过逐步排查集群配置、客户端行为、资源限制等方面,应该能找到根本原因。</think>在生产环境中使用Operator部署Redis集群时,写入数据失败可能与分片架构相关。以下是逐步分析框架和关键排查方向: --- ### **一、Redis Cluster分片机制的核心影响** Redis Cluster采用**哈希槽分片(16384 slots)**,写入失败可能与以下分片逻辑相关: 1. **键未路由到正确分片** - 现象:客户端收到`MOVED`或`ASK`重定向错误但未正确处理 - 原因:客户端未实现集群协议(如直接使用单机版SDK) - 验证命令: ```bash redis-cli -c -p <port> SET key value # 观察是否自动重定向 ``` 2. **哈希槽分配异常** - 检查集群槽覆盖完整性: ```bash redis-cli --cluster check <node-ip>:<port> # 确认输出中所有16384 slots均为"covered" ``` - 槽未分配或节点宕机会导致对应槽位数据不可写 --- ### **二、Operator部署场景的特有问题** #### 1. **CRD配置错误** - 检查RedisCluster CR资源中分片配置: ```yaml apiVersion: redis.redis.opstreelabs.in/v1beta1 kind: RedisCluster spec: clusterSize: 6 # 总节点数需为分片数倍数(如3主3从) replicas: 1 # 每个主节点的副本数 resources: ... # 资源不足会导致节点无法启动 ``` #### 2. **网络策略限制** - 分片间通信依赖**节点发现**(gossip协议) - 确认Pod网络策略允许: - 所有Redis Pod的TCP 6379(客户端)和16379(集群总线)端口互通 - 跨节点通信未被Calico/NetworkPolicy阻断 --- ### **三、高频故障场景排查** #### 场景1:跨槽操作(Cross-Slot Error) - **触发条件**:事务/Lua脚本中涉及多个键且未使用`{hash_tag}` - 错误示例: `ERR CROSSSLOT Keys in request don't hash to the same slot` - 解决方案: 强制相关键落在同一槽(如`{user123}.order`和`{user123}.profile`) #### 场景2:集群状态异常 - **检查集群健康度**: ```bash redis-cli CLUSTER INFO | grep cluster_state # 正常应为"cluster_state:ok" ``` - **主从切换失败**: 检查Operator日志是否有`failover`错误 ```bash kubectl logs -l app=redis-operator -c operator ``` --- ### **四、数据写入失败的直接验证步骤** 1. **强制写入测试(绕过客户端路由)** ```bash # 连接到具体分片节点直接写入 redis-cli -h <pod-ip> -c SET key_hashed_to_this_node value ``` - 成功 → 客户端路由逻辑问题 - 失败 → 节点级别问题(如磁盘权限、内存不足) 2. **检查节点日志** ```bash kubectl logs <redis-pod> | grep -E "ERR|WARN" ``` - 关键错误:`OOM command not allowed`、`-MISCONF`(持久化失败) --- ### **五、总结与建议** - **分片架构相关可能性排序**: **客户端路由问题** > **哈希槽分配异常** > **跨槽操作** > **Operator配置错误** - **优先行动项**: 1. 使用`redis-cli --cluster check`验证分片完整性 2. 检查客户端是否启用集群模式(如Java中`JedisCluster`而非`Jedis`) 3. 在Operator中明确配置`antiAffinity`避免节点资源竞争 建议结合Redis的`CLUSTER LOG`命令(查看最近集群事件)和Operator事件日志联动分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值