前面我写的一系列博客,如果你能够耐心看到这一篇,那你应该对一个概念就不是太陌生了:Deployment.

为什么提这个概念呢,这就要说到Deployment的一个不足了.Deployment不足以覆盖所有的应用编排问题,因为在它看来,一个应用的所有Pod,是完全一样的,所以它们之间就没有顺序,也无所谓运行在哪台宿主机上.需要时,Deployment就通过Pod模板创建新的Pod,不需要时,就"杀掉"任意一个Pod.

但是在实际场景中,并不是所有应用都满足这样的要求.比如:主从关系,主备关系,还有就是数据存储类应用,多个实例通常会在本地磁盘上保存一份数据,而这些实例一旦被杀掉,即使重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败.

这种实例之间有不对等关系,或者有依赖关系的应用,被称为"有状态应用"(Stateful Application)

为了能对"有状态应用"做出支持,Kubernetes在Deployment基础上,扩展出了:StatefulSet.

StatefulSet设计

StatefulSet将真实世界里的应用状态,抽象为了两种情况:

  • 1,拓扑状态.这种情况是说,应用的多个实例之间不是完全对等的关系.这些应用实例,必须按照某些顺序启动,比如某个应用的主节点A要先于B启动,那么当我把A和B两个节点删除之后,重新创建出来时,也要是这个顺序才行.并且,新创建出来的A和B,必须和原来的A和B网络标识一样,这样原先的访问者才能使用同样的方法,访问到这个新Pod.
  • 2,存储状态.这种情况是说,应用的多个实例分别绑定了不同的存储数据.对于这些应用实例来说,Pod A第一次读取到的数据,和隔了十分钟之后再次读取到的数据,应该是同一份,哪怕在此期间Pod A被重新创建过.

所以,StatefulSet的核心功能,就是通过某种方式,记录这些状态,然后在Pod被重新创建时,能够为新Pod恢复这些状态.

Headless Service

在深入了解StatefulSet之前,咱们先来讲讲Headless Service.

我们知道,Service是Kubernetes项目中用来将一组Pod暴露给外界访问的一种机制,比如,一个Deployment有3个Pod,那么我就可以定义一个Service,然后用户只要能访问到这个Service,就能访问到某个具体的Pod.

但是,这个Service是怎么被访问到的呢?

第一种方式,以Service的VIP(Virtual IP,即:虚拟IP)方式.比如:当我访问192.168.0.1这个Service的IP地址时,它就是一个VIP.在实际中,它会把请求转发到Service代理的具体Pod上.

第二种方式,就是以Service的DNS方式.在这里又分为两种处理方法:第一种是Normal Service.这种情况下,当访问DNS记录时,解析到的是Service的VIP.第二种是Headless Service.这种情况下,访问DNS记录时,解析到的就是某一个Pod的IP地址.

可以看到,Headless Service不需要分配一个VIP,而是可以直接以DNS记录的方式解析出被代理Pod的IP地址.这样设计有什么好处呢?

这样设计可以使Kubernetes项目为Pod分配唯一"可解析身份".而有了这个身份之后,只要知道了一个Pod的名字以及它对应的Service的名字,就可以非常确定地通过这条DNS记录访问到Pod的IP地址.

再回到StatefulSet

介绍完Headless Service之后,咱们再回来讲讲,StatefulSet的核心功能,是如何在Pod被重新创建时,能够为新Pod恢复这些状态.

为了详细讲解,现在编写一个StatefulSet的YAML文件,如下:

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.9.1
ports:
- containerPort: 80
name: web

可以看到,在这个YAML文件中,多了一个serviceName=nginx字段.这个字段的作用,就是告诉StatefulSet控制器,在执行控制循环时,要使用nginx这个Headless Service来保证Pod的"可解析身份."这样,在创建Pod过程中,StatefulSet给它所管理的所有Pod名字,进行编号,使得每个Pod实例不重复.而更重要的是,这些Pod的创建,也是严格按照编号顺序来进行的.

这样的意思就是说,当有主从关系时,有明确先后关系时,StatefulSet通过这种机制,使得先后创建顺序成为可能.

整个StatefulSet流程

接下来回顾一下整个流程.

首先,StatefulSet的控制器直接管理的是Pod,而StatefulSet区分这些实例的方式,就是通过在Pod的名字里面加上事先约定好的编号.

其次,Kubernetes通过Headless Service,为这些有编号的Pod,在DNS服务器中生成带有同样编号的DNS记录.只要StatefulSet能够保证这些Pod名字里的编号不变,那么Service中DNS记录也就不会变.

最后,StatefulSet还为每一个Pod分配并创建一个同样编号的PVC.这样就可以保证每个Pod都拥有一个独立的Volume.在这种情况下,即使Pod被删除,它所对应的PVC和PV依然会留下来,所以当这个Pod被重新创建出来之后,Kubernetes会为它找到同样编号的PVC,挂载这个PVC对应的Volume,从而获取到以前保存在Volume中的数据.

其实StatefulSet就是一种特殊的Deployment,只不过它的每个Pod都被编号了.正是由于这种机制,使得具有主从关系的创建成为可能.

关于StatefulSet相关内容到这里就介绍的差不多了.

以上内容来自我学习<深入剖析Kubernetes>专栏文章之后的一些见解,有偏颇之处,还望指出.

感谢您的阅读~

[Kubernetes]深入理解StatefulSet的更多相关文章

  1. Kubernetes系列(四) StatefulSet

    作者: LemonNan 原文地址: https://juejin.im/post/6870071267438329869 Kubernetes系列(四) StatefulSet Kubernetes ...

  2. 【K8s】Kubernetes架构理解

    抽空学习了一下Kubernetes,感觉和大数据领域内集群的资源管理.任务调度等有异曲同工之处,简单总结一下备忘. [概念] Kubernetes是一个工业级的容器编排平台,单词有点长,常用K8s代称 ...

  3. 说说你对kubernetes的理解(简单)

    目录 整体概述 pod工作流程 k8s网络 flannel 网络策略,network proxy 几套证书理解 组件 master管理节点上组件 node节点 整体概述 k8s是一个编排工具,是谷歌的 ...

  4. Kubernetes — 深入理解容器镜像

    而正如我前面所说的,Namespace 的作用是“隔离”,它让应用进程只能看到该 Namespace 内的“世界”:而 Cgroups 的作用是“限制”,它给这个“世界”围上了一圈看不见的墙.这么一折 ...

  5. Kubernetes:理解资源的概念

    不知你是否已清楚,Kubernetes 是支持 Docker 和 rkt(当前是这两种)的容器调度系统.除了下面这些优美的特性,比如简易部署,配置管理,服务发现,等等,它还允许我们以一种更高效的方式来 ...

  6. 架构图+kubernetes 问题理解 -- kube-pproxy - endpoint

    1.详述kube-proxy原理,一个请求是如何经过层层转发落到某个pod上的整个过程.请求可能来自pod也可能来自外部. 1.1kube-proxy为集群提供service功能,相同功能的pods对 ...

  7. [Kubernetes]关于 Kubernetes ,你想要的,都在这儿了

    陆陆续续,关于 Kubernetes 写了有 20+ 篇文章了. 今天这篇文章来一个整合,从实践到理论,可以按需查看(我是按照博客发表时间来排序的,如果后续有想要更新的内容,也会及时更新到这篇文章中) ...

  8. [Kubernetes]PV,PVC,StorageClass之间的关系详解

    在Kubernetes中,容器化一个应用比较麻烦的地方莫过于对其"状态"的管理,而最常见的"状态",莫过于存储状态. 在[Kubernetes]深入理解Stat ...

  9. 在Kubernetes上运行有状态应用:从StatefulSet到Operator

    一开始Kubernetes只是被设计用来运行无状态应用,直到在1.5版本中才添加了StatefulSet控制器用于支持有状态应用,但它直到1.9版本才正式可用.本文将介绍有状态和无状态应用,一个通过K ...

随机推荐

  1. JAVA的三个版本,JSE,JEE,JME三者之间的区别

    JAVA是一种面向对象语言由SUN公司出品 J针对不同的使用方向规划出JSE,JEE,JME三个版本 1.JSE 指标准版一般用于用户学习JAVA语言的基础也是使用其他两个版本的基础主要用于编写C/S ...

  2. RMQ 问题 ST 算法(模板)

    解决区间查询最大值最小值的问题 用 $O(N * logN)$ 的复杂度预处理 查询的时候只要 $O(1)$ 的时间  这个算法是 real 小清新了   有一个长度为 N 的数组进行 M 次查询 可 ...

  3. (一)jdk8学习心得之遍历

    一.遍历 -- 最好和stream流连用 使用jdk8提供的forEach进行遍历时,采用的是多线程的操作,理论上讲是会比原来的方法更快.但是注意,系统启动时需要加载lambda框架的内容.因此如果通 ...

  4. C#中字符串转日期类型

    1,yyyyMMdd DateTime date = DateTime.ParseExact(", "yyyyMMdd", System.Globalization.Cu ...

  5. Python——pyqt5——智能提示(lineEdit/conmbobox)

    一.文本框智能补全 completer = QtWidgets.QCompleter(data) completer.setCompletionMode(QtWidgets.QCompleter.Po ...

  6. Python——模块——fnmatch(文件名对比)

    一.模块作用 fnmatch 模块主要用于文件名的比较,使用 Unix shell 使用的 glob 样式模式. 二.简单匹配 fnmatch() 将单个文件名与模式进行比较并返回布尔值,来看它们是否 ...

  7. js slice 假分页

    语法 arrayObject.slice(start,end) 参数 描述 start 必需.规定从何处开始选取.如果是负数,那么它规定从数组尾部开始算起的位置.也就是说,-1 指最后一个元素,-2 ...

  8. htaccess 的使用基本小节 For apache httpd

    htaccess 的使用基本小节 For apache httpd .htaccess的基本作用 .htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令.       .ht ...

  9. 20165223《网络对抗技术》Exp5 MSF基础应用

    目录 -- MSF基础应用 实验说明 实验任务内容 基础问题回答 实验内容 主动攻击 ms17_10_eternalblue(成功) ms17_10_psexec(成功) ms08_067_netap ...

  10. python中的sequence(序列)

    摘要 这篇文章主要是为了让自己记住字典不是序列,python中序列的类型 序列化的定义 有个朋友问我,什么是序列化,我瞬间懵了,然后查了一下,发现廖雪峰老师给出了一个很舒服的解释: 序列化:我们把变量 ...