基于K8s部署Redis高可用
K8s集群为一主二从
1.项目架构图
2.部署Redis服务
2.1 创建Redis配置文件
创建资源清单文件 redis-cluster-cm.yaml ,并输入以下内容:
apiVersion: v1
kind: ConfigMap
metadata:name: redis-cluster-config
data:redis-config: |appendonly yesprotected-mode nodir /dataport 6379cluster-enabled yescluster-config-file /data/nodes.confcluster-node-timeout 5000masterauth Chengke2025requirepass Chengke2025
创建 ConfigMap 资源
[root@k8s-master01]# kubectl apply -f redis-cluster-cm.yaml
2.2 创建Redis
创建资源清单文件 redis-cluster-sts.yaml ,并输入以下内容:
apiVersion: v1
kind: Service
metadata:name: redis-headlesslabels:app.kubernetes.io/name: redis-cluster
spec:ports:- name: redis-6379protocol: TCPport: 6379targetPort: 6379selector:app.kubernetes.io/name: redis-clusterclusterIP: Nonetype: ClusterIP
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: redis-clusterlabels:app.kubernetes.io/name: redis-cluster
spec:serviceName: redis-headlessreplicas: 6selector:matchLabels:app.kubernetes.io/name: redis-clustertemplate:metadata:labels:app.kubernetes.io/name: redis-clusterspec:affinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: app.kubernetes.io/nameoperator: Invalues:- redis-clustertopologyKey: kubernetes.io/hostnamecontainers:- name: redisimage: 'redis:7.2.6'command:- "redis-server"args:- "/etc/redis/redis.conf"- "--protected-mode"- "no"- "--cluster-announce-ip"- "$(POD_IP)"env:- name: POD_IPvalueFrom:fieldRef:fieldPath: status.podIPports:- name: redis-6379containerPort: 6379protocol: TCPvolumeMounts:- name: configmountPath: /etc/redis- name: redis-cluster-datamountPath: /dataresources:limits:cpu: '2'memory: 4Girequests:cpu: 50mmemory: 500Mivolumes:- name: configconfigMap:name: redis-cluster-configitems:- key: redis-configpath: redis.confvolumeClaimTemplates:- metadata:name: redis-cluster-dataspec:accessModes: [ "ReadWriteOnce" ]storageClassName: "nfs-client"resources:requests:storage: 5Gi
执行下面的命令,创建资源
[root@k8s-master01]# kubectl apply -f redis-cluster-sts.yaml
2.3 创建K8s集群外部访问服务
采用 NodePort 方式在 Kubernetes 集群外发布 Redis 服务,指定的端口为 31379
使用 vi 编辑器,创建资源清单文件 redis-cluster-svc-external.yaml ,并输入以下内容:
kind: Service
apiVersion: v1
metadata:name: redis-cluster-externallabels:app: redis-cluster-external
spec:ports:- protocol: TCPport: 6379targetPort: 6379nodePort: 31379selector:app.kubernetes.io/name: redis-clustertype: NodePort
执行下面的命令,创建 Service 资源
[root@k8s-master01]# kubectl apply -f redis-cluster-svc-external.yaml
3. 自动创建Redis集群
[root@k8s-master01]# kubectl exec -it redis-cluster-0 -- redis-cli -a Chengke2025 --cluster create --cluster-replicas 1 $(kubectl get pods -l app.kubernetes.io/name=redis-cluster -o jsonpath='{range.items[*]} {.status.podIP}:6379 {end}')
3.1 验证集群状态
[root@k8s-master01]# kubectl exec -it redis-cluster-0 -- redis-cli -p 6379 -a Chengke2025 cluster info
或者使用
[root@k8s-master01 1]# kubectl exec -it redis-cluster-0 -- redis-cli -a Chengke2025 --cluster check $(kubectl get pods -l app.kubernetes.io/name=rediscluster -o jsonpath='{range.items[0]}{.status.podIP}:6379{end}')
4.集群功能测试
4.1 压力测试
使用 Redis 自带的压力测试工具,测试 Redis 集群是否可用,并简单测试性能
测试 set 场景:
[root@k8s-master01]# kubectl exec -it redis-cluster-0 -- redis-benchmark -h
192.168.10.11 -p 31379 -a Chengke2025 -t set -n 100000 -c 20 -d 100 --cluster
4.2 故障切换测试
测试前查看集群状态(以一组 Master/Slave 为例)
[root@k8s-master01 1]# kubectl exec -it redis-cluster-0 -- redis-cli -a
Chengke2025 --cluster check $(kubectl get pods -l app.kubernetes.io/name=rediscluster -o jsonpath='{range.items[0]}{.status.podIP}:6379{end}')
测试场景1: 手动删除一个 Master 的 Slave,观察 Slave Pod 是否会自动重建并加入原有 Master。
结果: 原有 Slave IP 为 10.244.85.142,删除后自动重建,IP 变更为 10.244.85.135,并自动加入原有 的 Master。
测试场景2: 手动删除 Master ,观察 Master Pod 是否会自动重建并重新变成 Master。 删除 Master 后,查看集群状态。
结果: 原有 Master IP 为 10.244.58.218,删除后自动重建, IP 变更为 10.244.58.219,并重新变成 Master
5. 安装管理客户端
5.1 编辑资源清单
创建资源清单文件 redisinsight-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: redisinsightlabels:app.kubernetes.io/name: redisinsight
spec:replicas: 1selector:matchLabels:app.kubernetes.io/name: redisinsighttemplate:metadata:labels:app.kubernetes.io/name: redisinsightspec:containers:- name: redisinsightimage: redis/redisinsight:2.60ports:- name: redisinsightcontainerPort: 5540protocol: TCPresources:limits:cpu: '2'memory: 4Girequests:cpu: 100mmemory: 500Mi
5.2 创建外部访问服务
采用 NodePort 方式在 Kubernetes 集群中对外发布 RedisInsight 服务,指定的端口为 31380
创建资源清单文件 redisinsight-svc-external.yaml
kind: Service
apiVersion: v1
metadata:name: redisinsight-externallabels:app: redisinsight-external
spec:ports:- name: redisinsightprotocol: TCPport: 5540targetPort: 5540nodePort: 31380selector:app.kubernetes.io/name: redisinsighttype: NodePort
执行下面的命令,创建 RedisInsight 资源。
[root@k8s-master01]# kubectl apply -f redisinsight-deploy.yaml -f redisinsightsvc-extenal.yaml