Kubernetes生产实践之Redis-cluster,


方案一 自定义yaml文件安装redis cluster

背景

在Kubernetes中部署Redis集群面临挑战,因为每个Redis实例都依赖于一个配置文件,该文件可以跟踪其他集群实例及其角色。为此,需要结合使用Kubernetes StatefulSets和PersistentVolumes实现。

redis cluster架构示意图:

创建StatefulSet yaml文件

  1. --- 
  2. apiVersion: v1 
  3. kind: ConfigMap 
  4. metadata: 
  5.   name: redis-cluster 
  6. data: 
  7.   update.sh: | 
  8.     #!/bin/sh 
  9.     REDIS_NODES="/data/nodes.conf" 
  10.     sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${REDIS_NODES} 
  11.     exec "$@" 
  12.   redis.conf: |+ 
  13.     bind 0.0.0.0 
  14.     cluster-enabled yes 
  15.     cluster-require-full-coverage no 
  16.     cluster-node-timeout 30000 
  17.     cluster-config-file /data/nodes.conf 
  18.     cluster-migration-barrier 1 
  19.     appendonly yes 
  20.     protected-mode no 
  21. --- 
  22. apiVersion: apps.kruise.io/v1beta1 
  23. # apiVersion: apps/v1 
  24. kind: StatefulSet 
  25. metadata: 
  26.   name: redis-cluster 
  27. spec: 
  28.   serviceName: redis-cluster 
  29.   replicas: 6 
  30.   selector: 
  31.     matchLabels: 
  32.       app: redis-cluster 
  33.   template: 
  34.     metadata: 
  35.       labels: 
  36.         app: redis-cluster 
  37.     spec: 
  38.       containers: 
  39.       - name: redis 
  40.         image: redis:6.2.1-alpine 
  41.         ports: 
  42.         - containerPort: 6379 
  43.           name: client 
  44.         - containerPort: 16379 
  45.           name: gossip 
  46.         command: ["/conf/update.sh", "redis-server", "/conf/redis.conf"] 
  47.         env: 
  48.         - name: POD_IP 
  49.           valueFrom: 
  50.             fieldRef: 
  51.               fieldPath: status.podIP 
  52.         volumeMounts: 
  53.         - name: conf 
  54.           mountPath: /conf 
  55.           readOnly: false 
  56.         - name: data 
  57.           mountPath: /data 
  58.           readOnly: false 
  59.       volumes: 
  60.       - name: conf 
  61.         configMap: 
  62.           name: redis-cluster 
  63.           defaultMode: 0755 
  64.   volumeClaimTemplates: 
  65.   - metadata: 
  66.       name: data 
  67.     spec: 
  68.       accessModes: [ "ReadWriteOnce" ] 
  69.       resources: 
  70.         requests: 
  71.           storage: 100Gi 
  72.       storageClassName: rbd 

注释:

  1. cluster-migration-barrier 那些分配后仍然剩余migration barrier个从节点的主节点才会触发节点分配,而不是分配前有migration barrier个从节点的主节点就会触发节点分配,默认是1,生产环境建议维持默认值 
  2. protected-mode no 参数是为了禁止外网访问redis,如果启用了,则只能够通过lookback ip(127.0.0.1)访问Redis,如果外网访问redis,会报出异常。 
  3. apiVersion: apps.kruise.io/v1beta1 控制器这里使用kruise提供的Advanced StatefulSet,如果集群没有安装kruise,可以使用 apps/v1 

安装redis-cluster

  1. [root@qd01-stop-k8s-master001 redis]# kubectl apply -f install-redis.yaml 
  2. configmap/redis-cluster created 
  3. statefulset.apps.kruise.io/redis-cluster created 
  4.  
  5. [root@qd01-stop-k8s-master001 redis]# kubectl get po -n op 
  6. NAME              READY   STATUS    RESTARTS   AGE 
  7. redis-cluster-0   1/1     Running   0          3m26s 
  8. redis-cluster-1   1/1     Running   0          3m14s 
  9. redis-cluster-2   1/1     Running   0          2m54s 
  10. redis-cluster-3   1/1     Running   0          2m23s 
  11. redis-cluster-4   1/1     Running   0          2m14s 
  12. redis-cluster-5   1/1     Running   0          114s 

创建redis-cluster service

  1. --- 
  2. apiVersion: v1 
  3. kind: Service 
  4. metadata: 
  5.   name: redis-cluster 
  6.   namespace: op 
  7. spec: 
  8.   type: ClusterIP 
  9.   ports: 
  10.   - port: 6379 
  11.     targetPort: 6379 
  12.     name: client 
  13.   - port: 16379 
  14.     targetPort: 16379 
  15.     name: gossip 
  16.   selector: 
  17.     app: redis-cluster 
  1. [root@qd01-stop-k8s-master001 redis]# kubectl apply -f redis-svc.yml 
  2. service/redis-cluster created 
  3. [root@qd01-stop-k8s-master001 redis]# kubectl get svc -n op 
  4. NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE 
  5. redis-cluster   ClusterIP   10.97.197.224   <none>        6379/TCP,16379/TCP   9s 
  6.  
  7. 测试能后连通 
  8. [root@qd01-stop-k8s-master001 redis]# telnet  10.97.197.224 6379 
  9. Trying 10.97.197.224... 
  10. Connected to 10.97.197.224. 
  11. Escape character is '^]'. 

初始化redis-cluster

执行如下命令,获取到pod IP,然后使用redis-cli --cluster创建集群

  1. [root@qd01-stop-k8s-master001 redis]# kubectl -n op exec -it redis-cluster-0 -- redis-cli --cluster create --cluster-replicas 1 $(kubectl -n op get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 {end}') 
  2. >>> Performing hash slots allocation on 6 nodes... 
  3. Master[0] -> Slots 0 - 5460 
  4. Master[1] -> Slots 5461 - 10922 
  5. Master[2] -> Slots 10923 - 16383 
  6. Adding replica 100.88.43.67:6379 to 100.64.147.152:6379 
  7. Adding replica 100.113.170.5:6379 to 100.98.174.217:6379 
  8. Adding replica 100.64.147.153:6379 to 100.80.158.227:6379 
  9. M: b47b27a3dbddf3fc1370cbe14ae753f4fce20b04 100.64.147.152:6379 
  10.    slots:[0-5460] (5461 slots) master 
  11. M: 09543217c903350e963fc4fdf4acb73f8a1b7f8b 100.98.174.217:6379 
  12.    slots:[5461-10922] (5462 slots) master 
  13. M: 5389ace495b68eeac85370d6783648dff68f2fb6 100.80.158.227:6379 
  14.    slots:[10923-16383] (5461 slots) master 
  15. S: b1f39714c006ae55b12b18e6537303d7a00e1704 100.64.147.153:6379 
  16.    replicates 5389ace495b68eeac85370d6783648dff68f2fb6 
  17. S: 0113f4668ec2f3ca2e9470c44bd5faab532b0936 100.88.43.67:6379 
  18.    replicates b47b27a3dbddf3fc1370cbe14ae753f4fce20b04 
  19. S: e1e2f18ae66c79f1943390beabb59613abbad38a 100.113.170.5:6379 
  20.    replicates 09543217c903350e963fc4fdf4acb73f8a1b7f8b 
  21. Can I set the above configuration? (type 'yes' to accept): yes 
  22. >>> Nodes configuration updated 
  23. >>> Assign a different config epoch to each node 
  24. >>> Sending CLUSTER MEET messages to join the cluster 
  25. Waiting for the cluster to join 
  26. .. 
  27. >>> Performing Cluster Check (using node 100.64.147.152:6379) 
  28. M: b47b27a3dbddf3fc1370cbe14ae753f4fce20b04 100.64.147.152:6379 
  29.    slots:[0-5460] (5461 slots) master 
  30.    1 additional replica(s) 
  31. S: 0113f4668ec2f3ca2e9470c44bd5faab532b0936 100.88.43.67:6379 
  32.    slots: (0 slots) slave 
  33.    replicates b47b27a3dbddf3fc1370cbe14ae753f4fce20b04 
  34. M: 09543217c903350e963fc4fdf4acb73f8a1b7f8b 100.98.174.217:6379 
  35.    slots:[5461-10922] (5462 slots) master 
  36.    1 additional replica(s) 
  37. M: 5389ace495b68eeac85370d6783648dff68f2fb6 100.80.158.227:6379 
  38.    slots:[10923-16383] (5461 slots) master 
  39.    1 additional replica(s) 
  40. S: e1e2f18ae66c79f1943390beabb59613abbad38a 100.113.170.5:6379 
  41.    slots: (0 slots) slave 
  42.    replicates 09543217c903350e963fc4fdf4acb73f8a1b7f8b 
  43. S: b1f39714c006ae55b12b18e6537303d7a00e1704 100.64.147.153:6379 
  44.    slots: (0 slots) slave 
  45.    replicates 5389ace495b68eeac85370d6783648dff68f2fb6 
  46. [OK] All nodes agree about slots configuration. 
  47. >>> Check for open slots... 
  48. >>> Check slots coverage... 
  49. [OK] All 16384 slots covered. 

验证集群信息

  1. [root@qd01-stop-k8s-master001 redis]# kubectl -n op  exec -it redis-cluster-0 -- redis-cli cluster info 
  2. cluster_state:ok 
  3. cluster_slots_assigned:16384 
  4. cluster_slots_ok:16384 
  5. cluster_slots_pfail:0 
  6. cluster_slots_fail:0 
  7. cluster_known_nodes:6 
  8. cluster_size:3 
  9. cluster_current_epoch:6 
  10. cluster_my_epoch:1 
  11. cluster_stats_messages_ping_sent:178 
  12. cluster_stats_messages_pong_sent:181 
  13. cluster_stats_messages_sent:359 
  14. cluster_stats_messages_ping_received:176 
  15. cluster_stats_messages_pong_received:178 
  16. cluster_stats_messages_meet_received:5 
  17. cluster_stats_messages_received:359 
  18.  
  19. [root@qd01-stop-k8s-master001 redis]# kubectl -n op  exec -it redis-cluster-0 -- redis-cli cluster nodes 
  20. 0113f4668ec2f3ca2e9470c44bd5faab532b0936 100.88.43.67:6379@16379 slave b47b27a3dbddf3fc1370cbe14ae753f4fce20b04 0 1615348311156 1 connected 
  21. 09543217c903350e963fc4fdf4acb73f8a1b7f8b 100.98.174.217:6379@16379 master - 0 1615348314162 2 connected 5461-10922 
  22. b47b27a3dbddf3fc1370cbe14ae753f4fce20b04 100.64.147.152:6379@16379 myself,master - 0 1615348312000 1 connected 0-5460 
  23. 5389ace495b68eeac85370d6783648dff68f2fb6 100.80.158.227:6379@16379 master - 0 1615348312000 3 connected 10923-16383 
  24. e1e2f18ae66c79f1943390beabb59613abbad38a 100.113.170.5:6379@16379 slave 09543217c903350e963fc4fdf4acb73f8a1b7f8b 0 1615348313160 2 connected 
  25. b1f39714c006ae55b12b18e6537303d7a00e1704 100.64.147.153:6379@16379 slave 5389ace495b68eeac85370d6783648dff68f2fb6 0 1615348312158 3 connected 

从输出可以看到,集群总共6个节点,三主三从

方案二 使用kubeDB安装redis

安装kubeDB

1、安装KubeDB

获取AppsCode License

https://license-issuer.appscode.com/

下载KubeDB charts

https://github.com/appscode/charts/tree/master/stable/kubedb-community

  1. [root@qd01-stop-k8s-master001 kubedb-community]# unzip kubedb-community-v0.16.2.tgz 
  2. [root@qd01-stop-k8s-master001 kubedb-community]# cd kubedb-community 
  3. [root@qd01-stop-k8s-master001 kubedb-community]# ls -al 
  4. total 96 
  5. drwxr-xr-x 4 root root   158 Mar 10 15:26 . 
  6. drwxr-xr-x 3 root root    66 Mar 10 15:24 .. 
  7. -rw-r--r-- 1 root root   351 Feb 16 09:55 Chart.yaml 
  8. drwxr-xr-x 2 root root    28 Mar 10 15:24 ci 
  9. -rw-r--r-- 1 root root   493 Feb 16 09:55 doc.yaml 
  10. -rw-r--r-- 1 root root   353 Feb 16 09:55 .helmignore 
  11. -rw-r--r-- 1 root root 24422 Feb 16 09:55 README.md 
  12. drwxr-xr-x 2 root root  4096 Mar 10 15:24 templates 
  13. -rw-r--r-- 1 root root 47437 Feb 16 09:55 values.openapiv3_schema.yaml 
  14. -rw-r--r-- 1 root root  5230 Feb 16 09:55 values.yaml 

修改values.yaml,把License文件放到kubedb-community目录下

2、使用helm安装

  1. [root@qd01-stop-k8s-master001 kubedb-community]# helm install kubedb-community --namespace kube-system --set-file license=./kubedb-community-license.txt -f values.yaml  . 
  2. NAME: kubedb-community 
  3. LAST DEPLOYED: Wed Mar 10 15:38:59 2021 
  4. NAMESPACE: kube-system 
  5. STATUS: deployed 
  6. REVISION: 1 
  7. TEST SUITE: None 
  8. NOTES: 
  9. To verify that KubeDB has started, run: 
  10.   kubectl get deployment --namespace kube-system -l "app.kubernetes.io/name=kubedb-community,app.kubernetes.io/instance=kubedb-community" 
  11. Now install/upgrade appscode/kubedb-catalog chart. 
  12. To install, run: 
  13.   helm install kubedb-catalog appscode/kubedb-catalog --version v0.16.2 --namespace kube-system 
  14. To upgrade, run: 
  15.   helm upgrade kubedb-catalog appscode/kubedb-catalog --version v0.16.2 --namespace kube-system 
  16.  
  17. 执行如下命令查看是否安装完成 
  18. [root@qd01-stop-k8s-master001 kubedb-community]# kubectl get deployment --namespace kube-system -l "app.kubernetes.io/name=kubedb-community,app.kubernetes.io/instance=kubedb-community" 
  19. NAME               READY   UP-TO-DATE   AVAILABLE   AGE 
  20. kubedb-community   1/1     1            1           38s 
  21.  
  22. 等待crds注册成功 
  23. [root@qd01-stop-k8s-master001 kubedb-community]# kubectl get crds -l app.kubernetes.io/name=kubedb -w 
  24. NAME                                       CREATED AT 
  25. elasticsearches.kubedb.com                 2021-03-10T07:39:42Z 
  26. elasticsearchversions.catalog.kubedb.com   2021-03-10T07:39:45Z 
  27. etcds.kubedb.com                           2021-03-10T07:39:42Z 
  28. etcdversions.catalog.kubedb.com            2021-03-10T07:39:45Z 
  29. memcacheds.kubedb.com                      2021-03-10T07:39:43Z 
  30. memcachedversions.catalog.kubedb.com       2021-03-10T07:39:45Z 
  31. mongodbs.kubedb.com                        2021-03-10T07:39:43Z 
  32. mongodbversions.catalog.kubedb.com         2021-03-10T07:39:45Z 
  33. mysqls.kubedb.com                          2021-03-10T07:39:43Z 
  34. mysqlversions.catalog.kubedb.com           2021-03-10T07:39:46Z 
  35. perconaxtradbs.kubedb.com                  2021-03-10T07:39:43Z 
  36. perconaxtradbversions.catalog.kubedb.com   2021-03-10T07:39:46Z 
  37. pgbouncers.kubedb.com                      2021-03-10T07:39:44Z 
  38. pgbouncerversions.catalog.kubedb.com       2021-03-10T07:39:46Z 
  39. postgreses.kubedb.com                      2021-03-10T07:39:44Z 
  40. postgresversions.catalog.kubedb.com        2021-03-10T07:39:46Z 
  41. proxysqls.kubedb.com                       2021-03-10T07:39:44Z 
  42. proxysqlversions.catalog.kubedb.com        2021-03-10T07:39:46Z 
  43. redises.kubedb.com                         2021-03-10T07:39:45Z 
  44. redisversions.catalog.kubedb.com           2021-03-10T07:39:46Z 

3、安装KubeDB Catalog

同样,先下载

https://github.com/appscode/charts/tree/master/stable/kubedb-catalog

  1. [root@qd01-stop-k8s-master001 kubedb-catalog]# tar -zxf kubedb-catalog-v0.16.2.tgz 
  2. [root@qd01-stop-k8s-master001 kubedb-catalog]# cd kubedb-catalog 
  3. [root@qd01-stop-k8s-master001 kubedb-catalog]# ls -al 
  4. total 24 
  5. drwxr-xr-x  3 root root  148 Mar 10 15:48 . 
  6. drwxr-xr-x  3 root root   28 Mar 10 15:48 .. 
  7. -rw-r--r--  1 root root  321 Jan 26 20:08 Chart.yaml 
  8. -rw-r--r--  1 root root  467 Jan 26 20:08 doc.yaml 
  9. -rw-r--r--  1 root root  353 Jan 26 20:08 .helmignore 
  10. -rw-r--r--  1 root root 3195 Jan 26 20:08 README.md 
  11. drwxr-xr-x 12 root root  188 Mar 10 15:48 templates 
  12. -rw-r--r--  1 root root  744 Jan 26 20:08 values.openapiv3_schema.yaml 
  13. -rw-r--r--  1 root root 1070 Jan 26 20:08 values.yaml 
  14.  
  15. [root@qd01-stop-k8s-master001 kubedb-catalog]# helm install kubedb-catalog --namespace kube-system -f values.yaml  . 
  16. NAME: kubedb-catalog 
  17. LAST DEPLOYED: Wed Mar 10 15:50:50 2021 
  18. NAMESPACE: kube-system 
  19. STATUS: deployed 
  20. REVISION: 1 
  21. TEST SUITE: None 

使用kubedb安装redis

1、先看下官方给的redis生命周期示意图

kubedb安装redis支持如下特性

  1. Features    Availability 
  2. Clustering    ✓ 
  3. Instant Backup    ✗ 
  4. Scheduled Backup    ✗ 
  5. Persistent Volume    ✓ 
  6. Initialize using Snapshot    ✗ 
  7. Initialize using Script    ✗ 
  8. Custom Configuration    ✓ 
  9. Using Custom docker image    ✓ 
  10. Builtin Prometheus Discovery    ✓ 
  11. Using Prometheus operator    ✓ 

2、查看支持的版本

  1. [root@qd01-stop-k8s-master001 kubedb-catalog]# kubectl get redisversions 
  2. NAME       VERSION   DB_IMAGE                DEPRECATED   AGE 
  3. 4.0.11     4.0.11    kubedb/redis:4.0.11                  15m 
  4. 4.0.6-v2   4.0.6     kubedb/redis:4.0.6-v2                15m 
  5. 5.0.3-v1   5.0.3     kubedb/redis:5.0.3-v1                15m 
  6. 6.0.6      6.0.6     kubedb/redis:6.0.6                   15m 

3、编辑yaml安装文件

可以参照

https://github.com/kubedb/docs/blob/v2021.01.26/docs/examples/redis/clustering/demo-1.yaml

这里选择安装6.0.6这个版本,我的集群storageClassName: "rbd",请根据实际修改

如果想自定义redis.conf,请参考

https://github.com/kubedb/docs/blob/v2021.01.26/docs/examples/redis/custom-config/redis-custom.yaml

  1. apiVersion: kubedb.com/v1alpha2 
  2. kind: Redis 
  3. metadata: 
  4.   name: redis-cluster 
  5.   namespace: op 
  6. spec: 
  7.   version: 6.0.6 
  8.   mode: Cluster 
  9.   cluster: 
  10.     master: 3 
  11.     replicas: 1 
  12.   storageType: Durable 
  13.   storage: 
  14.     resources: 
  15.       requests: 
  16.         storage: 1Gi 
  17.     storageClassName: "rbd" 
  18.     accessModes: 
  19.       - ReadWriteOnce 

执行安装

  1. [root@qd01-stop-k8s-master001 kubedb-community]# kubectl apply -f redis-cluster.yaml 
  2. redis.kubedb.com/redis-cluster created 
  3.  
  4. 安装完成,可以如下查看 
  5. [root@qd01-stop-k8s-master001 kubedb-community]# kubectl get rd,po -n op 
  6. NAME                             VERSION   STATUS         AGE 
  7. redis.kubedb.com/redis-cluster   6.0.6     Provisioning   6m55s 
  8.  
  9. NAME                         READY   STATUS    RESTARTS   AGE 
  10. pod/redis-cluster-shard0-0   1/1     Running   0          6m54s 
  11. pod/redis-cluster-shard0-1   1/1     Running   0          6m18s 
  12. pod/redis-cluster-shard1-0   1/1     Running   0          5m38s 
  13. pod/redis-cluster-shard1-1   1/1     Running   0          5m1s 
  14. pod/redis-cluster-shard2-0   1/1     Running   0          4m30s 
  15. pod/redis-cluster-shard2-1   1/1     Running   0          4m8s 
  16.  
  17. [root@qd01-stop-k8s-master001 redis]# kubectl get svc -n op 
  18. NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE 
  19. redis-cluster        ClusterIP   10.97.197.224   <none>        6379/TCP   5h16m 
  20. redis-cluster-pods   ClusterIP   None            <none>        6379/TCP   17m 

4、验证集群

  1. [root@qd01-stop-k8s-master001 kubedb-community]# kubectl get pods -n  op  -o jsonpath='{range.items[*]}{.metadata.name} ---------- {.status.podIP}:6379{"\t\n"}{end}' | grep redis 
  2. redis-cluster-shard0-0 ---------- 100.64.147.156:6379 
  3. redis-cluster-shard0-1 ---------- 100.98.174.218:6379 
  4. redis-cluster-shard1-0 ---------- 100.126.252.204:6379 
  5. redis-cluster-shard1-1 ---------- 100.113.170.6:6379 
  6. redis-cluster-shard2-0 ---------- 100.107.55.69:6379 
  7. redis-cluster-shard2-1 ---------- 100.78.230.4:6379 
  8.  
  9. [root@qd01-stop-k8s-master001 redis]# kubectl -n op  exec -it redis-cluster-shard0-0  -- redis-cli cluster info 
  10. cluster_state:ok 
  11. cluster_slots_assigned:16384 
  12. cluster_slots_ok:16384 
  13. cluster_slots_pfail:0 
  14. cluster_slots_fail:0 
  15. cluster_known_nodes:6 
  16. cluster_size:3 
  17. cluster_current_epoch:3 
  18. cluster_my_epoch:1 
  19. cluster_stats_messages_ping_sent:864 
  20. cluster_stats_messages_pong_sent:882 
  21. cluster_stats_messages_sent:1746 
  22. cluster_stats_messages_ping_received:879 
  23. cluster_stats_messages_pong_received:864 
  24. cluster_stats_messages_meet_received:3 
  25. cluster_stats_messages_received:1746 
  26.  
  27. [root@qd01-stop-k8s-master001 redis]# kubectl -n op  exec -it redis-cluster-shard0-0  -- redis-cli cluster nodes 
  28. 1895cb4b9c31b848666c61000e502f55a29a8255 100.64.147.155:6379@16379 master - 0 1615365162008 2 connected 5461-10922 
  29. 30bdbf2ca37001774498a9b935afbc1cd2ce389c 100.126.252.203:6379@16379 slave 2c06092fafa99e0158e39e6237a04fed25be3550 0 1615365163000 1 connected 
  30. 9b2cfbd5c1b417121d410141b6da9512ad29ce3c 100.78.230.3:6379@16379 slave e83446c368839c5fdccf5f70e3b1004eb67cb651 0 1615365163512 3 connected 
  31. 2c06092fafa99e0158e39e6237a04fed25be3550 100.82.197.130:6379@16379 myself,master - 0 1615365162000 1 connected 0-5460 
  32. 1379d2b20f26ab13d53068d276ec5d988b7a0273 100.64.122.197:6379@16379 slave 1895cb4b9c31b848666c61000e502f55a29a8255 0 1615365163000 2 connected 
  33. e83446c368839c5fdccf5f70e3b1004eb67cb651 100.107.55.68:6379@16379 master - 0 1615365164014 3 connected 10923-16383 

相关内容