StatefulSet介绍

从1.9 GA版本开始,StatefulSet成为kubernetes的稳定特性。StatefulSet是一种副本控制器,管理pod的部署、缩放等。与ReplicaSet、Deployment不同的是,它对集合中的pod提供顺序、唯一性保证。StatefulSet为集合中的每个pod分配唯一、持久的pod名称、DNS解析、持久化存储,并且负责将这些标识粘在pod上,无论pod调度到任何节点上。

什么时候需要使用StatefulSet

当应用的需求,与下述中的一条或者多条相符时,使用StatefulSet就会有价值:

  • 唯一、稳定的网络标识(pod原本没有网络标识,service有)。
  • 稳定、持久化存储。
  • 多个副本有序、优雅的部署与缩放。
  • 多个副本有序、优雅的部署与缩放。
  • 多个副本有序、优雅的自动滚动升级。

StatefulSe限制

  • StatefulSet特性,1.5之前的版本不可用,1.9之前的版本不稳定。
  • 必需为pod提供持久化存储。
  • 删除或者缩容StatefulSet时,出于数据安全的目的,不会自动删除与pod相关的持久化存储,需要手动处理。
  • 当前StatefulSet需要通过无头服务为其所管理的pod提供网络标识,或者说DNS条目,用户需手动创建无头服务。

唯一、稳定pod名称

StatefulSet中的pod名称由StatefulSet配置中的name加上表示序号的整数,整数从0开始取值,最大值为副本数量减1.

唯一、稳定网络ID

StatefulSet通过与其相关的无头服务为每个pod提供DNS解析条目。假如无头服务的DNS条目为:
"$(service name).$(namespace).svc.cluster.local",
那么pod的解析条目就是"$(pod name).$(service name).$(namespace).svc.cluster.local",每个pod name也是唯一的。

稳定持久存储

通过 PersistentVolume 提供持久化存储。

创建StatefulSet

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
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: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

上述文件包含两个对象,前边名为nginx的service,其clusterIP为None,所以它是无头服务。下边为名web的StatefulSet,其.spec.serviceName的值为nginx,指明通过上边的nginx无头服务提供DNS解析功能功。.spec.volumeClaimTemplates表示持久化存储。将以上内容保存在web.yaml文件中。

执行创建命令:

kubectl create -f web.yaml 
service "nginx" created
statefulset "web" created

确认结果:

kubectl get service nginx
NAME      CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx     None         <none>        80/TCP    12s
kubectl get statefulset web
NAME      DESIRED   CURRENT   AGE
web       2         1         20s

如果从另一个终端监控StatefulSet创建过程,会看到如下内容:

kubectl get pods -w -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     0/1       Pending   0          0s
web-0     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         19s
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         18s

两个pod,web-0与web-1按序创建,web-0必须先创建并且处于就绪状态后才可以创建web-1。

创建完成后,执行如下命令确认pod名称:

kubectl get pods -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          1m
web-1     1/1       Running   0          1m

运行如下命令检查pod的名称在集群内是否可以解析:

kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh 
nslookup web-0.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name:      web-0.nginx
Address 1: 10.244.1.6
nslookup web-1.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name:      web-1.nginx
Address 1: 10.244.2.6

测试pod名称、DNS解析条目的粘性。先将pod删除,然后StatefulSet自动恢复缺失副本,再对比新pod与已删除pod的标识是否一致。

kubectl delete pod -l app=nginx
pod "web-0" deleted
pod "web-1" deleted

在另一个终端中监控StatefulSet自动恢复过程:

kubectl get pod -w -l app=nginx
NAME      READY     STATUS              RESTARTS   AGE
web-0     0/1       ContainerCreating   0          0s
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          2s
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         34s

运行如下命令:

for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1
kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh 
nslookup web-0.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name:      web-0.nginx
Address 1: 10.244.1.7
nslookup web-1.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name:      web-1.nginx
Address 1: 10.244.2.8

可以看到新pod的名称、主机名称、DNS解析条目都没有变,这些标识被粘在新pod上。但是pod的IP地址变了,所以当在集群中访问pod时,不要直接通过不稳定的IP。

运行如下命令查看持久化存储:

kubectl get pvc -l app=nginx
NAME        STATUS    VOLUME                                     CAPACITY   ACCESSMODES   AGE
www-web-0   Bound     pvc-15c268c7-b507-11e6-932f-42010a800002   1Gi        RWO           48s
www-web-1   Bound     pvc-15c79307-b507-11e6-932f-42010a800002   1Gi        RWO           48s

首先需要配置好集群内的持久化存储功能,以上几个volume在创建 StatefulSet时自动创建、命名、绑定到pod。默认情况下nginx的"/usr/share/nginx/html/index.html"位于以上的持久存储中。运行如下代码修改index.html文件:

for i in 0 1; do kubectl exec web-$i -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html'; done
for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
web-0
web-1

再一次删除pod,确认持久存储是否生效,在旧pod中写入index.html的内容是否被保留到新pod中。删除、监控过程不表,直接确认结果:

for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
web-0
web-1

结果证明文件内容没有丢失。

StatefulSet的扩容、缩容、滚动升级、删除操作与Deployment、ReplicaSet相似,不同之处是StatefulSet保证pod被按顺序操作。

参考: https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/

StatefulSet介绍从1.9 GA版本开始,StatefulSet成为kubernetes的稳定特性。StatefulSet是一种副本控制器,管理pod的部署、缩放等。与ReplicaSet、Deployment不同的是,它对集合中的pod提供顺序、唯一性保证。StatefulSet为集合中的每个pod分配唯一、持久的pod名称、DNS解析、持久化存储,并且负责将这些标识粘在pod上,无...
文章目录一: k8s 的五种控制器1.1: k8s 的控制器类型1.2:Deployment控制器1.2.1:测试deployment控制器1.3:Satef ulSe t控制器1.3.1:创建无头服务的service资源和dns资源1.3.2:创建 state f ulse t资源1.4:DaemonSet控制器1.4.1:测试1.5:job控制器1.5.1:测试1.6:cronjob控制器1.6.1:测试如有疑问可评论区交流! 一: k8s 的五种控制器 1.1: k8s 的控制器类型 Kubernetes 中内建了很多contr
State f ulSe t(一) ​ Deployment 假设了一个应用的所有Pod都是一样的,他们之间没有顺序。但在实际场景中,多个实例之间通常会存在依赖关系,例如分布式应用中存在主从、主备关系;数据存储类应用,它的多个实例,往往都会在本地磁盘上保存一份数据。而这些实例一旦被杀掉,即便重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。 ​ 当实例之间有不对等关系时,以及实例对外部数据有依赖关系时,被称为“有 状态 应用”( State ful Application) State f ulSe t将应用
大家可能已知道, 所谓无 状态 :“每一次请求都不依赖历史数据,也无数据持久化需求,扩容简单,即扩即用”。 说人话就是“只是个传声筒,左耳进右耳出,不往脑子里去。 就算复制N个传声筒,其工作内容也是完全一致的”。 所谓有 状态 :“依赖历史数据,且具有数据持久化需求,扩容后续工作复杂”。 数据库为有 状态 的典型,若复制出N个数据库,就涉及master/slave角色分担,底层数据同步的工作。 那么在 k8s 中,在2种工作负载的调度有何异同? 均以con State f ulSe t 前几篇讲解的都是关于无 状态 的应用, 今天这篇介绍 Kubernetes 中的另一种应用, 有 状态 应用, 而 有 状态 的应用是由 State f ulSe t 来进行管理部署 , ** State f ulSe t 也是 kubernetes 中的一种资源类型, 作用类似于无 状态 应用的 Deployment **. 操作的基础 最近的文章都是基于 minikube 进行.
文章目录 State f ulSe t使用场景限制创建 State f ulSe tPod标识稳定的网络标识稳定的持久化存储有序的部署和扩缩更新策略 State f ulSe t Deployment是面向无 状态 的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的。 但是在部署像MySQL、MongoDB这类的集群时,Deployment明显就有些不合适了。因此 kubernetes 提供了Seatef ulSe t,它是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有 状态 服务的问题,它所管理的Pod
podApi对象概览 apiVersion + kind 一个是版本 一个是资源组 共同确定当前yaml由谁来管理 metadata元数据 用来唯一标识 该资源 在 k8s 中一个对象 是通过标签选择另外一个对象的 spec 标示容器期望的 状态 status 状态 只读的 RC、Deployment、DaemonSet都是面向无 状态 的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而 State f ulSe t是什么?顾名思义,有 状态 集合 ,管理所有有 状态 的服务,比如MySQL、MongoDB集群等。 State f ulSe t本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有 状态 服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在 State f ulSe t中,Pod名字称为网络标识
Kubernetes 的世界中,ReplicaSet和Deployment主要用于处理无 状态 的服务,无 状态 服务的需求往往非常简单并且轻量,每一个无 状态 节点存储的数据在重启之后就会被删除,虽然这种服务虽然常见,但是我们仍然需要有 状态 的服务来实现一些特殊的需求, State f ulSe t 就是 Kubernetes 为了运行有 状态 服务引入的资源,例如 Zookeeper、Kafka 等。 这篇文章会介绍 Kubernetes 如何在集群中运行有 状态 服务,同时会分析这些有 状态 服务 State f ulSe t ...