在Kubernetes的3個node上部署redis cluster_Kubernetes中文社群
目的
redis clustor 需要6臺伺服器才能正常運⾏,由於種種原因,開發或者某些特別的需求,只能在3臺伺服器上運⾏redis clustor。在不使用哨兵模式情況下,而使⽤最新的clustor模式運行redis。
本文僅作為redis部署方式的研究及理解
準備工作
製作redis docker.latest映象其中包含以下元件:
1. redis-cli
2. ruby
3. redis-trib
打包到映象上傳到阿里映象伺服器中cluster-redis:latest
建立叢集操作
3臺伺服器上各自運行兩個redis容器
使用以下編寫好的redis-cluster部署檔案,可在一臺部署出兩個不同埠,不同角⾊的redis容器。
redis-cluster.yaml
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: redis-blue labels: app: redis member: redis-blue spec: replicas: 3 template: metadata: labels: app: redis member: redis-blue spec: hostNetwork: true containers: - name: redis image: registry.cn-hangzhou.aliyuncs.com/wise2c/cluster-redis:latest command: ["/bin/sh", "-c"] args: ["echo 'dir /tmp/data' >> /root/redis.conf && /usr/local/bin/redis-server /root/redis.conf"] #- /usr/local/bin/redis-server #- /root/redis.conf ports: - name: redis-port containerPort: 6379 - name: cluster-port containerPort: 16379 volumeMounts: - mountPath: /tmp/data name: data volumes: - name: data hostPath: path: /tmp/redis-blue --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: redis-green labels: app: redis member: redis-green spec: replicas: 3 template: metadata: labels: app: redis member: redis-green spec: hostNetwork: true containers: - name: redis image: registry.cn-hangzhou.aliyuncs.com/wise2c/cluster-redis:latest command: ["/bin/sh", "-c"] args: ["sed -i 's/6379/6380/g' /root/redis.conf && echo 'dir /tmp/data' >> /root/redis.conf && /usr/local/ports: - name: redis-port containerPort: 6380 - name: cluster-port containerPort: 16380 volumeMounts: - mountPath: /tmp/data name: data volumes: - name: data hostPath: path: /tmp/redis-green
kubectl create -f redis-cluster.yaml
執行以下指令碼,創建出整個redis叢集。redis會自動分配雜湊槽,使得master與其對應的slave不會出現在同一臺伺服器上。
create_cluster.sh
#!/usr/bin/env bash redis_count=`kubectl get pod -o wide -l app=redis | grep Running | wc -l` #echo "redis_count:"$redis_count if [ $redis_count -ne 6 ]; then echo "the running redis count: ${redis_count} is error" exit 1 fi redis_blue_ips=`kubectl get pod -o wide -l app=redis -l member=redis-blue | awk 'NR>1{printf $6":6379 "}' redis_green_ips=`kubectl get pod -o wide -l app=redis -l member=redis-green | awk 'NR>1{printf $6":6380 "}' redis_ips=$redis_blue_ips" "$redis_green_ips echo "redis_ips:"$redis_ips redis_blue_name=`kubectl get pod -o wide -l app=redis -l member=redis-blue | grep Running | awk '{printf $1" "}' #echo $redis_ips | awk -F' ' '{for( i=1;i<NF; i++ ) print $i}' `` kubectl create -f redis-cluster.yaml bash create_cluster.sh
關掉其中一臺機器 由於master和slave 不在同一臺機器上,當我們直接關掉其中⼀一臺vm,比如vm2
這時vm3上,由redis cluster自動恢復vm3slave2(6380) —> master2(6380) 提升為master,叢集工作正常,業務不中斷。
恢復關掉的的機器
當我們重新啟動vm2, 這時候叢集的狀態:
這時叢集工作正常,此時vm3有2個master。如果我們關掉vm3,會讓叢集中2個master同時下線,導致叢集無法自動恢復。
重點:執行以下指令碼,提升slave2到master2,恢復叢集的自動修復功能。
failover.sh
#!/usr/bin/env bash redis_blue_name=`kubectl get pod -o wide -l app=redis -l member=redis-blue | grep Running | awk '{printf $1":6379 redis_names=`kubectl get pod -o wide -l app=redis -l member=redis-blue | grep Running | awk '{printf $1","}' redis_array=${redis_names//,/ } for redis_name in $redis_array do kubectl exec -it ${redis_name} -- redis-cli cluster failover done
bash failover.sh
叢集自動恢復,變成下面的狀態。
叢集工作正常,業務不中斷。
作者後話
以上的操作,目的是讓各臺虛擬上不出現有2個master。當其中一臺虛擬機器出現當機,叢集就不能正常工作.。如果是3臺master和3臺slave分別在不同的機器剛好錯開,redis cluster能自動恢復.。最好的解決方案,依然是有6臺虛擬機器、3臺master、3臺slave的redis cluster。
To do
我們可以進⼀一步將
- create-redis.sh
- failover.sh
- kubectl
製作為映象, k8s deployment運行此映象。實現:
- 建立叢集
- 恢復叢集的自動修復功能(任意關掉其中一臺伺服器,業務不中斷。每過一秒,檢查叢集中是否有slave需要提升許可權,叢集都能正常工作.業務不中斷。)