k8s上部署高可用redis集群--三主三从

K8S搭建三主三从高可用redis集群

本方案采用StatefulSet进行redis的部署。它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序。在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless service,headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。
在k8s上搭建Redis sentinel完全没有意义,经过测试,当master节点宕机后,sentinel选择新的节点当主节点,当原master恢复后,此时无法再次成为集群节点。因为在物理机上部署时,sentinel探测以及更改配置文件都是以IP的形式,集群复制也是以IP的形式,但是在容器中,虽然采用的StatefulSet的Headless Service来建立的主从,但是主从建立后,master、slave、sentinel记录还是解析后的IP,但是pod的IP每次重启都会改变,所有sentinel无法识别宕机后又重新启动的master节点,所以一直无法加入集群,虽然可以通过固定pod IP或者使用NodePort的方式来固定,或者通过sentinel获取当前master的IP来修改配置文件。 sentinel实现的是高可用Redis主从,检测Redis Master的状态,进行主从切换等操作,但是在k8s中,无论是dc或者ss,都会保证pod以期望的值进行运行,再加上k8s自带的活性检测,当端口不可用或者服务不可用时会自动重启pod或者pod的中的服务,所以当在k8s中建立了Redis主从同步后,相当于已经成为了高可用状态,并且sentinel进行主从切换的时间不一定有k8s重建pod的时间快,所以个人认为在k8s上搭建sentinel没有意义。

K8s集群环境

节点

IP

master

192.168.1.100

node1

192.168.1.101

node2

192.168.1.102

node3

192.168.1.103

下载镜像经导入集群中redis:3.2.8、inem0o/redis-trib:latest
docker pull redis:3.2.8; docker save –o redis.tar redis:3.2.8
docker pull inem0o/redis-trib:latest; docker save –o redis-trib.tar inem0o/redis-trib:latest
redis.tar上传至k8s的各个node节点;redis-trib.tar上传至k8s的master节点

一、创建存储卷

创建NFS存储主要是为了给Redis提供稳定的后端存储,当Redis的Pod重启或迁移后,依然能获得原先的数据。

  1. 安装nfs软件包

    ]# yum –y install nfs-utils rpcbind #任选一台节点(这里选k8s-master)

  2. 创建共享存储

    ]# mkdir -p /usr/local/k8s/redis/pv{1…6} #创建共享目录
    ]# cat /etc/exports #配置共享路径
    /redis/pv1 192.168.1.0/24(rw,sync,no_root_squash)
    /redis/pv2 192.168.1.0/24(rw,sync,no_root_squash)
    /redis/pv3 192.168.1.0/24(rw,sync,no_root_squash)
    /redis/pv4 192.168.1.0/24(rw,sync,no_root_squash)
    /redis/pv5 192.168.1.0/24(rw,sync,no_root_squash)
    /redis/pv6 192.168.1.0/24(rw,sync,no_root_squash)
    ]# systemctl restart rpcbind;systemctl restart nfs;systemctl enable nfs

    查看共享路径
    exportfs –v #k8s-master上操作
    其他节点安装nfs客户端,并验证
    ]# yum -y install nfs-utils
    ]# showmount -e 192.168.1.100
    Export list for 192.168.1.10:
    /redis/pv1 192.168.1.0/24
    /redis/pv2 192.168.1.0/24
    /redis/pv3 192.168.1.0/24
    /redis/pv4 192.168.1.0/24
    /redis/pv5 192.168.1.0/24
    /redis/pv6 192.168.1.0/24

二、创建PV

以下操作在k8s-master上执行即可
1.每一个Redis Pod都需要一个独立的PV来存储自己的数据,因此可以创建一个pv.yaml文件,包含6个PV:

]# vim pv.yaml 
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv1
spec:
  capacity:
    storage: 2Gi
  accessModes:
- ReadWriteMany
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: "redis"
  nfs:
    server: 192.168.1.10
    path: "/usr/local/k8s/redis/pv1"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-vp2
spec:
  capacity:
    storage: 2Gi
  accessModes:
- ReadWriteMany
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: "redis"
  nfs:
    server: 192.168.1.10
    path: "/usr/local/k8s/redis/pv2"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv3
spec:
  capacity:
    storage: 2Gi
  accessModes:
- ReadWriteMany
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: "redis"
  nfs:
    server: 192.168.1.10
    path: "/usr/local/k8s/redis/pv3"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-vp4
spec:
  capacity:
    storage: 2Gi
  accessModes:
- ReadWriteMany
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: "redis"
  nfs:
    server: 192.168.1.10
    path: "/usr/local/k8s/redis/pv4"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv5
spec:
  capacity:
    storage: 2Gi
  accessModes:
- ReadWriteMany
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: "redis"
  nfs:
    server: 192.168.1.10
    path: "/usr/local/k8s/redis/pv5"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-vp6
spec:
  capacity:
    storage: 2Gi
  accessModes:
- ReadWriteMany
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: "redis"
  nfs:
    server: 192.168.1.10
    path: "/usr/local/k8s/redis/pv6"

    
]# kubectl create -f pv.yaml #创建pv存储卷
persistentvolume "nfs-pv1" created
persistentvolume "nfs-pv2" created
persistentvolume "nfs-pv3" created
persistentvolume "nfs-pv4" created
persistentvolume "nfs-pv5" created
persistentvolume "nfs-pv6" created

三、创建configmap

将Redis的配置文件转化为Configmap,这是一种更方便的配置读取方式。配置文件redis.conf如下

]# vim redis.conf
appendonly yes
cluster-enabled yes
cluster-config-file /var/lib/redis/nodes.conf
cluster-node-timeout 5000
dir /var/lib/redis
port 6379

]# kubectl create configmap redis-conf --from-file=redis.conf
]# kubectl describe cm redis-conf #查看创建的configmap:
Name:         redis-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis.conf:
----
appendonly yes
cluster-enabled yes
cluster-config-file /var/lib/redis/nodes.conf
cluster-node-timeout 5000
dir /var/lib/redis
port 6379

Events:  <none> 

四、创建headless service

Headless service是StatefulSet实现稳定网络标识的基础,我们需要提前创建。准备文件headless-service.yml如下:

]# vim headless-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: redis-service
  labels:
    app: redis
spec:
  ports:
  - name: redis-port
    port: 6379
  clusterIP: None
  selector:
app: redis

]# kubectl create -f headless-service.yml
]# kubectl get svc redis-service 

五、创建redis集群节点

  1. 通过StatefulSet创建6个redis的pod ,实现3主3从的redis集群

    ]# vim redis.yaml
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
    name: redis-app
    spec:
    serviceName: “redis-service”
    replicas: 6
    selector:
    matchLabels:
    app: redis
    appCluster: redis-cluster
    template:
    metadata:
    labels:
    app: redis
    appCluster: redis-cluster
    spec:
    containers:
    - name: redis
    image: “redis:3.2.8”
    command:
    - “redis-server”
    args:
    - “/etc/redis/redis.conf”
    - “–protected-mode”
    - “no”
    resources:
    requests:
    cpu: “100m”
    memory: “100Mi”
    ports:
    - name: redis
    containerPort: 6379
    protocol: “TCP”
    - name: cluster
    containerPort: 16379
    protocol: “TCP”
    volumeMounts:
    - name: “redis-conf”
    mountPath: “/etc/redis”
    - name: “redis-data”
    mountPath: “/var/lib/redis”
    volumes:
    - name: “redis-conf”
    configMap:
    name: “redis-conf”
    items:
    - key: “redis.conf”
    path: “redis.conf”
    volumeClaimTemplates:
    - metadata:
    name: redis-data
    spec:
    accessModes: [ “ReadWriteMany” ]
    storageClassName: “redis”
    resources:
    requests:
    storage: 2Gi

    ]# kubectl create -f redis.yaml
    ]# kubectl get pods -o wide

在这里插入图片描述

六、初始化redis集群

初始化集群采用redis-trib这个工具,直接yum安装redis-trib这个软件,执行初始化
yum -y install redis-trib
]# redis-trib create --replicas 1 10.244.3.20:6379 10.244.2.42:6379 10.244.1.44:6379 10.244.2.43:6379 10.244.3.21:6379 10.244.1.45:6379
在这里插入图片描述
输入 yes 确定
在这里插入图片描述
在这里插入图片描述
或者采用部署redis-trib容器初始化:参考链接https://github.com/iNem0o/docker-redis-trib

]# docker run --rm -ti inem0o/redis-trib create --replicas 1 10.244.3.20:6379  10.244.2.42:6379  10.244.1.44:6379  10.244.2.43:6379  10.244.3.21:6379  10.244.1.45:6379    # IP为6个redis pod的IP以及端口
在提示中输入Yes继续初始化

验证集群状态,集群节点状态为OK,共有6个节点

#kubectl exec -ti redis-app-0 -- redis-cli -c
> cluster iinfo    # 查看集群状态
> role    #查看角色

在这里插入图片描述

七、创建用于访问的service

之前创建了用于实现StatefulSet的Headless Service,但该Service没有Cluster IP,因此不能用于外界访问。所以,我们还需要创建一个Service,专用于为Redis集群提供访问和负载均衡;也可以部署为Ingress供集群外部访问。这里只创建用于内部访问的service

]# vim redis-access-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: redis-access-service
  labels:
    app: redis
spec:
  ports:
  - name: redis-port
    protocol: "TCP"
    port: 6379
    targetPort: 6379
  selector:
    app: redis
    appCluster: redis-cluster

]# kubectl create -f redis-access-service.yaml
该Service名称为 redis-access-service,在K8S集群中暴露6379端口。如果需要提供集群外部访问,可以创建NodePort或者ingress类型

八、redis主从切换测试

删除一个pod为redis的master
]# kubectl delete pods redis-app-1
pod “redis-app-0” deleted

删除pod后,k8s会自动重建一个名称为“redis-app-1”并加入到集群中,但IP不一定是原来的IP;再次查看集群角色,redis-app-1由master变为salve,集群整体依然是6个

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在Kubernetes上部署Redis高可用可以通过Redis Sentinel或Redis Cluster来实现。这里以Redis Sentinel为例,步骤如下: 1. 创建Redis Sentinel镜像 首先需要创建Redis Sentinel镜像,可以通过以下Dockerfile创建: ``` FROM redis:5.0.7-alpine RUN apk add --no-cache --update curl COPY sentinel.conf /etc/redis/sentinel.conf CMD ["redis-sentinel", "/etc/redis/sentinel.conf"] ``` 其中sentinel.conf是Redis Sentinel的配置文件,可以在其中设置Redis实例的地址、端口等信息。 2. 创建Redis StatefulSet 接着创建Redis StatefulSet,可以参考以下yaml文件: ``` apiVersion: v1 kind: Service metadata: name: redis spec: selector: app: redis ports: - name: redis port: 6379 targetPort: 6379 clusterIP: None --- apiVersion: apps/v1 kind: StatefulSet metadata: name: redis spec: serviceName: redis replicas: 3 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis image: redis:5.0.7-alpine command: - redis-server - /etc/redis/redis.conf volumeMounts: - name: redis-config mountPath: /etc/redis - name: sentinel image: my-redis-sentinel:latest volumeMounts: - name: sentinel-config mountPath: /etc/redis volumes: - name: redis-config configMap: name: redis-config - name: sentinel-config configMap: name: sentinel-config volumeClaimTemplates: - metadata: name: data annotations: volume.beta.kubernetes.io/storage-class: "gp2" spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi ``` 其中,StatefulSet中有两个容器:一个是Redis容器,一个是Redis Sentinel容器。Redis容器使用Redis官方镜像,Redis Sentinel容器使用自己创建的Redis Sentinel镜像。同时,还需要创建两个ConfigMap,一个用于Redis配置,一个用于Redis Sentinel配置。 3. 部署Redis Sentinel 最后部署Redis Sentinel,可以参考以下yaml文件: ``` apiVersion: apps/v1 kind: Deployment metadata: name: redis-sentinel spec: replicas: 3 selector: matchLabels: app: redis-sentinel template: metadata: labels: app: redis-sentinel spec: containers: - name: redis-sentinel image: my-redis-sentinel:latest command: - redis-sentinel - /etc/redis/sentinel.conf volumeMounts: - name: sentinel-config mountPath: /etc/redis volumes: - name: sentinel-config configMap: name: sentinel-config ``` 通过部署Redis Sentinel,可以实现Redis集群高可用。如果Redis主节点出现故障,Redis Sentinel会自动将从节点升级为主节点,从而保证Redis集群的可用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值