记录一下近期实现的在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还在持久卷里存储着,它的网络标识就没有变化