服务器资源
k8s中有三台worker节点
192.168.1.100
192.168.1.101
192.168.1.102
配置文件
创建配置字典,挂载redis的配置文件
key为redis.conf
value为:
appendonly yes
cluster-enabled yes
cluster-config-file /data/nodes.conf
cluster-require-full-coverage no
cluster-migration-barrier 1
cluster-node-timeout 60000
protected-mode no
daemonize no #让redis前台运行
port 6379
#下面的认证需要在集群搭建成功后添加,然后重启redis集群
requirepass XXX@2022 #开启密码认证
masterauth XXX@2022 #开启认证
创建redis服务
通过statefulset创建redis集群,有状态应用可以是副本之间有主从关系,数据需要做持久化。
在项目空间的 工作负载-有状态副本集-创建 进行 Redis 的创建。
基本信息定义
容器组设置,从自己的镜像仓库选择redis的版本,设置副本数为6,设置启动命令如下
存储设置,先是声明持久卷声明,再是挂载配置文件字典
PVC声明,挂载到容器的/data路径
配置文件的挂载,挂载到conf目录(依据自己使用的redis容器读取配置文件位置挂载)
创建
redis集群资源清单
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: ipaas-redis-cluster-v1
namespace: xiaoyu
labels:
app: ipaas-redis-cluster
version: v1
annotations:
kubesphere.io/creator: admin
spec:
replicas: 6
selector:
matchLabels:
app: ipaas-redis-cluster
version: v1
template:
metadata:
creationTimestamp: null
labels:
app: ipaas-redis-cluster
version: v1
annotations:
kubesphere.io/restartedAt: '2022-11-03T02:20:00.393Z'
logging.kubesphere.io/logsidecar-config: '{}'
spec:
volumes:
- name: host-time
hostPath:
path: /etc/localtime
type: ''
- name: volume-tdz1y1
configMap:
name: redis-conf
items:
- key: redis.conf
path: redis.conf
defaultMode: 420
containers:
- name: redis-cluster
image: 'harbor.leadchina.cn/ipaas/ipaas-redis:5.0.14'
command:
- redis-server
args:
- /conf/redis.conf
- '--cluster-announce-ip'
- $(POD_IP)
ports:
- name: tcp-6379
containerPort: 6379
protocol: TCP
env: #环境变量需要在yml中创建
- name: POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
resources:
limits:
cpu: 200m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
volumeMounts:
- name: host-time
mountPath: /etc/localtime
- name: redis-pvc
mountPath: /data
- name: volume-tdz1y1
mountPath: /conf
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
serviceAccountName: default
serviceAccount: default
securityContext: {}
imagePullSecrets:
- name: ipaas-repo
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: ipaas-redis-cluster
version: v1
topologyKey: kubernetes.io/hostname
schedulerName: default-scheduler
volumeClaimTemplates:
- kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: redis-pvc
namespace: ipaas
creationTimestamp: null
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: csi-rbd-sc
volumeMode: Filesystem
status:
phase: Pending
serviceName: ipaas-redis-cluster
podManagementPolicy: OrderedReady
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0
revisionHistoryLimit: 10
初始化集群
上面创建的redis副本之间并没什么关联,只是单个的redis服务,而通过容器化部署的redis不能通过副本的虚拟ip进行初始化,使用 ip
地址的方式在每次 K8s
调度 redis
后 ip
都会发生变化,所以在 K8s
集群中使用 ip
方式初始化集群并不太合适,但是如果使用内部 DNS
直接跟上面一样初始化集群会出现错误,因为 redis
对域名的支持并不太好,所以这时候可以用 Redis-tribe
。
创建部署
通过yaml创建
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: xiaoyu
labels:
app: redis-cluster-tools
name: redis-cluster-tools
spec:
replicas: 1
selector:
matchLabels:
app: redis-cluster-tools
template:
metadata:
labels:
app: redis-cluster-tools
name: pos-redis
spec:
containers:
- name: pos-redis
image: sunnywang/redis-tools-ubuntu:v0.5.1
imagePullPolicy: IfNotPresent
args:
- /bin/bash
- -c
- sleep 3600
进入到redis-cluster-tools的终端,分别进行master节点的初始化和slave节点的关联
首先进入到redis集群副本的终端查看容器的DNS
进入redis-cluster-tools的终端,先利用上面查看到的redis集群副本的DNS进行master节点的初始化
#执行以下命令初始化 master 节点,这时候之前的内部 DNS 的域名可以用了
redis-trib.py create `dig +short redis-cluster-0.redis-cluster-49ag.yek.svc.cluster.local`:6379 `dig +short redis-cluster-1.redis-cluster-49ag.yek.svc.cluster.local`:6379 `dig +short redis-cluster-2.redis-cluster-49ag.yek.svc.cluster.local`:6379
给每个master节点绑定对应的副本节点
#给master节点0绑定5
redis-trib.py replicate --master-addr `dig +short redis-cluster-0.redis-cluster-49ag.yek.svc.cluster.local`:6379 --slave-addr `dig +short redis-cluster-5.redis-cluster-49ag.yek.svc.cluster.local`:6379
#给master节点1绑定3
redis-trib.py replicate --master-addr `dig +short redis-cluster-1.redis-cluster-49ag.yek.svc.cluster.local`:6379 --slave-addr `dig +short redis-cluster-3.redis-cluster-49ag.yek.svc.cluster.local`:6379
#给master节点2绑定4
redis-trib.py replicate --master-addr `dig +short redis-cluster-2.redis-cluster-49ag.yek.svc.cluster.local`:6379 --slave-addr `dig +short redis-cluster-4.redis-cluster-49ag.yek.svc.cluster.local`:6379
#注意点,这里在进行主从绑定时,要注意交叉绑定,最终的结果就是不要把一对主从绑定完被调度到同一台节点上,这样的话,当发生机器节点宕机时,副本没有及时调度会造成redis集群缺少哈希槽而不可用。
不合适的结构
合适的结构
绑定成功输出信息
集群验证
进入redis集群的任意一个副本中,查看集群状态
redis-cli
127.0.0.1:6379>cluster info
此时的集群是没有设置密码的,需要在配置字典中redis.conf添加参数然后重新创建redis集群让其生效
验证方式一
使用基础命令进行验证,验证集群模式的
redis-cli
需要加-c
。
如果已经设置密码的话,需要使用 redis-cli -a 密码 -c 来进入redis集群
验证方式二
验证集群是否可以正常主从切换,在带密码认证的情况下
#进入容器0,通过以下命令查看是否为主节点
cat nodes.conf
#然后删除该容器让其重新创建,正常情况下副本5应该会变为master节点,而新的副本0会变为slave
集群使用
集群暴露
上面方式创建的redis集群是产生的服务是headless类型的,就是对应的服务是没有ClusterIP的,不过一样可以通过该服务的DNS在集群内进行该服务的访问。只需在连接redis集群的微服务那里配置 DNS:6379就可以,这个DNS会被解析为一串对应的6个redis副本的虚拟IP。
还可以将其通过具有ClusterIP的服务暴露,k8s集群内需要连接redis集群的微服务只需配置ClusterIP:6379也是可以的
上面俩种方式都是只能在k8s集群内进行访问redis集群,如果要想让k8s集群外部也可以使用,可以把服务的访问类型改为NodePord类型,那么就可以通过集群内任一节点的ip:主机端口进行访问了。除了修改服务的访问类型还可以通过配置ingress来暴露redis集群到外部访问。
连接redis集群
当应用连接redis集群时,应用会通过redis集群的主节点进行写操作,而从节点进行读操作;需要注意的是当集群内发生任意一对主从的切换,要保证代码中可以做到自动刷新redis集群的拓扑结构,防止发生主从切换时代码内还会连接旧master的IP。文章来源:https://www.toymoban.com/news/detail-462248.html
如果是java代码,在确保springboot的版本为2.3.0以上的情况下,配置文件中添加如下配置文章来源地址https://www.toymoban.com/news/detail-462248.html
spring.redis.timeout=60s
spring.redis.lettuce.cluster.refresh.period=60s
spring.redis.lettuce.cluster.refresh.adaptive=true
到了这里,关于k8s容器化搭建redis集群的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!