准备存储环境
~# apt install nfs-server
~# mkdir -pv /data/redisCluster/{redis0,redis1,redis2,redis3,redis4,redis5}
~# vim /etc/exports
/data/redisCluster *(rw,no_root_squash)
~# exportfs -arv
创建pv
redis-cluster-pv.yaml资源清单文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: redis-cluster-pv0
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
server: 192.168.2.131
path: /data/redisCluster/redis0
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: redis-cluster-pv1
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
server: 192.168.2.131
path: /data/redisCluster/redis1
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: redis-cluster-pv2
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
server: 192.168.2.131
path: /data/redisCluster/redis2
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: redis-cluster-pv3
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
server: 192.168.2.131
path: /data/redisCluster/redis3
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: redis-cluster-pv4
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
server: 192.168.2.131
path: /data/redisCluster/redis4
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: redis-cluster-pv5
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
server: 192.168.2.131
path: /data/redisCluster/redis5
~# kubectl apply -f redis-cluster-pv.yaml #创建pv
~# kubectl get pv #验证
部署redis cluster
准备配置文件
appendonly yes
cluster-enabled yes
cluster-config-file /var/lib/redis/nodes.conf
cluster-node-timeout 5000
dir /var/lib/redis
port 6379
databases 16
pidfile /var/run/redis.pid
logfile "redis.log"
protected-mode no
masterauth "123456"
requirepass "123456"
loglevel notice
always-show-logo no
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
replica-serve-stale-data yes
replica-read-only yes
cluster-node-timeout 15000
cluster-migration-barrier 1
cluster-require-full-coverage no
基于配置文件创建configmap
~# kubectl create configmap redis-conf --from-file=redis.conf -n redis-cluster
~# kubectl get configmap -n redis-cluster
创建redis cluster
redis.yaml资源清单:
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: redis-cluster
labels:
app: redis
spec:
selector:
app: redis
appCluster: redis-cluster
ports:
- name: redis
port: 6379
clusterIP: None
---
apiVersion: v1
kind: Service
metadata:
name: redis-access
namespace: redis-cluster
labels:
app: redis
spec:
selector:
app: redis
appCluster: redis-cluster
ports:
- name: redis-access
protocol: TCP
port: 6379
targetPort: 6379
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: redis-cluster
spec:
serviceName: redis
replicas: 6
selector:
matchLabels:
app: redis
appCluster: redis-cluster
template:
metadata:
labels:
app: redis
appCluster: redis-cluster
spec:
terminationGracePeriodSeconds: 20
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- redis
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7.0.4
command:
- "redis-server"
args:
- "/etc/redis/redis.conf"
- "--protected-mode"
- "no"
resources:
requests:
cpu: "500m"
memory: "500Mi"
ports:
- containerPort: 6379
name: redis
protocol: TCP
- containerPort: 16379
name: cluster
protocol: TCP
volumeMounts:
- name: conf
mountPath: /etc/redis
- name: data
mountPath: /var/lib/redis
volumes:
- name: conf
configMap:
name: redis-conf
items:
- key: redis.conf
path: redis.conf
volumeClaimTemplates:
- metadata:
name: data
namespace: redis-cluster
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 5Gi
~# kubectl apply -f redis.yaml
~# kubectl get pod -n redis-cluster
pod创建完成
root@ubuntu01:~# kubectl get pod -n redis-cluster
NAME READY STATUS RESTARTS AGE
redis-0 1/1 Running 2 (13h ago) 18h
redis-1 1/1 Running 2 18h
redis-2 1/1 Running 2 (13h ago) 18h
redis-3 1/1 Running 2 (13h ago) 18h
redis-4 1/1 Running 2 (13h ago) 18h
redis-5 1/1 Running 2 (13h ago) 18h
pvc绑定完成
root@ubuntu01:~# kubectl get pvc -n redis-cluster
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-redis-0 Bound redis-cluster-pv3 5Gi RWO 19h
data-redis-1 Bound redis-cluster-pv5 5Gi RWO 19h
data-redis-2 Bound redis-cluster-pv0 5Gi RWO 19h
data-redis-3 Bound redis-cluster-pv1 5Gi RWO 19h
data-redis-4 Bound redis-cluster-pv4 5Gi RWO 18h
data-redis-5 Bound redis-cluster-pv2 5Gi RWO
初始化redis cluster
~# kubectl run -it redis-cluster-init --image=redis:7.0.4 --restart=Never -n redis-cluster bash
#进入pod执行以下命令:
~# apt update #更新apt源
~# apt-get install dnsutils -y #安装dig命令,用来获取podIP
~# redis-cli --cluster create `dig +short redis-0.redis.redis-cluster.svc.cluster.local`:6379 `dig +short redis-1.redis.redis-cluster.svc.cluster.local`:6379 `dig +short redis-2.redis.redis-cluster.svc.cluster.local`:6379 `dig +short redis-5.redis.redis-cluster.svc.cluster.local`:6379 `dig +short redis-3.redis.redis-cluster.svc.cluster.local`:6379 `dig +short redis-4.redis.redis-cluster.svc.cluster.local`:6379 --cluster-replicas 1
注意:使用statefulset + headless 会生成集群内唯一的pod域名,其格式为:podName.serviceName.namespace.svc.cluster.local
集群验证
root@ubuntu01:~# kubectl get pod -n redis-cluster -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis-0 1/1 Running 2 (13h ago) 19h 10.200.79.61 192.168.2.132 <none> <none>
redis-1 1/1 Running 2 19h 10.200.38.191 192.168.2.133 <none> <none>
redis-2 1/1 Running 2 (13h ago) 19h 10.200.79.50 192.168.2.132 <none> <none>
redis-3 1/1 Running 2 (13h ago) 19h 10.200.38.144 192.168.2.133 <none> <none>
redis-4 1/1 Running 2 (13h ago) 18h 10.200.79.10 192.168.2.132 <none> <none>
redis-5 1/1 Running 2 (13h ago) 18h 10.200.38.139 192.168.2.133 <none> <none>
redis-cluster-init 1/1 Running 0 10h 10.200.79.7 192.168.2.132 <none> <none>
root@redis-0:/data# redis-cli --cluster check 10.200.38.191:6379
10.200.38.191:6379 (cf7bd4a4...) -> 0 keys | 5462 slots | 1 slaves.
10.200.38.144:6379 (ab8f790a...) -> 0 keys | 5461 slots | 1 slaves.
10.200.38.139:6379 (90e3178c...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 10.200.38.191:6379)
M: cf7bd4a4d27b1de53d581930e7c8139145e271a4 10.200.38.191:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: ab8f790ab44f41c112a5e9189e38635965363687 10.200.38.144:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 90e3178ca88349a389a4749fce0b5073c9c44405 10.200.38.139:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: a4b70516bbe449b1b31b552e521e4c4601010b20 10.200.79.61:6379
slots: (0 slots) slave
replicates ab8f790ab44f41c112a5e9189e38635965363687
S: a83cd857f6c1cc200af187e5b5f43629c2470fee 10.200.79.50:6379
slots: (0 slots) slave
replicates 90e3178ca88349a389a4749fce0b5073c9c44405
S: 7ecfb358c3974fbb5169f4cab663684a9655e453 10.200.79.10:6379
slots: (0 slots) slave
replicates cf7bd4a4d27b1de53d581930e7c8139145e271a4
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
10.200.38.191:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.200.79.10,port=6379,state=online,offset=43486,lag=1
master_failover_state:no-failover
master_replid:3a690e738cf825af8a2e2daef663f4acfcb74e60
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:43486
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:43486
10.200.38.191:6379> set key1 value1
OK
10.200.38.191:6379> get key1
"value1"
#故障验证,停止191的redis服务
redis-cli shutdown
#确认服务已停止
root@ubuntu01:~# redis-cli -h 10.200.38.191 -p 6379
Could not connect to Redis at 10.200.38.191:6379: Connection refused
#在191的slave节点10上查看,可以发现已经能够正常查询,表示主从切换正常
10.200.79.10:6379> get key1
"value1"