K8S的Pod类型-StatefulSet和Deployment区别与应用
ReplicaSet、ReplicationController、Deployment等,由于是无状态服务,所以这些控制器创建的pod序号都是随机值。并且在缩容的时候并不会明确缩容某一个pod,而是随机的,因为所有实例得到的返回值都是一样,所以缩容任何一个pod都可以。
1、通俗的服务状态
有了持久化存储 PersistentVolume,应用就可以把一些运行时的关键数据落盘,相当于有了一份“保险”,如果 Pod 发生意外崩溃,也只不过像是按下了暂停键,等重启后挂载 Volume,再加载原数据就能够满血复活,恢复之前的“状态”继续运行。
所以从这个角度来说,理论上任何应用都是有状态的。
只是有的应用的状态信息不是很重要,即使不恢复状态也能够正常运行,这就是我们常说的“无状态应用”。“无状态应用”典型的例子就是 Nginx 这样的 Web 服务器,它只是处理 HTTP 请求,本身不生产数据(日志除外),不需要特意保存状态,无论以什么状态重启都能很好地对外提供服务。
还有一些应用,运行状态信息就很重要了,如果因为重启而丢失了状态是绝对无法接受的,这样的应用就是“有状态应用”。
“有状态应用”的例子也有很多,比如 Redis、MySQL 这样的数据库,它们的“状态”就是在内存或者磁盘上产生的数据,是应用的核心价值所在,如果不能够把这些数据及时保存再恢复,那绝对会是灾难性的后果。
理解了这一点,我们结合目前学到的知识思考一下:Deployment 加上 PersistentVolume,在 Kubernetes 里是不是可以轻松管理有状态的应用了呢?
是的,这样是可以是实现的,用 Deployment 来保证高可用,用 PersistentVolume 来存储数据,确实可以部分达到管理“有状态应用”的目的。
但是, Kubernetes 的眼光则更加全面和长远,它认为“状态”不仅仅是数据持久化,在集群化、分布式的场景里,还有多实例的依赖关系、启动顺序和网络标识(例如PodIP的变化)等问题需要解决,而这些问题恰恰是 Deployment 力所不及的。
因为只使用 Deployment,多个实例之间是无关的,启动的顺序不固定,Pod 的名字、IP 地址、域名也都是完全随机的,这正是“无状态应用”的特点。
但对于“有状态应用”,多个实例之间可能存在依赖关系,比如 master/slave、active/passive,需要依次启动(这个时候就要保证PodIP是固定的)才能保证应用正常运行,外界的客户端也可能要使用固定的网络标识来访问实例,而且这些信息还必须要保证在 Pod 重启后不变。
所以,Kubernetes 就在 Deployment 的基础之上定义了一个新的 API 对象,名字也很好理解,就叫 StatefulSet,专门用来管理有状态的应用。
2、专业的服务状态
从数据层面看状态,数据的状态往往受2个维度有关,一是与时间相关或者顺序相关的,不同的操作顺序可能导致同一个时间点上的数据状态大于1个,二是与数据的副本状态相关的。也就是数据的位置,数据落在多个副本上,可能出现多种数据状态的组合。
从服务层面看,服务层面的状态取决于实例是单独维护数据还是共享数据,或者说是否存在多个数据闭环让数据的流向产生了多条路径。有状态的服务往往比较难进行水平拓展,在现在容器盛行的环境,把服务设计成无状态的更加高效,即便是有状态的服务,也要将状态内敛在系统的某个范围,比如分布式的存储,对于业务服务,我不需要关心数据在多个副本的状态,数据的状态由分布式存储这个服务本身解决。
差异维度 | 有状态服务 | 无状态服务 |
服务本身 | 服务本身依赖或者存在局部的状态数据,这些数据需要自身持久化或者可以通过其他节点恢复。 | 服务不依赖自身的状态,实例的状态数据可以维护在内存中。 |
节 点 | 一个请求只能被某个节点(或者同等状态下的节点)处理。 | 任何一个请求都可以被任意一个实例处理。 |
数据状态 | 存储状态数据,实例的拓展需要整个系统参与状态的迁移。 | 不存储状态数据,实例可以水平拓展,通过负载均衡将请求分发到各个节点。 |
系统中 | 在一个封闭的系统中,存在多个数据闭环,需要考虑这些闭环的数据一致性问题。 | 在一个封闭的系统中,只存在一个数据闭环。 |
架构中 | 通常存在于分布式架构中。 | 通常存在于单体架构的集群中。 |
相关资源 | statefulSet,由于是有状态的服务,所以每个pod都有特定的名称和网络标识。比如pod名是由statefulSet名+有序的数字组成(0、1、2..) | ReplicaSet、ReplicationController、Deployment等,由于是无状态服务,所以这些控制器创建的pod序号都是随机值。并且在缩容的时候并不会明确缩容某一个pod,而是随机的,因为所有实例得到的返回值都是一样,所以缩容任何一个pod都可以。 |
相关服务 | 有状态服务 可以说是 需要数据存储功能的服务、或者指多线程类型的服务,队列等。(mysql数据库、kafka、zookeeper等) | 多个实例可以共享相同的持久化数据。例如:nginx实例,tomcat实例等 |
更多推荐
所有评论(0)