前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >kubernetes-20:redis-cluster容器化

kubernetes-20:redis-cluster容器化

作者头像
千里行走
发布2019-11-30 14:44:51
1.3K0
发布2019-11-30 14:44:51
举报
文章被收录于专栏:千里行走千里行走

目录:

(1).redis容器化

1.容器化redis-cluster各个节点实例

2.初始化redis-cluster集群

3.集群节点文件说明

3.1.appendonly.aof

3.2.dump.rdb

3.3.PDB和AOF的优先级

3.4.nodes.conf

(2).容器重启导致节点ip变化的问题解决

2.1.相关配置方式

2.2.整个操作过程演示

2.3.应用如何适配

(3).配置文件说明

(4).相关文章阅读

笔者使用Redis容器化只用于本地环境,用于自己一些项目的调试(https://github.com/hepyu/saf)。

故,是一个简单实现,pod亲和性等生产级别配置没有做过多考虑。

如果要生产环境容器化redis,需要考虑方方面面的问题,很长的一个过程。

(1).redis容器化

1.容器化redis-cluster各个节点实例

先执行local pv所使用的本地pv目录:

https://github.com/hepyu/k8s-app-config/blob/master/yaml/init.sh

执行命令容器化redis-cluster:sh ./deploy.sh

查看redis容器化节点实例

kubectl get all -n redis-cluster-min -o wide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES

pod/redis-hkc-0 1/1 Running 0 8d 10.244.0.108 future <none> <none>

pod/redis-hkc-1 1/1 Running 0 8d 10.244.0.109 future <none> <none>

pod/redis-hkc-2 1/1 Running 0 8d 10.244.0.110 future <none> <none>

pod/redis-hkc-3 1/1 Running 0 8d 10.244.0.111 future <none> <none>

pod/redis-hkc-4 1/1 Running 0 8d 10.244.0.112 future <none> <none>

pod/redis-hkc-5 1/1 Running 0 8d 10.244.0.113 future <none> <none>

接下来我们要做redis集群初始化,如果我们现在进入redis操作会出现什么情况呢?

我们进入其中的一个redis node中执行set, get尝试操作,会提示错误:

root@redis-hkc-0:/data# redis-cli -h 10.244.0.111 -p 9720 -c

10.244.0.111:9720>

10.244.0.111:9720> cluster info

cluster_state:fail

cluster_slots_assigned:16384

cluster_slots_ok:5461

cluster_slots_pfail:10923

cluster_slots_fail:0

cluster_known_nodes:6

cluster_size:3

cluster_current_epoch:6

cluster_my_epoch:3

cluster_stats_messages_ping_sent:1154655

cluster_stats_messages_sent:1154655

cluster_stats_messages_received:0

10.244.0.111:9720>

10.244.0.111:9720>

10.244.0.111:9720>

10.244.0.111:9720> set a 1

(error) CLUSTERDOWN The cluster is down

可以看到cluster info是可以显示cluster的信息,但是执行set/get方法时提示cluster down,这是因为我们没有完成redis-cluster的初始化。

2.初始化redis-cluster集群

我们再开一个容器进行此项操作,为此我专门制作了一个image专门用于进行redis-cluster初始化,工程位于:

https://github.com/hepyu/redis-cluster-initialize-image

(需要注意,我用的redis版本是5.x)。

git clone 后直接执行docker.build.sh完成image制作。

执行命令进入容器

kubectl run -i --tty init-redis-cluster --image=hpy253215039/redis-cluster-initialize-image:0.1 --restart=Never /bin/bash

(第二次进入执行:kubectl exec -it init-redis-cluster -- /bin/bash)

进入容器后,cd /app/3rd/redis-5.0.7/src,执行:

Redis-5.0已经舍弃了redis-trib.py的方式初始化集群,改用redis-cli初始化集群:

redis-cli --cluster create --cluster-replicas 1 10.244.0.173:9720 10.244.0.109:9720 10.244.0.110:9720 10.244.0.111:9720 10.244.0.112:9720 10.244.0.113:9720

有可能会报错:

Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

解决方式:

1)、将需要新增的节点下aof、rdb等本地备份文件删除;

2)、同时将新Node的集群配置文件删除,即:删除你redis.conf里面cluster-config-file所在的文件;

3)、再次添加新节点如果还是报错,则登录新Node,./redis-cli–h x –p对数据库进行清除:

Ip:7001> flushdb #清空当前数据库

我图省事(自己用嘛),直接删除local pv重建目录,重新容器化。

redis-cli --cluster create --cluster-replicas 1 10.244.0.184:9720 10.244.0.185:9720 10.244.0.186:9720 10.244.0.187:9720 10.244.0.188:9720 10.244.0.189:9720

可以发现IP发生变化,打印信息:

>>> Performing hash slots allocation on 6 nodes...

Master[0] -> Slots 0 - 5460

Master[1] -> Slots 5461 - 10922

Master[2] -> Slots 10923 - 16383

Adding replica 10.244.0.188:9720 to 10.244.0.184:9720

Adding replica 10.244.0.189:9720 to 10.244.0.185:9720

Adding replica 10.244.0.187:9720 to 10.244.0.186:9720

M: f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.184:9720

slots:[0-5460] (5461 slots) master

M: 150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720

slots:[5461-10922] (5462 slots) master

M: a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720

slots:[10923-16383] (5461 slots) master

S: 3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720

replicates a44ee1eaef7f89cd1013f10638d5d878dd982001

S: 699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720

replicates f8b4cc1d884eb3ced239c572e016a49cabd0313f

S: 3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720

replicates 150da7a79af740c55a61124f1d422fb9fcd19459

Can I set the above configuration? (type 'yes' to accept): yes

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join

......

>>> Performing Cluster Check (using node 10.244.0.184:9720)

M: f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.184:9720

slots:[0-5460] (5461 slots) master

1 additional replica(s)

S: 3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720

slots: (0 slots) slave

replicates 150da7a79af740c55a61124f1d422fb9fcd19459

S: 699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720

slots: (0 slots) slave

replicates f8b4cc1d884eb3ced239c572e016a49cabd0313f

M: 150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720

slots:[5461-10922] (5462 slots) master

1 additional replica(s)

S: 3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720

slots: (0 slots) slave

replicates a44ee1eaef7f89cd1013f10638d5d878dd982001

M: a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720

slots:[10923-16383] (5461 slots) master

1 additional replica(s)

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

我们使用命令行进入其中的一个节点:

[root@init-redis-cluster redis-5.0.7]# redis-cli -c -h 10.244.0.184 -p 9720

10.244.0.184:9720> get a 1

(error) ERR wrong number of arguments for 'get' command

10.244.0.184:9720> cluster info

cluster_state:ok

cluster_slots_assigned:16384

cluster_slots_ok:16384

cluster_slots_pfail:0

cluster_slots_fail:0

cluster_known_nodes:6

cluster_size:3

cluster_current_epoch:6

cluster_my_epoch:1

cluster_stats_messages_ping_sent:160

cluster_stats_messages_pong_sent:150

cluster_stats_messages_sent:310

cluster_stats_messages_ping_received:145

cluster_stats_messages_pong_received:160

cluster_stats_messages_meet_received:5

cluster_stats_messages_received:310

10.244.0.184:9720>

10.244.0.184:9720>

10.244.0.184:9720> set a 1

-> Redirected to slot [15495] located at 10.244.0.186:9720

OK

10.244.0.186:9720> get a

"1"

10.244.0.186:9720>

可以看到,集群现在处于可用状态。

3.集群节点文件说明

我们随意找一个本地存储:/datavip/k8s-data/redis-cluster-min-pv-local-0,其目录结构如下:

appendonly.aof

dump.rdb

nodes.conf

3.1.appendonly.aof

以日志的形式来记录每个写操作,将redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

这也是为什么我们在使用redis时会有一些禁手,比如:不允许用keys等操作,因为其执行时间的方差差异太大,有可能直接把整个集群堵死。笔者曾经工作的一家公司,有同学用keys,直接把redis-cluster生产集群的tps干到<1。

3.2.dump.rdb

指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际的操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储(binlog)。存储的文件为:dum.rdb

RDB需要fork子进程来进行持久化。如果数据集太大,fork系统调用可能消耗较多时间,甚至导致redis暂停服务( n ms-1s)。AOF也需要fork,但是你可以在不影响持久性的前提下控制多久重写一次日志。

3.3.PDB和AOF的优先级

Redis 4.0 之后新增的方式,混合持久化(同时开启RDB和AOF模式),是结合了 RDB 和 AOF 的优点,在写入的时候,先把当前的数据以 RDB 的形式写入文件的开头,再将后续的操作命令以 AOF 的格式存入文件,这样既能保证 Redis 重启时的速度,又能简单数据丢失的风险。

我们线上是两个都开着。

3.4.nodes.conf

查阅其内容便一目了然:

记录集群内的其他节点信息,用于通信。

例:

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720@19720 slave a44ee1eaef7f89cd1013f10638d5d878dd982001 0 1574686485562 4 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 myself,master - 0 1574686485000 2 connected 5461-10922

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.184:9720@19720 master - 0 1574686484000 1 connected 0-5460

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574686486000 3 connected 10923-16383

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574686486563 5 connected

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574686484560 6 connected

vars currentEpoch 6 lastVoteEpoch 0

第一个字段是节点 ID,一个40个字符的随机字符串,当一个节点被创建时不会再发生变化(除非CLUSTER RESET HARD被使用),所以当pod重启前我们只要nodeId对应的ip:port改掉即可,就可以保证集群的正常使用。

(2).容器重启导致节点ip变化的问题解决

2.1.相关配置方式

在redis-configmap.yaml中有这么一段脚本:

fix-ip.sh: |

#!/bin/sh

CLUSTER_CONFIG="/data/nodes.conf"

if [ -f ${CLUSTER_CONFIG} ]; then

if [ -z "${POD_IP}" ]; then

echo "Unable to determine Pod IP address!"

exit 1

fi

echo "Updating my IP to ${POD_IP} in ${CLUSTER_CONFIG}"

sed -i.bak -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${CLUSTER_CONFIG} #改

nodes.conf中本机的ip地址,因为pod每次重启后会导致ip改变。

fi

exec "$@"

这个脚本在容器启动后执行,修改当前redis节点实例的nodes.conf,将本机实例的node编号对应的ip换成新的podIP。由于nodes.conf是由redis-cluster集群维护,所以当这个节点实例启动时,redis-cluster也会将nodes.conf的本地修改同步到当前集群内的其他redis节点的nodes.conf文件,会有一个sync操作。

在redis-statefulset.yaml中的启动命令:

command: ["/conf/fix-ip.sh", "redis-server", "/conf/redis.conf"]

先执行fix-ip.sh修改nodes.conf,然后再启动redis-server,这样才能保证redis-cluster将nodes.conf的更改同步到其他节点实例。

2.2.整个操作过程演示

集群最初IP:

[root@future redis-cluster-min]# kubectl get pod -n redis-cluster-min -o wide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES

redis-hkc-0 1/1 Running 0 38h 10.244.0.192 future <none> <none>

redis-hkc-1 1/1 Running 0 39h 10.244.0.185 future <none> <none>

redis-hkc-2 1/1 Running 0 39h 10.244.0.186 future <none> <none>

redis-hkc-3 1/1 Running 0 39h 10.244.0.187 future <none> <none>

redis-hkc-4 1/1 Running 0 39h 10.244.0.188 future <none> <none>

redis-hkc-5 1/1 Running 0 39h 10.244.0.189 future <none> <none>

我们接下来选择redis-hkc-3重启,然后观察其nodes.conf文件变化,重启前,我们先进入redis-hkc-3查看一下这个实例的nodes.conf中hkc-3的node标识:

[root@future redis-cluster-min]# kubectl exec -it -n redis-cluster-min redis-hkc-3 -- /bin/bash

root@redis-hkc-3:/data# cat nodes.conf

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574688847000 3 connected 10923-16383

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.192:9720@19720 master - 1574688835599 1574688833292 1 disconnected 0-5460

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574688844318 5 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 master - 0 1574688847000 2 connected 5461-10922

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574688845000 6 connected

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720@19720 myself,slave a44ee1eaef7f89cd1013f10638d5d878dd982001 0 1574688844000 4 connected

vars currentEpoch 6 lastVoteEpoch 0

我们再进入redis-hkc-4,看一下redis-hkc-3节点的Node标识在redis-hkc-4的nodes.conf中的配置:

[root@future redis-cluster-min]# kubectl exec -it -n redis-cluster-min redis-hkc-4 -- /bin/bash

root@redis-hkc-4:/data# cat nodes.conf

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574688845431 6 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 master - 0 1574688846433 2 connected 5461-10922

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720@19720 slave a44ee1eaef7f89cd1013f10638d5d878dd982001 0 1574688847000 4 connected

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.192:9720@19720 master - 1574688835609 1574688834406 1 disconnected 0-5460

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 myself,slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574688847000 5 connected

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574688846000 3 connected 10923-16383

vars currentEpoch 6 lastVoteEpoch 0

OK,现在我们杀掉redis-hkc-3这个pod:

kubectl delete -n redis-cluster-min pod redis-hkc-3

然后查看新POD,发现redis-hkc-3的ip变成10.244.0.194:

[root@future redis-cluster-min]# kubectl get pod -n redis-cluster-min -o wide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES

redis-hkc-0 1/1 Running 0 40h 10.244.0.192 future <none> <none>

redis-hkc-1 1/1 Running 0 41h 10.244.0.185 future <none> <none>

redis-hkc-2 1/1 Running 0 41h 10.244.0.186 future <none> <none>

redis-hkc-3 1/1 Running 0 12s 10.244.0.194 future <none> <none>

redis-hkc-4 1/1 Running 0 41h 10.244.0.188 future <none> <none>

redis-hkc-5 1/1 Running 0 41h 10.244.0.189 future <none> <none>

查看redis-hkc-3的nodes.conf,可以看到对应的ip被自动修改为新IP:10.244.0.194:

[root@future redis-cluster-min]# kubectl exec -it -n redis-cluster-min redis-hkc-3 -- /bin/bash

root@redis-hkc-3:/data# cat nodes.conf

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574688847000 3 connected 10923-16383

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.192:9720@19720 master - 1574688835599 1574688833292 1 disconnected 0-5460

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574688844318 5 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 master - 0 1574688847000 2 connected 5461-10922

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574688845000 6 connected

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.194:9720@19720 myself,slave a44ee1eaef7f89cd1013f10638d5d878dd982001 0 1574688844000 4 connected

vars currentEpoch 6 lastVoteEpoch 0

查看redis-hkc-4的nodes.conf,可以看到redis-hkc-3节点对应的ip被自动修改为新IP:10.244.0.194,说明redis-hkc-3启动时,redis-cluster集群将redis-hkc-3的nodes.conf变更同步到了集群的其他节点:

[root@future redis-cluster-min]# kubectl exec -it -n redis-cluster-min redis-hkc-4 -- /bin/bash

root@redis-hkc-4:/data# cat nodes.conf

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574834074462 6 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 master - 0 1574834075000 2 connected 5461-10922

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.194:9720@19720 slave a44ee1eaef7f89cd1013f10638d5d878dd982001 1574834069654 1574834068000 4 disconnected

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.192:9720@19720 master - 0 1574834077000 1 connected 0-5460

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 myself,slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574834077000 5 connected

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574834077469 3 connected 10923-16383

vars currentEpoch 6 lastVoteEpoch 0

2.3.应用如何适配

要求应用程序初始化redis-cluster时,address中不能使用ip,要换成域名。这样即使POD重启IP反生变化,也不会波及到应用程序(其实在重启POD的过程中,对应用会有短时间影响)。

如,在本例配置下:

redis.cluster.address=redis-hkc-0.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-1.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-2.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-3.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-4.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-5.redis-hkc.redis-cluster-min.svc.cluster.local:9720

(3).配置文件说明

4个配置文件:

redis-configmap.yaml

redis-pv-local.yaml

redis-service.yaml

redis-statefulset.yaml

1.redis-configmap.yaml

主要放置fix-ip脚本(POD重启前修改nodes.conf)和redis.conf配置文件。

2.redis-pv-local.yaml

本地存储,生产云环境使用NAS云盘(要做充分性能/压力测试)。

3.redis-service.yaml

headless service。

这里的Headless Services主要是使用它作为标识每个redis-node的域名,这样应用程序直接配置6个域名和端口即可,不需要使用ip,其格式为:

$(podname).(headless server name).namespace.svc.cluster.local

即:

redis-hkc-0.redis-hkc.redis-cluster-min.svc.cluster.local:9720,其始终执行有状态下编号为1的pod,达到与PodIP的无关性。

4.redis-statefulset.yaml

主要配置文件,用于定义有状态容器:redis-cluster。

关键配置:

command: ["/conf/fix-ip.sh", "redis-server", "/conf/redis.conf"]

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 千里行走 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档