您的位置:

K8s部署Redis

一、K8s部署Redis集群

K8s可以帮助我们快速部署Redis集群。首先,我们需要创建一个redis-master Deployment,同时为redis-master指定1个Pod。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-master
  labels:
    app: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
      role: master
  template:
    metadata:
      labels:
        app: redis
        role: master
    spec:
      containers:
      - name: redis-master
        image: redis
        command: ["redis-server"]
        args: ["--requirepass", "password"]
        ports:
        - containerPort: 6379

接着,我们为redis-master创建一个NodePort类型的Service,以便在K8s集群外部通过IP:NodePort的方式访问redis-master。

apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    app: redis
    role: master
spec:
  type: NodePort
  ports:
  - port: 6379
    targetPort: 6379
    nodePort: 30001
  selector:
    app: redis
    role: master

然后,我们创建一个redis-slave Deployment,并指定它有2个Pods,它们的Pod Template和redis-master是一致的,只是少了一个role: master的Label。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-slave
  labels:
    app: redis
spec:
  replicas: 2
  selector:
    matchLabels:
      app: redis
      role: slave
  template:
    metadata:
      labels:
        app: redis
        role: slave
    spec:
      containers:
      - name: redis-slave
        image: redis
        command: ["redis-server"]
        args: ["--requirepass", "password", "--slaveof", "redis-master", "6379"]
        ports:
        - containerPort: 6379

同样地,为redis-slave创建一个NodePort类型的Service。

apiVersion: v1
kind: Service
metadata:
  name: redis-slave
  labels:
    app: redis
    role: slave
spec:
  type: NodePort
  ports:
  - port: 6379
    targetPort: 6379
    nodePort: 30002
  selector:
    app: redis
    role: slave

二、K8s部署Redis集群外部访问不上

当我们在K8s集群外部访问redis时,可能会遇到Connection refused的错误。这时,我们需要检查以下几个方面:

1、确保redis-master和redis-slave的Service的type是NodePort。

2、确保redis-master和redis-slave的Pod都启动并且没有CrashLoopBackOff的错误。

3、检查防火墙和网络配置是否允许访问K8s集群的IP:NodePort。

三、K8s部署Redis哨兵

为了保证Redis的高可用性,我们可以使用Redis哨兵来做主从切换。和部署Redis集群类似,我们首先需要创建哨兵的Deployment。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-sentinel
  labels:
    app: redis
spec:
  replicas: 3
  selector:
    matchLabels:
      app: redis
      role: sentinel
  template:
    metadata:
      labels:
        app: redis
        role: sentinel
    spec:
      containers:
      - name: redis-sentinel
        image: redis
        command:
          - "/bin/sh"
          - "-ec"
          - |
            redis-sentinel /usr/local/etc/redis/sentinel.conf
        env:
        - name: SENTINEL_QUORUM
          value: "2"
        - name: REDIS_MASTER_SERVICE_NAME
          value: "redis-master"
        ports:
        - containerPort: 26379
        volumeMounts:
        - name: config
          mountPath: /usr/local/etc/redis
      volumes:
      - name: config
        configMap:
          name: redis-sentinel-config

然后,为redis-sentinel创建一个NodePort类型的Service,以便在K8s集群外部通过IP:NodePort的方式访问redis-sentinel。

apiVersion: v1
kind: Service
metadata:
  name: redis-sentinel
  labels:
    app: redis
    role: sentinel
spec:
  type: NodePort
  ports:
  - port: 26379
    targetPort: 26379
    nodePort: 30179
  selector:
    app: redis
    role: sentinel

最后,我们需要为redis-master创建一个ConfigMap,用于配置哨兵。

apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-sentinel-config
data:
  sentinel.conf: |
    port 26379
    daemonize no
    logfile ""
    dir "/tmp"
    sentinel monitor mymaster redis-master 6379 2
    sentinel down-after-milliseconds mymaster 5000
    sentinel failover-timeout mymaster 60000
    sentinel parallel-syncs mymaster 1

四、K8s部署Redis缺点

和其他基于容器的应用一样,K8s部署Redis也存在一些缺点:

1、网络延迟:和普通的虚拟机相比,由于K8s要额外的处理网络数据包的转发等操作,所以可能会带来一定的网络延迟。

2、性能损失:由于K8s需要运行一些辅助容器,如Proxy,所以可能会带来一定的性能损失。

3、复杂度:K8s的使用和配置相对复杂,可能需要学习额外的知识,如K8s的API和yaml文件的编写。

五、K8s部署Redis Cluster

除了部署Redis主从模式和哨兵模式,我们还可以使用Redis Cluster来实现高可用性。Redis Cluster是通过对多个Redis实例进行分片来实现高可用性和可扩展性的方案。在K8s中,我们可以使用StatefulSet来部署Redis Cluster。

在StatefulSet中,每个Pod的名字都会按照指定的规则进行命名,例如:redis-cluster-0、redis-cluster-1、redis-cluster-2。为了实现Redis Cluster的分片,我们还需要为StatefulSet创建一个Headless Service。

完整的Redis Cluster在K8s中的部署示例如下:

apiVersion: v1
kind: Service
metadata:
  name: redis-cluster
  labels:
    app: redis
spec:
  clusterIP: None
  ports:
  - name: redis
    port: 6379
  selector:
    app: redis
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-cluster
spec:
  serviceName: "redis-cluster"
  replicas: 6
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis
        command:
        - redis-server
        - /usr/local/etc/redis/redis.conf
        ports:
        - containerPort: 6379
        volumeMounts:
        - name: config
          mountPath: /usr/local/etc/redis/
  volumeClaimTemplates:
  - metadata:
      name: redis-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-cluster-config
data:
  redis.conf: |
    cluster-enabled yes
    cluster-config-file /data/nodes.conf
    cluster-node-timeout 5000
    appendonly yes
  nodes.conf: |
    # This file will be automatically generated by Redis

六、K8s部署Redis集群外部访问

同样地,为了让Redis Cluster能够被外部访问,我们仍然需要为Headless Service创建一个NodePort类型的Service,例如:

apiVersion: v1
kind: Service
metadata:
  name: redis-cluster-nodeport
  labels:
    app: redis
spec:
  type: NodePort
  ports:
  - name: redis
    port: 6379
    targetPort: 6379
    nodePort: 30003
  selector:
    app: redis

七、K8s部署Redis集群的原理

Redis集群是通过一致性哈希的算法来实现分片的。具体来说,集群将所有的key分成16384个槽位,每个Redis实例负责一部分槽位。

在Redis集群中,客户端需要根据key的哈希值,选择相应的Redis实例进行操作。当Redis集群中的一个节点宕机时,集群会将其负责的槽位重新分配给其它节点。同时,Redis集群还支持主从复制和哨兵机制,来确保集群的高可用性。

八、Redis部署安装

除了使用K8s部署Redis外,我们还可以从官方网站下载Redis的源码,然后进行编译和安装。完整的Redis部署安装过程如下:

1、下载Redis的源码:

$ wget https://download.redis.io/releases/redis-6.2.5.tar.gz
$ tar xzf redis-6.2.5.tar.gz
$ cd redis-6.2.5

2、编译Redis:

$ make

3、安装Redis:

$ make install

4、启动Redis Server:

$ redis-server

九、K8s部署方式

K8s提供了多种方式来部署应用程序:

1、Deployment:用于快速创建Pod、ReplicaSet和Service。

2、StatefulSet:用于有状态应用程序的部署,例如数据库。

3、DaemonSet:用于在K8s集群中的每个节点上启动一个Pod。

4、Job:用于运行短暂或一次性的任务。

5、CronJob:类似于Linux的crontab,用于定时执行任务。

十、K8s部署流程

在K8s中部署一个应用程序的流程通常如下:

1、准备Docker镜像:将应用程序及其依赖打包成Docker镜像,并上传到镜像仓库。

2、编写K8s的yaml文件:按照需要,编写应用程序的Deployment、Service、ConfigMap、Secret等K8s资源的yaml文件。

3、创建K8s资源:使用kubectl create或kubectl apply命令,创建K8s资源。

4、验证部署:使用kubectl get命令,查看各个K8s资源的状态,验证部署是否成功。