hello云胜

技术与生活

0%

固定IP搭建redis集群方案二

固定IP搭建redis集群方案二

在方案一中我们使用statefuset的6个副本,固定在6个ip的ip池中。

但是仍然会有IP绑定变换的问题,虽然测试效果显示集群整体功能不受影响,但是谨慎起见,我仍然有些不放心。

既然我们可以给pod绑定ip了,那么我直接编写6个deployment,每个deployment使用1个副本,并且直接写死ip。

应该就可以搭建出完全固定ip的容器化redis-cluster方案。

建一个ippool

给redis容器专门建一个大的IPpool。以后业务申请的redis ip全部从这里分配

1
2
3
4
5
6
7
8
9
10
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: redis-ippool
spec:
blockSize: 26
cidr: 10.10.0.0/20
ipipMode: Always
natOutgoing: true

image-20230718100213762

blockSize 设置为26。那么这个k8s集群可以容纳64个主机,足够了。每个ip段是64个ip。

1
2
3
4
[root@paas-m-k8s-master-1 calico]# calicoctl get ippool
NAME CIDR SELECTOR
default-ipv4-ippool 100.64.0.0/10 all()
redis-ippool 10.10.0.0/20 all()

建6个deployment

举一个例子,其余5个类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc-0
namespace: redis-test
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: nfs-client
volumeMode: Filesystem
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: redis-test
name: redis-cluster-0
labels:
app: redis-cluster-0
spec:
replicas: 1
selector:
matchLabels:
app: redis-cluster-0
template:
metadata:
labels:
app: redis-cluster-0
annotations:
"cni.projectcalico.org/ipAddrs": "[\"10.10.0.1\"]"
spec:
volumes:
- name: redis-data
persistentVolumeClaim:
claimName: redis-pvc-0
- name: config
configMap:
name: redis-config
containers:
- name: redis
image: redis:5.0.5-alpine
command:
- "sh"
- "-c"
- "redis-server /data/conf/redis.conf"
ports:
- containerPort: 6379
name: client
- containerPort: 16379
name: gossport
resources:
limits:
cpu: "1"
volumeMounts:
- name: redis-data
mountPath: /data/data
- name: config
mountPath: /data/conf

全部创建出来

1
2
3
4
5
6
kc apply -f redis-deploy-0.yaml
kc apply -f redis-deploy-1.yaml
kc apply -f redis-deploy-2.yaml
kc apply -f redis-deploy-3.yaml
kc apply -f redis-deploy-4.yaml
kc apply -f redis-deploy-5.yaml

image-20230718113151524

全部启动成功,然后组成集群

1
kubectl -n redis-test exec -it redis-cluster-0-77dbcddbb8-w29hm -- redis-cli --cluster create --cluster-replicas 1 -a 123456 10.10.0.1:6379 10.10.0.2:6379 10.10.0.3:6379 10.10.0.4:6379 10.10.0.5:6379 10.10.0.6:6379 

完成。

测试

image-20230718113748035

全部删除deploy后重新部署deploy

image-20230718144518127

一切正常。

测试单个master宕机,主备切换也没问题。

现在的问题

现在的问题是,我发现所有的pod都分配在同一台node上,这是因为我们在分配ip时,是连续使用的,这个ip段都是在这一台node节点上。

calico根据blockSize给每个node分配地址段。

1
2
blockSize: 26
cidr: 10.10.0.0/20

这里我们用的blockSize是26位,所以每个ip段是64个ip。

我这个测试k8s,node节点只有2个,node5和node6

现在用了10.10.10.1~6左右的ip都落在了node6上,可以看到calico建了一条路由,10.10.0.0,掩码255.255.255.192

都到node6上

image-20230718160117696

我们创建一个ip是10.10.0.100的看下

image-20230718161122335

还是落在node6

建了一个10.10.15.254试试

image-20230718161212654

终于落到node5

现在的路由表

image-20230718161312683

关于calico的ip分配

Calico分配IP地址的原则为,将整个IPPool分为多个地址块,每个Node获得一个Block

在Calico默认的使用模式中,Calico每个Node一个分配一个Block,每个Block默认为64个IP,当单个Node启动的Pod超过64时,才会分配下一个Block。

因为现在我测试环境只有两个node,所以,如果我使用下面的ippool配置

1
2
blockSize: 21
cidr: 11.11.0.0/20

那么就只能分出2个block,正好一个node一个。

每个block里有2^11个ip。2048

image-20230718163605930

起两个nginx镜像测试下路由分配。

image-20230718163812076

image-20230718163851450

可以看到这条路由的掩码是21位

image-20230718164248652

所以下一个block可用ip是11.11.8.1

然而很可惜,下一个block,也分配给了node5

image-20230718165556227

查了一下,calico分配block有一个Block affinity亲和性策略,不好把握。

看3.24版本的calico开始可以配置Block affinity。但是我的calico版本还不支持。

目前研究到这里。

总结

这个方案的问题在于,ip和node节点绑死了,如果按照递增的方式来分配redis的ip,将导致所有的redis节点全部部署在一个node上,一旦node宕机,这些pod无法在其他node拉起,这样失去了k8s调度的意义。

如果想采用将ip block分配到不同的机器,再从这些block中选ip的方式,其操作很难控制。

所以,我认为这个方案也不好。

现在我觉得固定ip和ip地址池的方案都不好。。。