在Kubernetes集群上部署redis集群

左手的ㄟ右手 2022-05-10 10:58 594阅读 0赞

一、实验环境

操作系统:CentOS Linux release 7.2.1511 (Core)

GlusterFS: 4.1

redis:4.9.105

  1. # docker pull redis:5.0-rc5-alpine3.8 // 官方镜像
  2. # docker pull racccosta/redis // redis集群构建工具

docker版本

  1. # docker version
  2. Client:
  3. Version: 1.12.3
  4. API version: 1.24
  5. Go version: go1.6.3
  6. Git commit: 6b644ec
  7. Built:
  8. OS/Arch: linux/amd64

二、方案思路

每个Master都可以拥有多个Slave。当Master下线后,Redis集群会从多个Slave中选举出一个新的Master作为替代,而旧Master重新上线后变成新Master的Slave。

image

三、部署过程

  1. 创建GlusterFS存储
  2. 创建PV

创建GlusterFS存储

打算创建一个6节点的Redis集群,所以共享了6个目录。

  1. #!/bin/bash
  2. for loop in 0 1 2 3 4 5
  3. do
  4. gluster volume create redis-vol-$loop replica 3 paasm1:/dcos/redis-brick/pv$loop paasm2:/dcos/redis-brick/pv$loop paashar:/dcos/redis-brick/pv$loop;
  5. gluster volume start redis-vol-$loop;
  6. done

创建GlusterFS端点定义

  1. # vi glusterfs-endpoints.yml
  2. ---
  3. kind: Endpoints
  4. apiVersion: v1
  5. metadata:
  6. name: glusterfs-cluster
  7. namespace: kube-system
  8. subsets:
  9. - addresses:
  10. - ip: 10.142.71.120
  11. ports:
  12. - port: 7096
  13. - addresses:
  14. - ip: 10.142.71.121
  15. ports:
  16. - port: 7096
  17. - addresses:
  18. - ip: 10.142.71.123
  19. ports:
  20. - port: 7096
  21. # kubectl apply -f glusterfs-endpoints.yml

配置 service

  1. # vi glusterfs-service.yml
  2. ---
  3. kind: Service
  4. apiVersion: v1
  5. metadata:
  6. name: glusterfs-cluster
  7. namespace: kube-system
  8. spec:
  9. ports:
  10. - port: 7096
  11. # kubectl apply -f glusterfs-service.yml

创建PV

每一个Redis Pod都需要一个独立的PV来存储自己的数据,因此包含6个PV:

  1. # vi glusterfs-pv.yml
  2. apiVersion: v1
  3. kind: PersistentVolume
  4. metadata:
  5. name: pv000
  6. namespace: kube-system
  7. spec:
  8. capacity:
  9. storage: 2Gi
  10. accessModes:
  11. - ReadWriteMany
  12. glusterfs:
  13. endpoints: "glusterfs-cluster"
  14. path: "redis-vol-0"
  15. readOnly: false
  16. ---
  17. apiVersion: v1
  18. kind: PersistentVolume
  19. metadata:
  20. name: pv001
  21. namespace: kube-system
  22. spec:
  23. capacity:
  24. storage: 2Gi
  25. accessModes:
  26. - ReadWriteMany
  27. glusterfs:
  28. endpoints: "glusterfs-cluster"
  29. path: "redis-vol-1"
  30. readOnly: false
  31. ---
  32. apiVersion: v1
  33. kind: PersistentVolume
  34. metadata:
  35. name: pv002
  36. namespace: kube-system
  37. spec:
  38. capacity:
  39. storage: 2Gi
  40. accessModes:
  41. - ReadWriteMany
  42. glusterfs:
  43. endpoints: "glusterfs-cluster"
  44. path: "redis-vol-2"
  45. readOnly: false
  46. ---
  47. apiVersion: v1
  48. kind: PersistentVolume
  49. metadata:
  50. name: pv003
  51. namespace: kube-system
  52. spec:
  53. capacity:
  54. storage: 2Gi
  55. accessModes:
  56. - ReadWriteMany
  57. glusterfs:
  58. endpoints: "glusterfs-cluster"
  59. path: "redis-vol-3"
  60. readOnly: false
  61. ---
  62. apiVersion: v1
  63. kind: PersistentVolume
  64. metadata:
  65. name: pv004
  66. namespace: kube-system
  67. spec:
  68. capacity:
  69. storage: 2Gi
  70. accessModes:
  71. - ReadWriteMany
  72. glusterfs:
  73. endpoints: "glusterfs-cluster"
  74. path: "redis-vol-4"
  75. readOnly: false
  76. ---
  77. apiVersion: v1
  78. kind: PersistentVolume
  79. metadata:
  80. name: pv005
  81. namespace: kube-system
  82. spec:
  83. capacity:
  84. storage: 2Gi
  85. accessModes:
  86. - ReadWriteMany
  87. glusterfs:
  88. endpoints: "glusterfs-cluster"
  89. path: "redis-vol-5"
  90. readOnly: false
  91. # kubectl apply -f glusterfs-pv.yml

创建Headless service

  1. # vi redis-service.yml
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: redis-service
  6. namespace: kube-system
  7. labels:
  8. app: redis
  9. spec:
  10. ports:
  11. - name: redis-port
  12. port: 6379
  13. clusterIP: None
  14. selector:
  15. app: redis
  16. appCluster: redis-cluster
  17. # kubectl apply -f redis-service.yml

创建Redis 集群

  1. # vi redis.yml
  2. apiVersion: apps/v1beta1
  3. kind: StatefulSet
  4. metadata:
  5. name: redis-app
  6. namespace: kube-system
  7. spec:
  8. serviceName: "redis-service"
  9. replicas: 6
  10. template:
  11. metadata:
  12. labels:
  13. app: redis
  14. appCluster: redis-cluster
  15. spec:
  16. terminationGracePeriodSeconds: 20
  17. affinity:
  18. podAntiAffinity:
  19. preferredDuringSchedulingIgnoredDuringExecution:
  20. - weight: 100
  21. podAffinityTerm:
  22. labelSelector:
  23. matchExpressions:
  24. - key: app
  25. operator: In
  26. values:
  27. - redis
  28. topologyKey: kubernetes.io/hostname
  29. containers:
  30. - name: redis
  31. image: hub.cmss.com:5000/registry.paas/library/redis:5.0
  32. command:
  33. - "redis-server"
  34. args:
  35. - "--protected-mode"
  36. - "no"
  37. - "--cluster-enabled"
  38. - "yes"
  39. - "--appendonly"
  40. - "yes"
  41. resources:
  42. requests:
  43. cpu: "100m"
  44. memory: "100Mi"
  45. ports:
  46. - name: redis
  47. containerPort: 6379
  48. protocol: "TCP"
  49. - name: cluster
  50. containerPort: 16379
  51. protocol: "TCP"
  52. volumeMounts:
  53. - name: "redis-data"
  54. mountPath: "/data"
  55. volumeClaimTemplates:
  56. - metadata:
  57. name: redis-data
  58. spec:
  59. accessModes: ["ReadWriteMany"]
  60. resources:
  61. requests:
  62. storage: 2Gi
  63. # kubectl apply -f redis.yml

总共创建了6个Redis节点(Pod),其中3个将用于master,另外3个分别作为master的slave

Redis的数据存储路径使用volumeClaimTemplates声明, 其会绑定到我们先前创建的PV上

  1. # kubectl get pv -n kube-system

可以看到之前创建的6个PV都被绑定

  1. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
  2. pv000 2Gi RWX Retain Bound kube-system/redis-data-redis-app-2 1h
  3. pv001 2Gi RWX Retain Bound kube-system/redis-data-redis-app-3 1h
  4. pv002 2Gi RWX Retain Bound kube-system/redis-data-redis-app-4 1h
  5. pv003 2Gi RWX Retain Bound kube-system/redis-data-redis-app-5 1h
  6. pv004 2Gi RWX Retain Bound kube-system/redis-data-redis-app-0 1h
  7. pv005 2Gi RWX Retain Bound kube-system/redis-data-redis-app-1 1h

初始化Redis集群

为了方便redis-trib的使用, 可以创建 /usr/local/bin/redis-trib 文件

  1. #!/bin/bash
  2. /usr/bin/docker run -it --privileged --rm \
  3. --net=host \
  4. redis-trib:latest \
  5. "$@"
  6. # chmod 777 /usr/local/bin/redis-trib
  7. 直接使用
  8. # redis-trib
  9. Usage: redis-trib <command> <options> <arguments ...>
  10. create host1:port1 ... hostN:portN
  11. --replicas <arg>
  12. check host:port
  13. info host:port
  14. fix host:port
  15. --timeout <arg>
  16. reshard host:port
  17. --from <arg>
  18. --to <arg>
  19. --slots <arg>
  20. --yes
  21. --timeout <arg>
  22. --pipeline <arg>
  23. rebalance host:port
  24. --weight <arg>
  25. --auto-weights
  26. --use-empty-masters
  27. --timeout <arg>
  28. --simulate
  29. --pipeline <arg>
  30. --threshold <arg>
  31. add-node new_host:new_port existing_host:existing_port
  32. --slave
  33. --master-id <arg>
  34. del-node host:port node_id
  35. set-timeout host:port milliseconds
  36. call host:port command arg arg .. arg
  37. import host:port
  38. --from <arg>
  39. --copy
  40. --replace
  41. help (show this help)
  42. For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

查看起的应用

  1. # kubectl get po -n kube-system -o wide |grep redis
  2. redis-app-0 1/1 Running 0 53s 10.222.98.88 paasm3
  3. redis-app-1 1/1 Running 0 50s 10.222.88.205 paasm2
  4. redis-app-2 1/1 Running 0 47s 10.222.65.206 paasm1
  5. redis-app-3 1/1 Running 0 45s 10.222.92.210 paasing
  6. redis-app-4 1/1 Running 0 41s 10.222.66.47 paashar
  7. redis-app-5 1/1 Running 0 38s 10.222.88.206 paasm2

利用redis-trib创建集群

添加 master 节点

  1. # redis-trib create --replicas 1 \
  2. 10.222.98.90:6379 \
  3. 10.222.88.208:6379 \
  4. 10.222.65.208:6379 \
  5. 10.222.92.213:6379 \
  6. 10.222.66.49:6379 \
  7. 10.222.88.209:6379

replicas 1的意思,就是每个节点创建1个副本(即:slave)

创建用于访问Service

前面我们创建了用于实现StatefulSet的Headless Service,但该Service没有Cluster Ip,因此不能用于外界访问。所以,我们还需要创建一个Service,专用于为Redis集群提供访问和负载均:

  1. # vi redis-access-service.yml
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: redis-access-service
  6. namespace: kube-system
  7. labels:
  8. app: redis
  9. spec:
  10. ports:
  11. - name: redis-port
  12. protocol: "TCP"
  13. port: 6379
  14. targetPort: 6379
  15. selector:
  16. app: redis
  17. appCluster: redis-cluster
  18. # kubectl apply -f redis-access-service.yml
  19. # kubectl get svc -n kube-system |grep redis-access
  20. redis-access-service ClusterIP 10.233.11.2 <none> 6379/TCP 16h

此时在k8s集群中可以通过10.233.11.2:6379 访问redis

检查集群状态

  1. # redis-trib check 10.233.11.2:6379
  2. M: 7a2984e16a9911296918822eea625e9d69e5d062 10.233.11.2:6379
  3. slots:5461-10922 (5462 slots) master
  4. 1 additional replica(s)
  5. S: 38e2c1e93aa3fc792b0c1ae4c7c9fe71a6713a0f 10.222.66.49:6379
  6. slots: (0 slots) slave
  7. replicates 7a2984e16a9911296918822eea625e9d69e5d062
  8. S: 9f13a91cdc81f102f1f05ef4ac7ecfd7019ea1ca 10.222.88.209:6379
  9. slots: (0 slots) slave
  10. replicates fe586bc12346bd26548f9dc909ff9c2309b6db0a
  11. M: fe586bc12346bd26548f9dc909ff9c2309b6db0a 10.222.65.208:6379
  12. slots:10923-16383 (5461 slots) master
  13. 1 additional replica(s)
  14. S: 7d8f97ab405c1cb281f19feaba439b05f7e51709 10.222.92.213:6379
  15. slots: (0 slots) slave
  16. replicates c275b4cd089b000c70bcf21f6fb6f6a6f3dbb0a3
  17. M: c275b4cd089b000c70bcf21f6fb6f6a6f3dbb0a3 10.222.98.90:6379
  18. slots:0-5460 (5461 slots) master
  19. 1 additional replica(s)
  20. [OK] All nodes agree about slots configuration.
  21. >>> Check for open slots...
  22. >>> Check slots coverage...
  23. [OK] All 16384 slots covered.

参考: https://www.jianshu.com/p/65c4baadf5d9

发表评论

表情:
评论列表 (有 0 条评论,594人围观)

还没有评论,来说两句吧...

相关阅读