今天让我们试着在k8s里部署一个redis集群,了解更多k8s的细节和特性。

环境:minikube v0.30 (kubernetes 1.10)

问题分析

本质上来说,在k8s上部署一个redis集群和部署一个普通应用没有什么太大的区别,但需要注意下面几个问题:

1、REDIS是一个有状态应用

这是部署redis集群时我们最需要注意的问题,当我们把redis以pod的形式部署在k8s中时,每个pod里缓存的数据都是不一样的,而且pod的IP是会随时变化,这时候如果使用普通的deployment和service来部署redis-cluster就会出现很多问题,因此需要改用StatefulSet + Headless Service来解决。

2、数据持久化

redis虽然是基于内存的缓存,但还是需要依赖于磁盘进行数据的持久化,以便服务出现问题重启时可以恢复已经缓存的数据。在集群中,我们需要使用共享文件系统 + PV(持久卷)的方式来让整个集群中的所有pod都可以共享同一份持久化储存。

概念介绍

在开始之前先来详细介绍一下几个概念和原理。

1、Headless Service

简单的说,Headless Service就是没有指定Cluster IP的Service,相应的,在k8s的dns映射里,Headless Service的解析结果不是一个Cluster IP,而是它所关联的所有Pod的IP列表。

2、StatefulSet

  StatefulSet是k8s中专门用于解决有状态应用部署的一种资源,总的来说可以认为它是Deployment/RC的一个变种,它有以下几个特性:

StatefulSet管理的每个Pod都有唯一的文档/网络标识,并且按照数字规律生成,而不是像Deployment中那样名称和IP都是随机的。(比如StatefulSet名字为redis,那么pod名就是redis-0, redis-1 ...)

StatefulSet中ReplicaSet的启停顺序是严格受控的,操作第N个pod一定要等前N-1个执行完才可以。

StatefulSet中的Pod采用稳定的持久化储存,并且对应的PV不会随着Pod的删除而被销毁。

另外需要说明的是,StatefulSet必须要配合Headless Service使用,它会在Headless Service提供的DNS映射上再加一层,最终形成精确到每个pod的域名映射,格式如下:

$(podname).$(headless service name)

有了这个映射,就可以在配置集群时使用域名替代IP,实现有状态应用集群的管理。

方案

借助StatefulSet和Headless Service,集群的部署方案设计如下(图片来自网络):


配置步骤大概罗列如下:

  1. 配置共享文件系统NFS

  2. 创建PV和PVC

  3. 创建ConfigMap

  4. 创建Headless Service

  5. 创建StatefulSet

  6. 初始化redis集群

实际操作

由于使用的是minikube的单node环境,为了简化复杂度,这次先不配置PV和PVC,直接通过普通Volume的方式来挂载数据。

1、创建ConfigMap

先创建redis.conf配置文件

appendonly yescluster-enabled yescluster-config-file /var/lib/redis/nodes.confcluster-node-timeout 5000dir /var/lib/redisport 6379

然后

kubectl create configmap redis-conf --from-file=redis.conf

来创建ConfigMap。

2、创建HeadlessService

apiVersion: v1kind: Servicemetadata:name: redis-servicelabels:app: redisspec:ports:- name: redis-portport: 6379clusterIP: Noneselector:app: redisappCluster: redis-cluster

3、创建StatefulSet

apiVersion: apps/v1beta1kind: StatefulSetmetadata:name: redis-appspec:serviceName: "redis-service"replicas: 6template:metadata:labels:app: redisappCluster: redis-clusterspec:terminationGracePeriodSeconds: 20affinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues:- redistopologyKey: kubernetes.io/hostnamecontainers:- name: redisimage: "registry.cn-qingdao.aliyuncs.com/gold-faas/gold-redis:1.0"command:- "redis-server"args:- "/etc/redis/redis.conf"- "--protected-mode"- "no"resources:requests:cpu: "100m"memory: "100Mi"ports:- name: rediscontainerPort: 6379protocol: "TCP"- name: clustercontainerPort: 16379protocol: "TCP"volumeMounts:- name: "redis-conf"mountPath: "/etc/redis"- name: "redis-data"mountPath: "/var/lib/redis"volumes:- name: "redis-conf"configMap:name: "redis-conf"items:- key: "redis.conf"path: "redis.conf"- name: "redis-data"emptyDir: {} 

4、初始化redis集群

StatefulSet创建完毕后,可以看到6个pod已经启动了,但这时候整个redis集群还没有初始化,需要使用官方提供的redis-trib工具。

我们当然可以在任意一个redis节点上运行对应的工具来初始化整个集群,但这么做显然有些不太合适,我们希望每个节点的职责尽可能地单一,所以最好单独起一个pod来运行整个集群的管理工具。

在这里需要先介绍一下redis-trib,它是官方提供的redis-cluster管理工具,可以实现redis集群的创建、更新等功能,在早期的redis版本中,它是以源码包里redis-trib.rb这个ruby脚本的方式来运作的(pip上也可以拉到python版本,但我运行失败),现在(我使用的5.0.3)已经被官方集成进redis-cli中。

开始初始化集群,首先在k8s上创建一个ubuntu的pod,用来作为管理节点:

kubectl run -i --tty redis-cluster-manager --image=ubuntu --restart=Never /bin/bash

进入pod内部先安装一些工具,包括wget,dnsutils,然后下载和安装redis:

wget http://download.redis.io/releases/redis-5.0.3.tar.gztar -xvzf redis-5.0.3.tar.gzcd redis-5.0.3.tar.gz && make

编译完毕后redis-cli会被放置在src目录下,把它放进/usr/local/bin中方便后续操作。

接下来要获取已经创建好的6个节点的host ip,可以通过nslookup结合StatefulSet的域名规则来查找,举个例子,要查找redis-app-0这个pod的ip,运行如下命令:

root@redis-cluster-manager:/# nslookup redis-app-0.redis-serviceServer:    10.96.0.10Address:  10.96.0.10#53Name:  redis-app-0.redis-service.gold.svc.cluster.localAddress: 172.17.0.10

  172.17.0.10就是对应的ip。这次部署我们使用0,1,2作为Master节点;3,4,5作为Slave节点,先运行下面的命令来初始化集群的Master节点:

redis-cli --cluster create 172.17.0.10:6379 172.17.0.11:6379 172.17.0.12:6379

然后给他们分别附加对应的Slave节点,这里的cluster-master-id在上一步创建的时候会给出:

redis-cli --cluster add-node 172.17.0.13:6379 172.17.0.10:6379 --cluster-slave --cluster-master-id adf443a4d33c4db2c0d4669d61915ae6faa96b46redis-cli --cluster add-node 172.17.0.14:6379 172.17.0.11:6379 --cluster-slave --cluster-master-id 6e5adcb56a871a3d78343a38fcdec67be7ae98f8redis-cli --cluster add-node 172.17.0.16:6379 172.17.0.12:6379 --cluster-slave --cluster-master-id c061e37c5052c22f056fff2a014a9f63c3f47ca0

集群初始化后,随意进入一个节点检查一下集群信息:


至此,集群初始化完毕,我们进入一个节点来试试,注意在集群模式下redis-cli必须加上-c参数才能够访问其他节点上的数据:


5、创建Service

现在进入redis集群中的任意一个节点都可以直接进行操作了,但是为了能够对集群其他的服务提供访问,还需要建立一个service来实现服务发现和负载均衡(注意这里的service和我们之前创建的headless service不是一个东西)

yaml文件如下:

apiVersion: v1kind: Servicemetadata:name: gold-redislabels:app: redisspec:ports:- name: redis-portprotocol: "TCP"port: 6379targetPort: 6379selector:app: redis    appCluster: redis-cluster

部署完做个测试:


到这里所有的工作就完毕了~

往期精彩

《Docker是什么?》

《Kubernetes是什么?》

《Kubernetes和Docker到底有啥关系?》

《教你如何快捷的查询选择网络仓库镜像tag》

《Docker镜像进阶:了解其背后的技术原理》

《教你如何修改运行中的容器端口映射》

《k8s学习笔记:介绍&上手》

《k8s学习笔记:缩扩容&更新》

《Docker君带你认识Docker Swarm》

《Docker 基础用法和命令帮助》


免责声明:本文内容来源于网络,所载内容仅供参考。转载仅为学习和交流之目的,如无意中侵犯您的合法权益,请及时联系西岐Docker君!


dockerchina

看完文章,点个「在看」奥,谢谢!

redis映射的概念_在K8S上搭建Redis集群相关推荐

  1. 微信公众号 多台服务器,在多台 Linux 服务器上搭建 Pulsar 集群

    作者:高天赐 编辑:Irene Pulsar 是一个支持多租户的.高性能的消息中间件.上一篇我们介绍了如何在 Mac 上搭建 Pulsar 集群,本文详细介绍如何在 3 台 Linux 服务器上搭建 ...

  2. k8s之搭建单机集群

    写在前面 本文一起看下如何在单机环境下搭建k8s集群. 基础环境准备参考这篇文章 . 1:k8s的前世今生 现在当我们提到容器技术时,首先想到的肯定是docker,但其实在docker之前,谷歌公司就 ...

  3. 单机上搭建Node集群

    搭建Node集群需要复制进程,而且通过主从模式并行处理业务.主进程不负责具体的业务处理,而是负责调度或管理工作进程,它是趋向于稳定的.工作进程负责具体的业务处理. 关于本 Node 进程的介绍请看No ...

  4. redis映射的概念_搭建分布式Redis Cluster集群与Redis入门

    目录 Redis 集群搭建Redis 是啥集群(Cluster)Redis Cluster 说明Redis Cluster 节点Redis Cluster 集群模式不能保证一致性创建和使用 Redis ...

  5. CentOS7上搭建Hadoop集群(入门级)

    场景 Hadoop Apache Hadoop是一款支持数据密集型分布式应用并以Apache 2.0许可协议发布的开源软 件框架,支持在商品硬件构建的大型集群上运行应用程序.Hadoop是根据Goog ...

  6. CentOS 7 上搭建 ZooKeeper 集群

    ZooKeeper 是什么? ZooKeeper 是分布式系统中的分布式协调服务,用于实现分布式同步,维护配置信息,分组和命名服务. 软件版本: CentOS 7.9 ZooKeeper 3.5.5 ...

  7. Linux上搭建伪集群 Hadoop3.1

    首先使用的是jdk1.8,将jdk 添加到环境变量中,hadoop 路径添加到环境变量中. vim /etc/profile #设置Hadoop环境变量 export HADOOP_HOME=/usr ...

  8. 在Hadoop集群上,搭建HBase集群

    (1)下载Hbase包,并解压:这里下载的是0.98.4版本,对应的hadoop-1.2.1集群 (2)覆盖相关的包:在这个版本里,Hbase刚好和Hadoop集群完美配合,不需要进行覆盖. 不过这里 ...

  9. 深入学习 Redis 之第 1 篇 —— Docker 安装 Redis 并搭建主从复制集群

    环境要求:CentOS7 X64 位,Redis6.0+ 理论基础 1.什么是 Redis 的主从复制? Redis 的复制功能支持多个库之间的数据同步.一类是主库(master),另一类是从库(sl ...

最新文章

  1. 前端技术学习之选择器(一)
  2. vb.net 设置打印纸张与页边距_文字办公—Word文档如何设置装订线
  3. python实现真正的冒泡排序算法(时间复杂度优化版)!
  4. 异步编程异常和死锁处理
  5. 安装nrm,报错request@2.88.2: request has been deprecated, see https://github.com/request/request/issu
  6. Linux Shell脚本之利用mysqldump备份MySQL数据库(详细注解)
  7. html 行级元素和块级元素标签列表分别有哪些
  8. dataGridView相关问题
  9. coldfusion php,在Coldfusion中加密,然后在PHP中解密
  10. GIT--使用流程规范
  11. 计算机想ping一下网络,电脑的Ping值和网络带宽之间有什么关系?
  12. canvas画一个渐变色的环形进度环
  13. day1—ECS阿里云云计算服务
  14. iOS开发——深拷贝与浅拷贝详解
  15. TCP/IP four-storey model
  16. 福昕PDF转Word转换器,让您毕业论文不用愁!
  17. LoadImage函数的用法
  18. 计算机开机跳过硬盘检查,快速取消Win7电脑开机自动检测硬盘的五大妙招
  19. GICv3软件overview手册之LPI(1)
  20. AC3简介及压制攻略 zz

热门文章

  1. Linux查看so库访问的IP,linux-ip命令杂记
  2. 计算机应用技术专业考试试题,全国专业技术人员计算机应用能力考试模拟试题笔试题.docx...
  3. websocket python unity_Unity 连接WebSocket(ws://)服务器
  4. 智能提示_文明放大镜·7 | 清新智能语音提示桩让你过马路除了看灯还可以听,赞...
  5. 分数的计算机应用教案,计算机应用实训实验
  6. spring实战(第4版读书笔记)
  7. C++栈与队列基本操作
  8. 对方启用和留言是什么意思_男子花八万元装修,装修到一半要求加价,对方:补给我一万两天就能装好...
  9. 游戏 mysql优化工具_MySQL 性能优化神器 Explain 使用分析
  10. android 相机和照片一起_Android相机开发(三): 实现拍照录像和查看