记录一下近期实现的在k8s上搭建redis集群的过程
1、新建存储类
 主要是为了和其它服务的存储类区分一下
 redis-beta-storage
 
 2、编写configMap
 redis启动时从configMap中读取配置
 
 bind:默认的127.0.0.1可能会导致其它ip地址无法远程访问,因此修改为0.0.0.0
 append only: 开启持久化存储模式,为存储提供更好的保护
 protected-mode:设置为no 允许其它机器访问
 requirepass: 设置密码
3、创建headless-service
 headless-service用于有状态应用的场景
-  headless service和普通service的区别 
 headless不分配clusterIp
 headless service通过解析service的DNS,返回所有pod的地址和dns
 普通service只能通过解析service的dns,返回service的clusterIp
-  statefulSet和Deployment的区别 
 statefulSet下的pod有DNS地址,通过解析pod的dns可以返回pod的ip
 deployment的pod是没有dns的
-  为什么要使用headless + statefulSet的组合 
 第一种:client想要自己决定使用哪个real server,通过dns可以得到real server的信息
 第二种:headless-service关联的每个pod都有自己的dns域名,因此pod可以相互访问,像redis这样集群间需要协作、选举的就需要这样的pod
 由于statefulset中的pod保持有不变的podName dnsName 因此拥有稳定的网络标识
kind: Service
apiVersion: v1
metadata:name: redis-cluster-servicenamespace: tool-betalabels:app: redis-clusterannotations:kubesphere.io/creator: admin
spec:ports:- name: redis-portprotocol: TCPport: 6379targetPort: 6379selector:app: redis-clusterclusterIP: NoneclusterIPs:- Nonetype: ClusterIPsessionAffinity: NoneipFamilies:- IPv4ipFamilyPolicy: SingleStackinternalTrafficPolicy: Cluster
4、部署redis statefulset 共6个
kind: StatefulSet
apiVersion: apps/v1
metadata:name: redis-clusternamespace: tool-betalabels:app: redis-clusterannotations:kubesphere.io/creator: admin
spec:replicas: 6selector:matchLabels:app: redis-clustertemplate:metadata:creationTimestamp: nulllabels:app: redis-clusterannotations:kubesphere.io/creator: adminkubesphere.io/restartedAt: '2024-03-26T06:49:20.735Z'spec:volumes:- name: redis-confconfigMap:name: redis-cluster-config-betadefaultMode: 420containers:- name: redisimage: 'redis:5.0.7'command:- sh- '-c'- redis-server /usr/local/redis/redis.confargs:- '--protected-mode'- 'no'ports:- name: rediscontainerPort: 6379protocol: TCP- name: clustercontainerPort: 16379protocol: TCPresources:limits:cpu: '2'memory: 4000Mirequests:cpu: 100mmemory: 500MivolumeMounts:- name: redis-confmountPath: /usr/local/redis/redis.confsubPath: redis.conf- name: redis-datamountPath: /var/lib/redisterminationMessagePath: /dev/termination-logterminationMessagePolicy: FileimagePullPolicy: IfNotPresentrestartPolicy: AlwaysterminationGracePeriodSeconds: 30dnsPolicy: ClusterFirstnodeSelector:env_type: betagroup_name: toolsecurityContext: {}affinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:topologyKey: kubernetes.io/hostnameschedulerName: default-schedulervolumeClaimTemplates:- kind: PersistentVolumeClaimapiVersion: v1metadata:name: redis-datacreationTimestamp: nullspec:accessModes:- ReadWriteManyresources:requests:storage: 1GistorageClassName: redis-beta-storagevolumeMode: Filesystemstatus:phase: PendingserviceName: redis-cluster-servicepodManagementPolicy: OrderedReadyupdateStrategy:type: RollingUpdaterollingUpdate:partition: 0revisionHistoryLimit: 10全部启动完成后,查看pod的状态
 命令 kubectl get pods -n 【namespace】
 
 查看pvc的情况
 kubectl get pvc -n 【namespace】
 
 查看pod的dns域名
 kubectl exec redis-cluster-0 -n tool-beta – hostname -f
 
 每个pod都会得到集群内的一个dns域名,格式为
 $(podname).$(service name).$(namespace).svc.cluster.local
 也可以通过临时启动一个pod来验证
kubectl run --rm -i --tty busybox --image=busybox:1.28 /bin/sh
$ nslookup redis-app-0.redis-service

 证明pod间可以解析该dns域名
若Redis Pod迁移或是重启(我们可以手动删除掉一个Redis Pod来测试),IP是会改变的,但是Pod的域名、SRV records、A record都不会改变。
5、初始化redis集群
 使用redis-cli来进行集群的初始化
首先查看各pod的ip
 
 进入到其中一个容器中
 
 使用命令创建集群
redis-cli --cluster create 192.168.5.127:6379 192.168.135.199:6379 192.168.5.112:6379 -a foobared
得到的信息类似于

 这些master节点的id用来添加slave节点
redis-cli --cluster add-node 10.168.235.225:6379 10.168.235.196:6379 --cluster-slave --cluster-master-id bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 -a foobared
依次给所有master节点添加好子节点后,查看集群情况
 进入redis-cli,输入命令cluster info
 
 cluster nodes

 写入数据、读取数据
注:集群模式需要redis-cli -c进入
 
 可以看到存储和读取时切换至其它节点
最后重启某个pod,验证是否还能组成集群

 可以看到,即使ip发生了变化,依然组成了集群
这是因为每个node的id是不变了,无论pod如何重启,只要nodeId还在持久卷里存储着,它的网络标识就没有变化