1. 程式人生 > >在k8s的3個node上部署redis cluster

在k8s的3個node上部署redis cluster

目的
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容器

微信截圖1_20170725101321.png

使用以下編寫好的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

微信截圖2_20170725115307.png

這時vm3上,由redis cluster自動恢復vm3slave2(6380) ---> master2(6380) 提升為master,叢集工作正常,業務不中斷。

恢復關掉的的機器

當我們重新啟動vm2, 這時候叢集的狀態:

微信截圖3_20170725142540.png

這時叢集工作正常,此時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

叢集自動恢復,變成下面的狀態。

微信截圖4_20170725162254.png

叢集工作正常,業務不中斷。

作者後話

以上的操作,目的是讓各臺虛擬上不出現有2個master。當其中一臺虛擬機器出現當機,叢集就不能正常工作.。如果是3臺master和3臺slave分別在不同的機器剛好錯開,redis cluster能自動恢復.。最好的解決方案,依然是有6臺虛擬機器、3臺master、3臺slave的redis cluster。

To do

我們可以進⼀一步將

1.create-redis.sh 
2.failover.sh 
3.kubectl

製作為映象, k8s deployment運行此映象。實現:

1.建立叢集
2.恢復叢集的自動修復功能(任意關掉其中一臺伺服器,業務不中斷。每過一秒,檢查叢集中是否有slave需要提升許可權,叢集都能正常工作.業務不中斷。)