hello云胜

技术与生活

0%

固定PODIP

相比于在服务器上部署redis cluster,在k8s环境下的部署redis cluster的主要困难点就在于POD的IP重启会改变。

redis组织运行cluster强依赖于ip。所以我们必须解决redis ip变化的问题。

之前的部署文档

k8s中部署redis集群 (qq.com)

曾经写过一个方案,使用fix-ip.sh脚本。在pod重启时,将自己之前生成的nodes.conf文件中myself的ip改成新的。

其他活着的pod能够自动将这个重启的pod更新成新的ip。

不过这种方案有一个致命的问题:只能处理一个pod重启的情况,如果有多个pod或者k8s集群故障导致整个redis集群重启,

那么redis cluster是无法自己恢复的,表现为redis cluster整体故障,并且手工也很难恢复。在生产上不可接受。

那么就换另一个思路,能不能保持pod的ip是固定的,这样就解决了pod重启ip变化的问题。

答案是肯定的,k8s支持对pod保持固定ip。但是需要我们来人工进行干预配置。

我的k8s集群之前搭建时使用的网络插件是calico。所以使用calico的配置方案。

下载calicoctl工具

1
2
3
curl -O -L  https://github.com/projectcalico/calicoctl/releases/download/v3.18.4/calicoctl
chmod +x calicoctl
cp calicoctl /usr/local/bin/

创建地址池

查看一下calico的配置文件

1
cat  /etc/cni/net.d/10-calico.conflist

看一下ipam是不是calico-ipam。(IPAM是k8s cni插件中负责分配ip的一类插件)

不是的话先改成这个。

image-20230711173949619

calico默认会创建一个cidr

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

这是calico在启动pod时默认进行分配的ip地址池。

然后我们可以创建自己的地址池。

因为我们搭建3主3从的集群,需要6个ip。所以可以创建1个掩码为30位的地址池,其可用ip正好是4个

再加一个31位掩码的地址池,其可用ip是2个。

(calico分配ip时,全0和全1的ip是可用的)

1
2
3
4
5
6
7
8
9
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: redis-ippool1
spec:
blockSize: 31
cidr: 11.11.11.0/30
ipipMode: Always
natOutgoing: true

image-20230717165134495

1
2
3
4
5
6
7
8
9
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: redis-ippool1
spec:
blockSize: 31
cidr: 11.11.11.4/31
ipipMode: Always
natOutgoing: true

image-20230717165120545

1
2
3
4
5
6
7
[root@paas-m-k8s-master-1 calico]# calicoctl apply -f ippool1.yaml
[root@paas-m-k8s-master-1 calico]# calicoctl apply -f ippool2.yaml
[root@paas-m-k8s-master-1 calico]# calicoctl get ippool
NAME CIDR SELECTOR
default-ipv4-ippool 100.64.0.0/10 all()
redis-ippool1 11.11.11.0/30 all()
redis-ippool2 11.11.11.4/31 all()

对之前的redis部署资源文件进行改造

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
61
62
63
64
65
66
67
68
69
70
71
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: redis-test
name: redis-cluster-static-ip
spec:
serviceName: redis-cluster-static-ip
replicas: 6
selector:
matchLabels:
app: redis-cluster-static-ip
template:
metadata:
labels:
app: redis-cluster-static-ip
# 增加这个注解
annotations:
#可以配置多个,逗号隔开
"cni.projectcalico.org/ipv4pools": "[\"redis-ippool1\",\"redis-ippool2\"]"
spec:
containers:
- name: redis
image: redis:5.0.5-alpine
ports:
- containerPort: 6379
name: client
- containerPort: 16379
name: gossport
# 不再使用fix-ip.sh
command: ["redis-server", "/data/conf/redis.conf"]
### 就绪指针探测
readinessProbe:
exec:
command:
- sh
- -c
- "redis-cli -h $(hostname) ping"
initialDelaySeconds: 15
timeoutSeconds: 5
livenessProbe:
exec:
command:
- sh
- -c
- "redis-cli -h $(hostname) ping"
initialDelaySeconds: 20
periodSeconds: 3

volumeMounts:
- name: config
mountPath: /data/conf
readOnly: false
- name: data
mountPath: /data/data
readOnly: false
volumes:
- name: config
configMap:
name: redis-config
defaultMode: 0755
volumeClaimTemplates:
- metadata:
name: data
annotations:
volume.beta.kubernetes.io/storage-class: "nfs-client"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi

部署

1
2
[root@paas-m-k8s-master-1 calico]# kubectl apply -f redis-sts-ippool.yaml
statefulset.apps/redis-cluster created

image-20230717171615011

组成集群

1
kubectl -n redis-test exec -it redis-cluster-static-ip-0 -- redis-cli --cluster create --cluster-replicas 1 -a 123456 $((kubectl -n redis-test get pods -l app=redis-cluster-static-ip -o jsonpath='{range.items[*]}{.status.podIP}:6379 ') | awk '{print $1" "$2" "$3" "$4" "$5" "$6" "}')

image-20230717171928812

可靠性测试

现在通过ip池限制了6个ip,但是这6个ip在6个pod之间是随机分配的。

如果6个pod全部重启,重新打乱ip的分配。集群是否可用?

当前的cluster nodes

image-20230717172126526

删除sts,模拟pod全部重启

1
2
3
[root@paas-m-k8s-master-1 calico]# kc -n redis-test delete sts redis-cluster-static-ip
[root@paas-m-k8s-master-1 calico]# kc -n redis-test get pod
[root@paas-m-k8s-master-1 calico]# kc apply -f redis-sts-ippool.yaml

image-20230717172818158

pod 3和5的ip换了

image-20230717172951710

测试redis集群是可用的。

总结,通过实验,该方案较以前的方案来说更加可靠。

(208条消息) Kubernetes 固定 Pod IP 地址方法_k8s如何固定pod的ip_-WF的博客-CSDN博客

(208条消息) Kubernetes 部署 Redis-Cluster_k8s部署redis集群ip变化就用不了怎么解决_-WF的博客-CSDN博客