kubernetes部署redis主从高可用集群

1.redis主从高可用集群结构

2.k8s部署有状态的服务选择

对于K8S集群有状态的服务,我们可以选择deployment和statefulset

  • statefulset
  • service&deployment
    对于有状态的服务例如:redis和mysql,我们使用statefulset为首选

3.设计原理

statefulset 的设计原理:

  • 拓扑状态

    应用的多个实例之间不是完全对等的关系,这个应用实例的启动必须按照某些顺序启动,比如应用的主节点 A 要先于从节点 B 启动。而如果你把 A 和 B 两个Pod删除掉,他们再次被创建出来是也必须严格按照这个顺序才行,并且,新创建出来的Pod,必须和原来的Pod的网络标识一样,这样原先的访问者才能使用同样的方法,访问到这个新的Pod

  • 存储状态

    应用的多个实例分别绑定了不同的存储数据.对于这些应用实例来说,Pod A第一次读取到的数据,和隔了十分钟之后再次读取到的数据,应该是同一份,哪怕在此期间Pod A被重新创建过.一个数据库应用的多个存储实例

无论是Master 还是 slave都作为statefulset的一个副本,通过pv/pvc进行持久化,对外暴露一个service 接受客户端请求

4.部署步骤

4.1 创建configmap用于存放redis的配置文件

  • 创建一个redis.conf文件
appendonly yes                      #开启Redis的AOF持久化
cluster-enabled yes                 #集群模式打开
cluster-config-file /var/lib/redis/nodes.conf  #下面说明
cluster-node-timeout 5000           #节点超时时间
dir /var/lib/redis                  #AOF持久化文件存在的位置
port 6379                           #开启的端口
  • 创建名称为redis.conf的ConfigMap
kubectl create configmap redis-conf --from-file=redis.conf
#查看configmap
kubectl get cm

4.2 创建headless service

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

apiVersion: v1
kind: Service
metadata:
  name: redis-service
  labels:
    app: redis
spec:
  ports:
  - name: redis-port
    port: 6379
  clusterIP: None
  selector:
    app: redis
    appCluster: redis-cluster

创建和查看:

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

4.3 创建redis集群节点

# cat redis.yaml
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: redis-app
spec:
  serviceName: "redis-service"
  replicas: 6
  template:
    metadata:
      labels:
        app: redis
        appCluster: redis-cluster
    spec:
      terminationGracePeriodSeconds: 20
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - redis
              topologyKey: kubernetes.io/hostname
      containers:
      - name: redis
        image: "redis"
        command:
          - "redis-server"                  #redis启动命令
        args:
          - "/etc/redis/redis.conf"         #redis-server后面跟的参数,换行代表空格
          - "--protected-mode"              #允许外网访问
          - "no"
        # command: redis-server /etc/redis/redis.conf --protected-mode no
        resources:                          #资源
          requests:                         #请求的资源
            cpu: "100m"                     #m代表千分之,相当于0.1 个cpu资源
            memory: "100Mi"                 #内存100m大小
        ports:
            - name: redis
              containerPort: 6379
              protocol: "TCP"
            - name: cluster
              containerPort: 16379
              protocol: "TCP"
        volumeMounts:
          - name: "redis-conf"              #挂载configmap生成的文件
            mountPath: "/etc/redis"         #挂载到哪个路径下
          - name: "redis-data"              #挂载持久卷的路径
            mountPath: "/var/lib/redis"
      volumes:
      - name: "redis-conf"                  #引用configMap卷
        configMap:
          name: "redis-conf"
          items:
            - key: "redis.conf"             #创建configMap指定的名称
              path: "redis.conf"            #里面的那个文件--from-file参数后面的文件
  volumeClaimTemplates:                     #进行pvc持久卷声明,
  - metadata:
      name: redis-data
    spec:
      accessModes: ["ReadWriteMany"]
      storageClassName: "cephfs"
      resources:
        requests:
          storage: 10G
posted @ 2020-05-15 10:15  yuhaohao  阅读(3608)  评论(1编辑  收藏  举报