> 文档中心 > k8s之实现redis一主多从动态扩缩容

k8s之实现redis一主多从动态扩缩容


架构

  • 基于statefulset实现一主多从redis,动态扩缩容redis从库,并基于storageclass实现动态存储,保证数据的持久化存储

在这里插入图片描述

主机名 IP
k8s-master-1 192.168.0.10
k8s-node-1 192.168.0.11
k8s-nfs 192.168.0.55

nfs-provider

# k8s-nfs nfs配置信息[root@k8s-nfs ~]# cat /etc/exports/data192.168.0.0/24(rw,all_squash)
[root@k8s-master-1 1master-Nslave]# cat nfs-provider.yaml apiVersion: v1kind: ServiceAccountmetadata:  name: nfs-client-provisioner  # replace with namespace where provisioner is deployed  namespace: redis---kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:  name: nfs-client-provisioner-runnerrules:  - apiGroups: [""]    resources: ["nodes"]    verbs: ["get", "list", "watch"]  - apiGroups: [""]    resources: ["persistentvolumes"]    verbs: ["get", "list", "watch", "create", "delete"]  - apiGroups: [""]    resources: ["persistentvolumeclaims"]    verbs: ["get", "list", "watch", "update"]  - apiGroups: ["storage.k8s.io"]    resources: ["storageclasses"]    verbs: ["get", "list", "watch"]  - apiGroups: [""]    resources: ["events"]    verbs: ["create", "update", "patch"]---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:  name: run-nfs-client-provisionersubjects:  - kind: ServiceAccount    name: nfs-client-provisioner    # replace with namespace where provisioner is deployed    namespace: redisroleRef:  kind: ClusterRole  name: nfs-client-provisioner-runner  apiGroup: rbac.authorization.k8s.io---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata:  name: leader-locking-nfs-client-provisioner  # replace with namespace where provisioner is deployed  namespace: redisrules:  - apiGroups: [""]    resources: ["endpoints"]    verbs: ["get", "list", "watch", "create", "update", "patch"]---kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:  name: leader-locking-nfs-client-provisioner  # replace with namespace where provisioner is deployed  namespace: redissubjects:  - kind: ServiceAccount    name: nfs-client-provisioner    # replace with namespace where provisioner is deployed    namespace: redisroleRef:  kind: Role  name: leader-locking-nfs-client-provisioner  apiGroup: rbac.authorization.k8s.io---apiVersion: apps/v1kind: Deploymentmetadata:  name: nfs-client-provisioner  labels:    app: nfs-client-provisioner  # replace with namespace where provisioner is deployed  namespace: redisspec:  replicas: 1  strategy:    type: Recreate  selector:    matchLabels:      app: nfs-client-provisioner  template:    metadata:      labels: app: nfs-client-provisioner    spec:      nodeName: k8s-master-1   #设置在master节点运行      tolerations:      #设置容忍master节点污点      - key: node-role.kubernetes.io/master operator: Equal value: "true"      serviceAccountName: nfs-client-provisioner      containers: - name: nfs-client-provisioner   image: registry.cn-hangzhou.aliyuncs.com/jiayu-kubernetes/nfs-subdir-external-provisioner:v4.0.0   imagePullPolicy: IfNotPresent   volumeMounts:     - name: nfs-client-rootmountPath: /persistentvolumes   env:     - name: PROVISIONER_NAMEvalue: k8s/nfs-subdir-external-provisioner     - name: NFS_SERVERvalue: 192.168.0.55     - name: NFS_PATHvalue: /data      volumes: - name: nfs-client-root   nfs:     server: 192.168.0.55  # NFS SERVER_IP     path: /data---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: redis-nfs  namespace: redis  annotations:    storageclass.kubernetes.io/is-default-class: "false"  # 是否设置为默认的storageclassprovisioner: k8s/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'allowVolumeExpansion: truereclaimPolicy: Deleteparameters:  archiveOnDelete: "false" 

redis.conf

[root@k8s-master-1 1master-Nslave]# cat configmap.yaml apiVersion: v1kind: Namespacemetadata:  name: redis---apiVersion: v1kind: ConfigMapmetadata:  name: redis  namespace: redisdata:  redis.conf: |-    daemonize no    protected-mode no    bind 0.0.0.0    port 6379    timeout 300    databases 16    save 900 1    save 300 10    save 60 10000     loglevel notice    logfile /data/redis.log    ###################    RDB ####################    dir /data    stop-writes-on-bgsave-error yes    rdbcompression yes    dbfilename dump.rdb    ##################     REPL###################     slave-read-only yes    repl-diskless-sync no    repl-timeout 120    ##################    SECURITY    ###################    requirepass 123456    masterauth 123456    ##################     AOF ####################    appendonly no    appendfilename "appendonly.aof"    appendfsync no

statefulset

[root@k8s-master-1 1master-Nslave]# cat statefulset.yaml apiVersion: v1kind: Servicemetadata:  name: redis  namespace: redisspec:  selector:    app: redis  ports:  - name: redis    port: 6379    targetPort: 6379    protocol: TCP  clusterIP: None  type: ClusterIP---apiVersion: apps/v1kind: StatefulSetmetadata:  name: redis  namespace: redisspec:  replicas: 2     # 默认是一主一从  selector:    matchLabels:      app: redis  serviceName: redis  template:    metadata:      labels: app: redis    spec:      containers:      - name: redis image: redis:5 imagePullPolicy: IfNotPresent command: - /bin/sh - -c - |   set -e   hostname=$(echo `hostname` | grep -oE '\-([0-9]+)$')   if [ "$hostname" != "-0" ]; then  #如果不是第一个节点,则向第一个节点同步     redis-server  /etc/redis.conf slaveof redis-0.redis.redis.svc.cluster.local 6379   else     redis-server /etc/redis.conf   fi volumeMounts: - name: redis-data   mountPath: /data - name: redis-conf   mountPath: /etc/redis.conf   subPath: redis.conf      volumes:      - name: redis-conf configMap:   name: redis  volumeClaimTemplates:  - metadata:      name: redis-data      namespace: redis    spec:      accessModes: ["ReadWriteMany"]      storageClassName: redis-nfs      resources: requests:   storage: 500Mi

部署

# 部署configmap[root@k8s-master-1 1master-Nslave]# kubectl apply -f configmap.yaml namespace/redis createdconfigmap/redis created# 部署nfs-provider[root@k8s-master-1 1master-Nslave]# kubectl apply -f nfs-provider.yaml serviceaccount/nfs-client-provisioner createdclusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner createdclusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner createdrole.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner createdrolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner createddeployment.apps/nfs-client-provisioner createdstorageclass.storage.k8s.io/redis-nfs created# 部署statefulset[root@k8s-master-1 1master-Nslave]# kubectl apply -f statefulset.yaml service/redis createdstatefulset.apps/redis created# 查看pod[root@k8s-master-1 1master-Nslave]# kubectl get pods -n redisNAME   READY   STATUS    RESTARTS   AGEnfs-client-provisioner-7f6758d967-l9b5p   1/1     Running   0   2m10sredis-01/1     Running   0   100sredis-11/1     Running   0   53s# 查看PV,PVC[root@k8s-master-1 1master-Nslave]# kubectl get pvc -n redisNAME   STATUS   VOLUME  CAPACITY   ACCESS MODES   STORAGECLASS   AGEredis-data-redis-0   Bound    pvc-e0642424-f6b3-405f-9d12-d53b277be042   500Mi      RWX     redis-nfs      2m21sredis-data-redis-1   Bound    pvc-5925df68-31da-41c9-9655-7e9bd4c9bfb6   500Mi      RWX     redis-nfs      94s[root@k8s-master-1 1master-Nslave]# kubectl get pvNAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM STORAGECLASS   REASON   AGEpvc-5925df68-31da-41c9-9655-7e9bd4c9bfb6   500Mi      RWX     Delete    Bound    redis/redis-data-redis-1   redis-nfs 96spvc-e0642424-f6b3-405f-9d12-d53b277be042   500Mi      RWX     Delete    Bound    redis/redis-data-redis-0   redis-nfs 2m23s# k8s-nfs节点查看[root@k8s-nfs ~]# ls /dataredis-redis-data-redis-0-pvc-e0642424-f6b3-405f-9d12-d53b277be042  redis-redis-data-redis-1-pvc-5925df68-31da-41c9-9655-7e9bd4c9bfb6# 查看redis-1复制情况[root@k8s-master-1 1master-Nslave]# kubectl exec redis-1 -n redis -- redis-cli -a 123456 info replication# Replicationrole:slave  #从库master_host:redis-0.redis.redis.svc.cluster.local  #主库信息master_port:6379master_link_status:upmaster_last_io_seconds_ago:7master_sync_in_progress:0slave_repl_offset:252slave_priority:100slave_read_only:1connected_slaves:0master_replid:03c3dd18042139cbe116946f6c46c640fb91681bmaster_replid2:0000000000000000000000000000000000000000master_repl_offset:252second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:252

扩容

扩容从redis-0->redis-N

# 扩容[root@k8s-master-1 1master-Nslave]# kubectl scale statefulset redis --replicas=4 -n redisstatefulset.apps/redis scaled# 查看pod[root@k8s-master-1 1master-Nslave]# kubectl get pods -n redisNAME   READY   STATUS    RESTARTS   AGEnfs-client-provisioner-7f6758d967-l9b5p   1/1     Running   0   6m52sredis-01/1     Running   0   6m22sredis-11/1     Running   0   5m35sredis-21/1     Running   0   16sredis-31/1     Running   0   11s# 可见pvc,pv都是动态生成的[root@k8s-master-1 1master-Nslave]# kubectl get pvc -n redisNAME   STATUS   VOLUME  CAPACITY   ACCESS MODES   STORAGECLASS   AGEredis-data-redis-0   Bound    pvc-e0642424-f6b3-405f-9d12-d53b277be042   500Mi      RWX     redis-nfs      7mredis-data-redis-1   Bound    pvc-5925df68-31da-41c9-9655-7e9bd4c9bfb6   500Mi      RWX     redis-nfs      6m13sredis-data-redis-2   Bound    pvc-521d77ec-64df-44e1-8a49-22d032046b86   500Mi      RWX     redis-nfs      54sredis-data-redis-3   Bound    pvc-365be101-2ced-4800-9db0-be68fdedd64d   500Mi      RWX     redis-nfs      49s[root@k8s-master-1 1master-Nslave]# kubectl get pvNAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM STORAGECLASS   REASON   AGEpvc-365be101-2ced-4800-9db0-be68fdedd64d   500Mi      RWX     Delete    Bound    redis/redis-data-redis-3   redis-nfs 55spvc-521d77ec-64df-44e1-8a49-22d032046b86   500Mi      RWX     Delete    Bound    redis/redis-data-redis-2   redis-nfs 60spvc-5925df68-31da-41c9-9655-7e9bd4c9bfb6   500Mi      RWX     Delete    Bound    redis/redis-data-redis-1   redis-nfs 6m19spvc-e0642424-f6b3-405f-9d12-d53b277be042   500Mi      RWX     Delete    Bound    redis/redis-data-redis-0   redis-nfs 7m6s# 查看复制信息,可见同步正常[root@k8s-master-1 1master-Nslave]# kubectl exec redis-3 -n redis -- redis-cli -a 123456 info replication# Replicationrole:slavemaster_host:redis-0.redis.redis.svc.cluster.localmaster_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:630slave_priority:100slave_read_only:1connected_slaves:0master_replid:03c3dd18042139cbe116946f6c46c640fb91681bmaster_replid2:0000000000000000000000000000000000000000master_repl_offset:630second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:449repl_backlog_histlen:182Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

缩容

缩容从redis-N->redis-0

# 缩容[root@k8s-master-1 1master-Nslave]# kubectl scale statefulset redis --replicas=1 -n redisstatefulset.apps/redis scaled# 查看pod[root@k8s-master-1 1master-Nslave]# kubectl get pods -n redisNAME   READY   STATUS    RESTARTS   AGEnfs-client-provisioner-7f6758d967-l9b5p   1/1     Running   0   11mredis-01/1     Running   0   11m# 查看pv,pvc,可见即使pod被删除了pvc和pv都没有被删除,后续当我们再进行扩容时对应的pod还是会使用之前的pv,[root@k8s-master-1 1master-Nslave]# kubectl get pvNAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM STORAGECLASS   REASON   AGEpvc-365be101-2ced-4800-9db0-be68fdedd64d   500Mi      RWX     Delete    Bound    redis/redis-data-redis-3   redis-nfs 6m29spvc-521d77ec-64df-44e1-8a49-22d032046b86   500Mi      RWX     Delete    Bound    redis/redis-data-redis-2   redis-nfs 6m34spvc-5925df68-31da-41c9-9655-7e9bd4c9bfb6   500Mi      RWX     Delete    Bound    redis/redis-data-redis-1   redis-nfs 11mpvc-e0642424-f6b3-405f-9d12-d53b277be042   500Mi      RWX     Delete    Bound    redis/redis-data-redis-0   redis-nfs 12m[root@k8s-master-1 1master-Nslave]# kubectl get pvc -n redisNAME   STATUS   VOLUME  CAPACITY   ACCESS MODES   STORAGECLASS   AGEredis-data-redis-0   Bound    pvc-e0642424-f6b3-405f-9d12-d53b277be042   500Mi      RWX     redis-nfs      12mredis-data-redis-1   Bound    pvc-5925df68-31da-41c9-9655-7e9bd4c9bfb6   500Mi      RWX     redis-nfs      11mredis-data-redis-2   Bound    pvc-521d77ec-64df-44e1-8a49-22d032046b86   500Mi      RWX     redis-nfs      6m39sredis-data-redis-3   Bound    pvc-365be101-2ced-4800-9db0-be68fdedd64d   500Mi      RWX     redis-nfs      6m34s