【实战】K8S部署Redis集群代理Predixy

文章目录

    • 前言
    • 技术积累
      • 为什么要在redis集群前面加个predixy代理?
      • 这样做的好处有哪些?
      • 常用代理配置
      • 网络存储
    • 实战构建predixy镜像并部署
      • 下载predixy源码编译构建镜像
      • 创建K8S配置文件predixy-configmap并执行
      • 网络储存PV与PVC
      • 部署predixy-deployment
    • 测试代理效果
    • 写在最后

前言

部署在K8S中的redis可以在集群内通过服务名访问,这个我们前面博文K8S Helm部署Redis Cluster & Redisinsight 已经介绍过了。但是还是有很多的问题,比如不能在K8S集群外访问,并且在切换库的时候会发生异常,而且只能安装特定的客户端来访问数据库。所以,今天就直接引入Redis集群代理Predixy来管理,让我们把集群当做单机一样。

技术积累

为什么要在redis集群前面加个predixy代理?

【实战】K8S部署Redis集群代理Predixy_第1张图片

如上图所视,在redis集群之上还存在一个predixy集群。在predixy集群之上可以加个nginx,负载最终端的请求,对于客户端来说,看起来只是连接了一个单机版的redis,实际上连接的是一个集群。

这样做的好处有哪些?

Redis pod重启可导致IP变化
POD重新安装后,NODE IP会变化,此时终端无感知
Redis处理连接负载高
集群扩缩容无感知
数据安全风险

常用代理配置

【实战】K8S部署Redis集群代理Predixy_第2张图片

我们希望能够继续使用Redis Cluster来管理Redis集群,所以Codis和Twemproxy不再考虑。redis-cluster-proxy是Redis官方在6.0版本推出的支持Redis Cluster协议的Proxy,但是目前还没有稳定版,暂时也无法大规模应用。

网络存储

PersistentVolume(PV)是集群中由管理员配置的一段网络存储。 它是集群中的资源,就像节点是集群资源一样。 PV是容量插件,如Volumes,但其生命周期独立于使用PV的任何单个pod。 此API对象捕获存储实现的详细信息,包括NFS,iSCSI或特定于云提供程序的存储系统。

PersistentVolumeClaim(PVC)是由用户进行存储的请求。 它类似于pod。 Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以一次读/写或多次只读)。

PV是运维人员来创建的,开发操作PVC,可是大规模集群中可能会有很多PV,如果这些PV都需要运维手动来处理这也是一件很繁琐的事情,所以就有了动态供给概念,也就是Dynamic Provisioning。而我们上面的创建的PV都是静态供给方式,也就是Static Provisioning。而动态供给的关键就是StorageClass,它的作用就是创建PV模板。

创建StorageClass里面需要定义PV属性比如存储类型、大小等;另外创建这种PV需要用到存储插件。最终效果是,用户提交PVC,里面指定存储类型,如果符合我们定义的StorageClass,则会为其自动创建PV并进行绑定。

实战构建predixy镜像并部署

下载predixy源码编译构建镜像

载predixy源码

mkdir -p /k8s/predixy
cd /k8s/predixy
wget https://codeload.github.com/joyieldInc/predixy/zip/refs/heads/master
unzip master
mv predixy-master predixy-1.0.5

编译源码

cd predixy-1.0.5
make 

准备Dockerfile
[root@master predixy]# pwd
/k8s/predixy
[root@master predixy]# vim predixy-dockerfile.yaml

FROM centos:7
RUN yum install -y epel-release net-tools
RUN yum install -y redis
RUN yum install -y libstdc++-static gcc gcc-c++ make
RUN mkdir /opt/predixy-1.0.5
RUN mkdir /etc/predixy
COPY ./predixy-1.0.5/src/predixy  /usr/local/bin/
COPY ./predixy-1.0.5/conf/*  /etc/predixy/
ENTRYPOINT ["/usr/local/bin/predixy","/etc/predixy/predixy.conf"]

然后就可以使用该镜像

[root@master predixy]# docker build .  -t prodixy:v1.0.5 -f predixy-dockerfile.yaml

创建K8S配置文件predixy-configmap并执行

vim predixy-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: predixy-config
  namespace: redis-cluster  #namespace按自已的修改
data:
  predixy.conf: |

    ################################### GENERAL ####################################
    ## Predixy configuration file example
    ## Specify a name for this predixy service
    ## redis command INFO can get this
    Name Predixy-DefaultNS
    ## Specify listen address, support IPV4, IPV6, Unix socket
    ## Examples:
    # Bind 127.0.0.1:7617
    # Bind 0.0.0.0:7617
    # Bind /tmp/predixy
    ## Default is 0.0.0.0:7617
    Bind 0.0.0.0:7617
    ## Worker threads
    WorkerThreads 4
    ## Memory limit, 0 means unlimited
    ## Examples:
    # MaxMemory 100M
    # MaxMemory 1G
    # MaxMemory 0
    ## MaxMemory can change online by CONFIG SET MaxMemory xxx
    ## Default is 0
    # MaxMemory 0
    ## Close the connection after a client is idle for N seconds (0 to disable)
    ## ClientTimeout can change online by CONFIG SET ClientTimeout N
    ## Default is 0 为0时表示禁止该功能,不主动断开客户端连接
    ClientTimeout 0
    ## IO buffer size
    ## Default is 4096
    # BufSize 4096
    ################################### LOG ########################################
    ## Log file path
    ## Unspecify will log to stdout
    ## Default is Unspecified
    Log /data/predixy.log

    ## LogRotate support

    ## 1d rotate log every day
    ## nh rotate log every n hours   1 <= n <= 24
    ## nm rotate log every n minutes 1 <= n <= 1440
    ## nG rotate log evenry nG bytes
    ## nM rotate log evenry nM bytes
    ## time rotate and size rotate can combine eg 1h 2G, means 1h or 2G roate a time
    ## Examples:
    # LogRotate 1d 2G
    # LogRotate 1d
    LogRotate 1d

    ## Default is disable LogRotate


    ## In multi-threads, worker thread log need lock,
    ## AllowMissLog can reduce lock time for improve performance
    ## AllowMissLog can change online by CONFIG SET AllowMissLog true|false
    ## Default is true
    # AllowMissLog false

    ## LogLevelSample, output a log every N
    ## all level sample can change online by CONFIG SET LogXXXSample N
    LogVerbSample 0
    LogDebugSample 0
    LogInfoSample 100
    LogNoticeSample 1
    LogWarnSample 1
    LogErrorSample 1


    ################################### AUTHORITY ##################################
    # Include auth.conf
    Authority {
        Auth "123456pw" {    # predixy 代理密码,业务后端认证需要配置的密码
            Mode admin   # 权限
        }
    }
    ################################### SERVERS ####################################
    #Include cluster.conf
    # Include sentinel.conf
    # Include try.conf
    ###############################################################################
    #这个clusterserverpool也可以放到cluster.conf文件中,看自已的需求
    ClusterServerPool {
      Password 123456    # redis cluste 集群密码
      MasterReadPriority 60
      StaticSlaveReadPriority 50
      DynamicSlaveReadPriority 60
      RefreshInterval 1
      ServerTimeout 1
      ServerFailureLimit 10
      ServerRetryTimeout 1
      KeepAlive 120
      Servers {
        #这个很重要,就是redis-server的集群IP地址,一定要要能取到,可以按我上面的curl方法,能取就行
        + redis-cluster.redis-cluster.svc.cluster.local:6379  
       }
     }
    ################################### DATACENTER #################################
    ## LocalDC specify current machine dc
    # LocalDC bj

    ## see dc.conf
    # Include dc.conf


    ################################### COMMAND ####################################
    ## Custom command define, see command.conf
    #Include command.conf
    ################################### LATENCY ####################################
    ## Latency monitor define, see latency.conf
    #Include latency.conf
        Mode write
    }
    Auth "#a complex password#" {
        Mode admin
    }
}

#执行

kubectl apply -f predixy-configmap.yaml

网络储存PV与PVC

#创建pvc,没有安装nfs-storage的自行查看之前的博文安装

vim predixy-pvc-nfs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: predixy-pvc-nfs
  namespace: redis-cluster
spec:
  accessModes:
  - ReadWriteMany
  resources:
     requests:
       storage: 5Gi
  storageClassName: nfs-storage

#执行

kubectl apply -f predixy-pvc-nfs.yaml

#查看状态

#  nfs创建了pvc会自动创建pv
[root@master nfs]# kubectl get pvc -A|grep  predixy-pvc-nfs
redis-cluster   predixy-pvc-nfs                           Bound    pvc-8524dbd5-fe88-49c5-9417-b1df0815f595   5Gi        RWX            nfs-storage    5m12s

[root@master nfs]# kubectl get pv -A | grep predixy
pvc-8524dbd5-fe88-49c5-9417-b1df0815f595   5Gi        RWX            Delete           Bound         redis-cluster/predixy-pvc-nfs                     nfs-storage             18m

部署predixy-deployment

注:predixy是无状态服务

vim predixy-deployment.yaml
--- 
apiVersion: apps/v1
kind: Deployment ## 升级、回滚
metadata:
  annotations:
    deployment.kubernetes.io/revision: '1'
  name: predixy
  namespace: redis-cluster
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: predixy
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: predixy
    spec:
      containers:
        - command:
            - predixy
            - /etc/predixy/predixy.conf
          image: registry.cn-hangzhou.aliyuncs.com/senfel/predixy:v1.0.5
          name: predixy
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          resources:
            requests:
              cpu: 100m
              memory: 30Mi
            limits:
              cpu: 100m
              memory: 30Mi
          volumeMounts:
            - mountPath: /etc/predixy/
              name: predixy-config-dir
              readOnly: true
            - mountPath: /data/
              name: predixy-data-dir
      imagePullSecrets:
      - name: registry.cn-hangzhou.aliyuncs.com
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 30
      volumes:
        - configMap:
            defaultMode: 420
            name: predixy-config ## ConfigMap
          name: predixy-config-dir
        - name: predixy-data-dir
          persistentVolumeClaim:
            claimName: predixy-pvc-nfs ## 存储

---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler ## 自动扩容
metadata:
  name: predixy
  namespace: redis-cluster
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: predixy
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: Resource
    resource:
       name: cpu
       target:
          type: Utilization
          averageUtilization: 50
  - type: Resource
    resource:
       name: memory
       target:
          type: AverageValue
          averageValue: 80Mi

---
apiVersion: v1
kind: Service ## 服务
metadata:
  name: predixy
  namespace: redis-cluster
spec:
  externalTrafficPolicy: Cluster
  ports:
    - name: predixy-port
      nodePort: 30617
      port: 7617
      protocol: TCP
      targetPort: 7617
  sessionAffinity: None
  type: NodePort
  selector:
    app: predixy
    

#执行

kubectl apply -f predixy-deployment.yaml

#查看状态

[root@master nfs]# kubectl get pod -A|grep predixy

redis-cluster predixy-ff95dcbc5-k9zjs 1/1 Running 0 15m
redis-cluster predixy-ff95dcbc5-nllx8 1/1 Running 0 15m

#删除

kubectl delete -f predixy-deployment.yaml

测试代理效果

K8S集群外部直接使用客户端调用

C:\Users\dev>redis-cli -h 10.10.22.91 -p 30617
10.10.22.91:30617> auth 123456pw
OK
10.10.22.91:30617> get name
“senfel”
10.10.22.91:30617> set name senfel1
OK
10.10.22.91:30617> get name
“senfel1”
10.10.22.91:30617> set age
(error) ERR wrong number of arguments for ‘set’ command
10.10.22.91:30617> set age 10
OK
10.10.22.91:30617> get age
“10”
10.10.22.91:30617>

写在最后

K8S部署Redis集群代理Predixy还是比较简单,只需要编译Predixy源码并构建镜像然后部署在K8S集群即可。最后的效果也是比较nice,直接可以负载均衡到任意的redis节点,让redis集群管理和K8S外部环境任意访问都轻而易举。

你可能感兴趣的:(Kubernetes,kubernetes,redis,容器)