极牛技术分享活动极牛技术实践分享系列是极牛联合顶级VC和技术专家为企业和技术人员提供的系统性线上技术分享活动。每期不同技术话题,与行业专家深入探讨,着力解决技术难点,推动技术创新。通过鸡牛在线技术分享群,隔周三20点准时开课。欢迎各院校、企业的行业专家和技术人员报名。本期话题为Kubernetes有状态集群服务部署与管理嘉宾介绍张守宏,从事软件研发十余年,目前从事基于Kubernetes的企业级容器云平台研发。Docker和Kubernetes,主要包括容器服务、存储服务、CI/CD和镜像服务等。在加入SpeedCloud之前,先后在CATechnologies和Symantec担任TechLead和PrincipalSoftwareEngineer。参与研发的软件产品包括:企业数据保护软件、云平台服务管理系统、企业客服平台等。摘要:在容器化时代,除了Web服务器等无状态容器服务,用户越来越多地使用容器来部署有状态的应用程序,例如MySQL、Redis和Cassandra。这些Pets(运行有状态服务的容器,需要特殊处理)带来了新的需求,包括更长的生命周期、配置依赖、有状态故障转移等。张守宏讲师深入介绍了Kubernetes如何满足容器编排系统有状态集群服务的新需求,包括如何利用Kubernetes的动态存储请求和分配机制实现服务状态的持久化存储,以及如何高效部署并运行有状态集群服务相关的Kubernetes新特性,如InitContainer、PetSet(StatefulSet)等。最后通过一个MySQL集群实例,介绍如何在Kubernetes中轻松部署一个高可用的有状态集群服务,并实现自动化管理。大纲:Kubernetes简介及运行有状态集群服务的挑战Kubernetes存储系统Kubernetes有状态集群服务相关特性实践:在Kubernetes上部署和管理MySQL集群大家晚上好,我是SpeedCloud的张守宏,很高兴我有有机会和大家分享这个关于容器云的技术分享。在容器化时代,除了Web服务器等无状态容器服务,用户越来越多地使用容器来部署有状态应用,这对容器编排系统提出了新的要求。今天要和大家分享的话题是如何在当前主流的容器云平台Kubernetes上部署和管理有状态的集群服务。这次分享的关键词有两个:一个是Kubernetes,一个是有状态的集群服务。在第一部分中,我们将了解什么是Kubernetes以及运行有状态集群服务的一些挑战。在接下来的两部分中,我们将重点介绍Kubernetes如何应对这些挑战,以及使用哪些特性来解决有状态集群服务特有的一些问题。最后一部分是实战部分,以MySQL集群为例,展示如何在Kubernetes上轻松部署和管理一个有状态的集群服务。什么是Kubernetes?总之,Kubernetes是一个运行和管理容器的平台。它在Docker和rkt等容器运行时之上实现容器集群和高可用性。Kubernetes,简称K8S,来自谷歌,支持多种云计算环境,100%开源。它是CloudNativeComputingFoundation的一部分,使用Go语言开发。Kubernetes的一些基本概念:其中一个核心概念是Pod,它是Kubernetes对容器的封装,是Kubernetes管理的最小单元。Pod是通过Deployment部署的,Deployment会创建一个ReplicaSet来保证Pod的数量永远是一个指定的值。Pod一般不直接对外提供服务,而是通过Service提供稳定的访问接口,一个Service可以挂载多个Pod实例。Service是如何找到它匹配的Pod的?依靠标签。Label是连接各种K8S资源的链接。ReplicaSet还通过Labels与其管理的Pod相关联。如果Pod中的容器运行有状态服务,如数据库、缓存等,还需要挂载存储卷来存储服务状态。解释完原理,我们来看一个例子:这是一个运行在K8S集群中的容器化应用案例。这个应用程序有自己的web客户端,也从Twitter收集数据,处理后存储在自己的DB中。可以看到容器中运行着两种类型的服务,无状态的和有状态的。当web服务器、流处理器等无状态服务出现问题时,可以直接杀掉,重新创建,非常好管理。但是对于有状态的服务,比如数据库,它需要更长的生命周期。以集群为例,集群成员之间如何维持稳定的成员关系?这些都对容器编排系统提出了新的挑战。K8S如何应对这些挑战?K8S运行的服务从简单到复杂分为三类:无状态服务、普通有状态服务和有状态集群服务。下面我们来看看K8S是如何运行这三类服务的。对于无状态服务,K8S使用RC(或更新后的ReplicaSet)来保证服务的实例数。通过Service提供稳定的访问接口。普通的有状态服务对状态保存的要求更高。Kubernetes提供了基于Volume和PersistentVolume的存储系统,可以实现服务的状态保存。状态集群服务,对集群管理有额外的要求。为此,K8S开发了一套以PetSet为核心的新特性,方便在K8S上部署和管理有状态的集群服务。我们来看看Kubernetes是如何满足“状态保存”的需求的。K8S存储系统大致分为三个层次:普通卷、持久卷和动态存储配置。普通卷普通卷,最简单的就是“单节点存储卷”。类似于Docker的存储卷,使用Pod所在K8S节点的本地目录。有两种,一种是emptyDir,是一个匿名的空目录,Kubernetes在创建Pod时创建,删除Pod时删除。另一个是hostPath,它与emptyDir不同的是它独立存在于Pod之外,路径名由用户指定。这种节点绑定的存储卷在Pod迁移到另一个节点后会丢失数据,因此只能用于存储临时数据或在同一Pod的容器之间共享数据。普通卷,第二种是“跨节点存储卷”。这种存储卷不绑定到具体的K8S节点,而是独立于K8S节点而存在。由于跨节点存储卷可以在任何Kubernetes节点上访问,并且更加灵活,因此被广泛使用。Kubernetes上的Volume是通过插件实现的,因此具有很强的可扩展性。目前几乎所有的主流存储都有对应的插件来支持Kubernetes。如果现有存储不能满足要求,也可以开发自己的卷插件。持久卷和普通卷有什么区别?公共卷和使用它的Pod之间存在静态绑定关系。我们不能单独创建一个commonvolume,因为它不是一个独立的K8S资源对象。而PersistentVolume简称PV,是一个K8S资源对象,所以我们可以单独创建。它与Pod没有直接关系,而是通过PersistentVolumeClaim实现动态绑定,简称PVC。动态绑定过程是怎样的?这就是PV的生命周期。首先是Provision,就是创建PV。这里创建PV有两种方式,静态的和动态的。静态方式是管理员手动创建一堆PV,组成一个PV池,供PVC绑定。在动态模式下,存储系统根据PVC要求自动创建一个称为存储类的对象。一个PV创建后,它的状态会变为Available,等待被一个PVC绑定。一旦被PVC绑定,PV的状态就会变成Bound,可以被对应的Pod使用。Pod用完后,PV会被释放,PV的状态会变成Released。成为Released的PV会根据定义的回收策略做相应的回收工作。回收策略有Retain、Delete和Recycle三种。Retain就是保留场景,K8S什么都不做。删除策略,K8S会自动删除PV和里面的数据。在Recycle方法中,K8S会删除PV中的数据,然后将PV的状态变为Available,可以被新的PVC绑定使用。动态方式是通过StorageClass完成的,这是一种新的存储配置方式。使用StorageClass有什么好处?除了由存储系统动态创建,节省管理员时间外,另一个好处是可以封装不同类型的存储,供PVC选择。比如这里有两个StorageClass,都使用了Google的存储系统,但是有一个使用的是普通的slow磁盘。另一个使用SSD,命名为fast。在PVC中,通过注解指定存储类的名称为fast,这样PVC就会绑定SSD而不是普通磁盘。好了,Kubernetes整个存储系统就介绍到这里了。让我们进入Kubernetes的两个与有状态集群服务相关的新特性:InitContainer和PetSet。什么是初始化容器?从名字上看,就是做初始化工作的容器。可以有一个,也可以有多个,这些InitContainer按照定义的顺序依次执行,只有所有的InitContainer执行完毕,主容器才会启动。由于Pod中的存储卷是共享的,因此InitContainer中产生的数据可以被主容器使用。InitContainer的使用示例本示例创建一个Pod,Pod运行一个nginx容器。Pod中有一个名为workdir的存储卷。当访问nginx容器服务时,会显示这个存储卷中的索引。html文件。而这个index.html文件是通过一个busybox初始化容器得到的。介绍完InitContainer,万众期待的出来了,今天的主角PetSet就出来了。什么是宠物套装?顾名思义就是宠物的集合,那么什么是宠物呢?这是一个需要特别照顾的豆荚。它有一个状态,一个身份,当然它比普通的Pod更复杂。具体来说,Pet具有三个特点:第一,存储稳定,这是通过我们前面介绍的PV/PVC来实现的。二是稳定的网络身份,这是通过一种叫做HeadlessService的特殊服务实现的。与普通Service相比,HeadlessService没有ClusterIP,ClusterIP用于为集群内的每个成员提供唯一的DNS名称,用于集群内成员之间的通信。三是序号命名规则。比如PetSet的名字是mysql,那么第一个激活的Pet就叫mysql-0,第二个叫mysql-1,以此类推。当一个Pet宕机时,新创建的Pet会被赋予与原来Pet相同的名字,名字可以匹配到原来的存储中,从而实现状态保存。好了,有状态服务集群服务相关的K8S特性就介绍到这里了。理论说完了,下面进入实战。以GaleraMySQL集群为例,介绍如何在Kubernetes上部署和管理一个有状态的集群服务。首先对GaleraMySQL有个大概的了解:![图片上传中...]不是主从集群,而是多Master集群。GaleraReplication将多个MySQL实例连接起来形成一个集群。GaleraReplication负责节点间的数据同步。用户可以连接任意节点进行读写操作。每次写入的数据都会通过GaleraReplication同步到整个集群,才算写入成功。节点之间没有数据延迟。节点发生故障后,可以直接退出集群,无需故障转移。如何在Kubernetes上部署运行?这是整体结构图:左边的HeadlessService用于为每个MySQLPet实例提供DNS名称,右边的??PVpool为MySQL提供存储。这里有两个初始化容器,第一个用来安装需要的文件,第二个做MySQL的初始化。PetSet中有多个Pet,每个Pet对应MySQL集群中的一个节点。整个MySQL集群都可以通过PetSet进行管理。具体部署MySQL集群的YAML文件是右边一个名为galera的HeadlessService,左边是PetSet,右边是使用Headless服务。Replicas的数量为3,将创建3个Pets。PetSet的注解定义了两个初始化容器:Install容器安装的文件可以被bootstrap容器使用;同时,bootstrap容器生成的MySQL配置文件会放在config存储卷中,供后续的MySQL容器使用。除了常规端口3306外,主容器GaleraMySQL的定义还暴露了一些其他端口,用于集群内的数据同步、状态传递等操作。MySQL启动参数中使用的文件在初始化容器中生成,并通过共享存储卷传递。数据存储卷的定义这里定义了三个存储卷,其中config和workdir是简单的本地目录,datadir是一个PVC,可以绑定到PV来存储MySQL数据库数据。所以部署一个集群只需要两个YAML文件,一个HeadlessService和一个PetSet。其中,初始化容器和存储卷定义在PetSet中。通过以上方式部署好MySQL集群后,后续的运维工作就比较简单了。如果某个集群节点因为某种原因崩溃了,Kubernetes会自动创建一个新的Pet来代替它,实现自动恢复。如果要扩容或缩容,也是指定这个PetSet的Replicas数量的命令。如果要升级,只需要修改PetSet定义中podTemplate的image值,然后删除旧的Pet,新创建的Pet会是最新版本。对于在Kubernetes上部署有状态集群服务,我们补充两点:第一点,在最新的Kubernetes1.5版本中,PetSet更名为StatefulSet。因此,根据您使用的K8S版本,您可能会看到不同的名称。第二点简单介绍一下极速云提供的有状态集群服务:数据库和缓存。对于服务的创建,用户不再需要了解我们之前介绍的所有技术术语,而只需要指定副本数量和存储大小。最后拿下图作为今天分享内容的总结:有状态的集群服务有两个需求:一个是存储需求,一个是集群需求。对于存储需求,Kubernetes的解决方案有:Volume、PersistentVolume。对于PV,除了手动创建PVpool外,还可以使用StorageClass让存储系统自动创建。对于集群需求,Kubernetes的解决方案是PetSet。PetSet使用InitContainer初始化集群,使用HeadlessService为集群成员提供稳定的网络身份。最后,我们以MySQL集群为例,说明如何在Kubernetes上部署和运行一个有状态的集群服务。目前,在Kubernetes上部署有状态集群服务还没有正式开始,但是已经完全可用了。如果你的项目有容器化需求,可以试试。Q&AQ1:容器中的数据应该存储在镜像中还是宿主机中?A1:通常数据存储在一个独立的存储设备中,容器通过Volume挂载使用。简单存储也可以使用宿主的目录。Q2:如何监控k8sResource?A2:有专门的容器监控工具,比如PrometheusQ3:Kubernetes和Mesos有什么区别,如何选择?A3:Kubernetes是为容器集群而生的。除了容器集群之外,Mesos还可以用于传统集群。如果是纯容器云环境,推荐K8S。Q4:什么样的业务量下适合使用Kubernetes?A4:K8S来自谷歌。已通过谷歌内部量产环境测试。普通公司的业务量不是问题。Q5:k8s和swarm在实际生产环境中的优缺点是什么,如何选择正确的模型?A5:swarm是docker原生的容器管理系统,但是相对于K8S来说比较新,还不是很成熟。生产环境目前推荐使用K8S。技术分享请关注鸡牛公众号回复
