什么是StatefulSet

StatefulSet 是Kubernetes中的一种控制器,他解决的什么问题呢?我们知道Deployment是对应用做了一个简化设置,Deployment认为一个应用的所有的pod都是一样的,他们之间没有顺序,也无所谓在那台宿主机上。需要扩容的时候就可以通过pod模板加入一个,需要缩容的时候就可以任意杀掉一个。但是实际的场景中,并不是所有的应用都能做到没有顺序等这种状态,尤其是分布式应用,他们各个实例之间往往会有对应的关系,例如:主从、主备。还有数据存储类应用,它的多个实例,往往会在本地磁盘存一份数据,而这些实例一旦被杀掉,即使从建起来,实例与数据之间关系也会丢失,而这些实例有不对等的关系,实例与外部存储有依赖的关系的应用,被称作“有状态应用”。StatefulSet与Deployment相比,相同于他们管理相同容器规范的Pod,不同的时候,StatefulSet为pod创建一个持久的标识符,他可以在任何编排的时候得到相同的标识符。

StatefulSet的应用特点:

  • 稳定且有唯一的网络标识符 当节点挂掉,既pod重新调度后其PodName和HostName不变,基于Headless Service来实现
  • 稳定且持久的存储  当节点挂掉,既pod重新调度能访问到相同的持久化存储,基于PVC实现
  • 有序、平滑的扩展、部署 即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现。
  • 有序、平滑的收缩、删除 既Pod是有顺序的,在收缩或者删除的时候要依据定义的顺序依次进行(既从N-1到0,既倒序)。

我们可以把这些抽象成两种应用状态:

  • 拓扑状态。是应用多个实例之间的不完全对等的关系,这些应用实例是必须按照定义的顺序启动的。例如主应用A先于从应用B启动,如果把A和B删掉,应用还要按照先启动主应用A再启动从应用B,且创建的应用必须和原来的应用的网络标识一样(既PodName和HostName)。这样他们就可以按照原来的顺序创建了。
  • 之间不是完全对等的关系

    极客时间版权所有: https://time.geekbang.org/column/article/41017

    存储状态。应用实例分别绑定了不同的数据存储,Pod A第一次读到的数据要和10分钟后读到的数据,是同一份。哪怕这期间Pod A被重建。这种典型的例子就是数据库应用的多个存储实例。

所以 StatefulSet的核心功能就是,通过某种方式记录应用状态,在Pod被重建的时候,通过这种方式还可以恢复原来的状态。

从上面的应用场景可以发现,StatefulSet由以下几个部分组成:

  • Headless Service 用于定义网络标识(DNS)
  • volumeClaimTemplates  用于创建PV
  • StatefulSet  用于定义具体应用

讲解Headless Service

我们知道kubernetes中的service是定义pod暴露外部访问的一种机制,例如:3个pod,我们可以定义一个service通过标签选择器选到这三个pod,然后让问这个service就可以访问这个pod。可以出门左转,看一下 Service的讲解。 我们这里具体讲一下Headless service。

Headless service是Service通过DNS访问的其中一种方式,只要我们访问"mypod.stsname.namespace.svc.cluster.local",我们就会访问到stsname下的mypod。而Service DNS的方式下有两种处理方法:

  • Normal Service 这里访问"mypod.stsname.namespace.svc.cluster.local"的时候会得到mypod的service的IP,既VIP。
  • Headless Service 这里访问"mypod.stsname.namespace.svc.cluster.local"的时候会得到mypod的IP,这里我们可以看到区别是,Headless Service 不需要分配一个VIP,而是通过DNS访问的方式可以解析出带代理的Pod的IP

Headleaa Service的定义方式:

apiVersion: v1
kind: Service
metadata:
name: myapp-headless
namespace: default
spec:
selector:
app: myapp
release: dev
clusterIP: "None"
ports:
- port:
targetPort:

Headless Service也是一个标准的Service的YAML文件,只不过clusterIP定义为None,既,这个service没有VIP作为"头"。以DNS会记录的方式记录所有暴露它代理的Pod。而它代理的Pod依然会采用标签选择器的机制选择。既:所有携带了 app=myapp 标签的pod。都会被service代理起来。

DNS格式:

pod-name.svc-name.namespace.svc.cluster.local

StatefulSet详解

kubectl explain sts.spec 主要字段解释:

  • replicas   副本数
  • selector  那个pod是由自己管理的
  • serviceName  必须关联到一个无头服务商
  • template 定义pod模板(其中定义关联那个存储卷)
  • volumeClaimTemplates  生成PVC

部署一个statefulset服务

这里我们用的storageClass,PV和PVC会动态创建。这个跑成功必须创建一个rook服务的动态存储,创建方法参考 rook官网。

apiVersion: v1
kind: Service
metadata:
name: myapp-sts
labels:
app: myapp-sts
spec:
ports:
- port:
name: web
clusterIP: "None"
selector:
app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp
spec:
serviceName: myapp-sts-svc
replicas:
selector:
matchLabels:
app: myapp-pod
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- containerPort:
name: web
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: myappdata
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "rook-ceph-block"
resources:
requests:
storage: 5Gi

查看一下服务

$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-sts ClusterIP None <none> /TCP 5m

查看pv/pvc

$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myappdata-myapp- Bound pvc-550493cf-dc1f-11e8-b8c9- 5Gi RWO rook-ceph-block 43m
myappdata-myapp- Bound pvc-5a4276b4-dc1f-11e8-b8c9- 5Gi RWO rook-ceph-block 43m
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-550493cf-dc1f-11e8-b8c9- 5Gi RWO Delete Bound default/myappdata-myapp- rook-ceph-block 43m
pvc-5a4276b4-dc1f-11e8-b8c9- 5Gi RWO Delete Bound default/myappdata-myapp- rook-ceph-block 43m

查看pod

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp- / Running 17h
myapp- / Running 17h

验证解析

$ kubectl exec -it myapp- -- /bin/sh
/ # nslookup myapp-.myapp-sts-svc.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve Name: myapp-.myapp-sts-svc.default.svc.cluster.local
Address : 10.244.3.37 myapp-.myapp-sts-svc.default.svc.cluster.local

扩容(扩展应该是按顺序扩展)

$ kubectl scale sts myapp --replicas=

$ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
myapp- / Running 18h
myapp- / Running 18h
myapp- / Pending 0s
myapp- / Pending 0s
myapp- / Pending 0s
myapp- / ContainerCreating 0s
myapp- / Running 15s
myapp- / Pending 0s
myapp- / Pending 1s
myapp- / Pending 1s
myapp- / ContainerCreating 1s
$ kubectl get pvc
NAME                STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
myappdata-myapp-0   Bound     pvc-550493cf-dc1f-11e8-b8c9-005056930126   5Gi        RWO            rook-ceph-block   18h
myappdata-myapp-1   Bound     pvc-5a4276b4-dc1f-11e8-b8c9-005056930126   5Gi        RWO            rook-ceph-block   18h
myappdata-myapp-2   Bound     pvc-25e46dbd-dcba-11e8-b8c9-005056930126   5Gi        RWO            rook-ceph-block   2m
myappdata-myapp-3   Bound     pvc-2f420e8c-dcba-11e8-b8c9-005056930126   5Gi        RWO            rook-ceph-block   1m
myappdata-myapp-4   Bound     pvc-4607d3c8-dcba-11e8-b8c9-005056930126   5Gi        RWO            rook-ceph-block   1m

缩容 (按倒序缩容)

$ kubectl scale sts myapp --replicas=

$  kubectl get pod -w
NAME READY STATUS RESTARTS AGE
myapp- / Running 18h
myapp- / Running 18h
myapp- / Running 3m
myapp- / Running 3m
myapp- / Running 2m
myapp- / Terminating 2m
myapp- / Terminating 2m
myapp- / Terminating 2m
myapp- / Terminating 2m
myapp- / Terminating 3m
myapp- / Terminating 3m
myapp- / Terminating 3m
myapp- / Terminating 3m

升级

查看升级策略

kubectl explain sts.spec.updateStrategy

  • rollingUpdate  滚动更新

kubectl explain sts.spec.updateStrategy.rollingUpdate

  • partition  分区更新,默认partition的值是0,当partition等N,N+的都会更新。

默认partition是从0开始更新

当partition等于4的时候,4以后的都要更新。

$ kubectl set image sts/myapp myapp=ikubernetes/myapp:v2
$ kubectl describe pod myapp-
Name: myapp-
Namespace: default
Priority:
PriorityClassName: <none>
Node: k8s-node01/172.16.138.41
Start Time: Thu, Nov :: -
Labels: app=myapp-pod
controller-revision-hash=myapp-5775ff7474
statefulset.kubernetes.io/pod-name=myapp-
Annotations: <none>
Status: Running
IP: 10.244.1.13
Controlled By: StatefulSet/myapp
Containers:
myapp:
Container ID: docker://75d5e6b3958f053908eb3e5fa1c2846ce91d90c9ff696f27e6220a66d2e8cc7c
Image: ikubernetes/myapp:v2
Image ID: docker-pullable://ikubernetes/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358
Port: /TCP
Host Port: /TCP
.....

Normal Service

极客时间版权所有

Kubernetes之StatefulSet的更多相关文章

  1. Kubernetes中StatefulSet介绍

    StatefulSet 是Kubernetes1.9版本中稳定的特性,本文使用的环境为 Kubernetes 1.11.如何搭建环境可以参考kubeadm安装kubernetes V1.11.1 集群 ...

  2. kubernetes之StatefulSet详解

    系列目录 概述 RC.Deployment.DaemonSet都是面向无状态的服务,它们所管理的Pod的IP.名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所 ...

  3. kubernetes之StatefulSet部署zk和kafka

    前提 至少需要三个node节点,否则修改亲和性配置 如果外部访问,需要自己暴露 需要有个storageClass,这样做的原因是避免手动创建pv了 部署zk和kafka 参考: https://www ...

  4. 图解kubernetes控制器StatefulSet核心实现原理

    StatefulSet是k8s中有状态应用管理的标准实现,今天就一起来了解下其背后设计的场景与原理,从而了解其适用范围与场景 1. 基础概念 首先介绍有状态应用里面的需要考虑的一些基础的事情,然后在下 ...

  5. 12 . Kubernetes之Statefulset 和 Operator

    Statefulset简介 k8s权威指南这样介绍的 "在Kubernetes系统中,Pod的管理对象RC.Deployment.DaemonSet和Job都面向无状态的服务.但现实中有很多 ...

  6. kubernetes使用statefulset部署mongoDB 单机版 自定义配置文件、密码等

    注: 官方镜像地址: https://hub.docker.com/_/mongo?tab=description docker版的mongo移除了默认的/etc/mongo.conf, 修改了db数 ...

  7. 9、kubernetes之statefulset控制器

    一.StatefulSet 有状态副本集 必要的三个组件:headless service.StatefulSet.volumeClaimTemplate 准备pv apiVersion: v1 ki ...

  8. kubernetes的Statefulset介绍

    StatefulSet是一种给Pod提供唯一标志的控制器,他可以保证部署和扩展的顺序. Pod一致性 包含次序(启动和停止次序).网络一致性.此一致性和Pod相关.与被调度到哪个Node节点无关. 稳 ...

  9. StatefulSet: Kubernetes 中对有状态应用的运行和伸缩

    在最新发布的 Kubernetes 1.5 我们将过去的 PetSet 功能升级到了 Beta 版本,并重新命名为StatefulSet.除了依照社区民意改了名字之外,这一 API 对象并没有太大变化 ...

随机推荐

  1. Linux常见系统故障

    Linux常见系统故障 1.修复MBR扇区故障 2.修复GRUB引导故障 3./etc/inittab文件丢失 4.遗忘root用户密码 5.修复文件系统 6.磁盘资源耗尽故障 一.修复MBR扇区故障 ...

  2. Ubuntu 16.04 使用校园网客户端上网

    对于使用校园网的学生来说,安装好Ubuntu之后,很多人需要用 DrClient 客户端来上网,那么怎么操作呢, 这里介绍 DrClient 客户端在Ubuntu上的使用方法, 首先下载 对应版本的软 ...

  3. 如何在 windows server 2008 上面 挂载NFS

    首先, 你在一台服务器上面配置好NFS 服务器:然后按照一下步骤: mounting the nfs on windows server 2008 r2: open Windows Server 的D ...

  4. Python开发【第二篇】运算符

    "+" 加号 __author__ = 'Tang' a = 8 b = 9 c = a + b a = 8.0 b = 9 c = a + b print(c) # 17.0 a ...

  5. windows环境:idea或者eclipse指定用户名操作hadoop集群

    方法 在系统的环境变量或java JVM变量添加HADOOP_USER_NAME(具体值视情况而定). 比如:idea里面可以如下添加HADOOP_USER_NAME=hdfs 原理:直接看源码 /h ...

  6. 转://看懂Oracle中的执行计划

    一.什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二.怎样查看Oracle执行计划? 2.1 explain plan for命令查看执行计划 在sq ...

  7. bzoj3122 [SDOI2013]随机数生成器

    bzoj3122 [SDOI2013]随机数生成器 给定一个递推式, \(X_i=(aX_{i-1}+b)\mod P\) 求满足 \(X_k=t\) 的最小整数解,无解输出 \(-1\) \(0\l ...

  8. SkylineGlobe 7.0.1 & 7.0.2版本Web开发 如何实现土方量计算

    土方量计算,或者叫填挖方计算,体积计算,Skyline在很早的版本中就提供了这个的功能. 目前的软件版本,不仅仅可以对地形修改对象进行土方量计算,还可以在FLY工程中导入DEM数字高程模型数据,计算不 ...

  9. rocketmq 4.4部署安装

    官网下载:rocketmq-all-4.4.0-bin-release.zip 准备环境:centos7.6 Maven Java8+ 操作: 在工作目录中进行如下操作: /home/software ...

  10. 拜托!面试请不要再问我Spring Cloud底层原理

    概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...