Kubernetes控制器之StatefulSet

  参考:https://kubernetes.io/zh/docs/concepts/workloads/controllers/statefulset/

    https://www.kubernetes.org.cn/deployment

  StatefulSet

  StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
  • 有序收缩,有序删除(即从N-1到0)

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

  • 用于定义网络标志(DNS domain)的Headless Service
  • 用于创建PersistentVolumes的volumeClaimTemplates
  • 定义具体应用的StatefulSet

  StatefulSet中每个Pod的DNS格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local,其中

  • serviceName为Headless Service的名字
  • 0..N-1为Pod所在的序号,从0开始到N-1
  • statefulSetName为StatefulSet的名字
  • namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace
  • .cluster.local为Cluster Domain 默认域就是cluster.local

  限制

  • 给定 Pod 的存储必须由 PersistentVolume 驱动 基于所请求的 storage class 来提供,由管理员预先提供。
  • 删除或者收缩 StatefulSet 并不会删除它关联的存储卷。这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
  • StatefulSet 当前需要 headless 服务 来负责 Pod 的网络标识。您需要负责创建此服务。
  • 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。为了实现 StatefulSet 中的 Pod 可以有序和优雅的终止,可以在删除之前将 StatefulSet 缩放为 0。
  • 在默认 Pod 管理策略(OrderedReady) 时使用 滚动更新,可能进入需要 人工干预 才能修复的损坏状态。

  组件

  下面的示例演示了 StatefulSet 的组件。

# cat web.yaml
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:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        #image: k8s.gcr.io/nginx-slim:0.8
        image: lowyard/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "managed-nfs-storage"
      resources:
        requests:
          storage: 1Gi
  • 名为 nginx 的 Headless Service 用来控制网络域名。
  • 名为web的StatefulSet .spec.replicas表明独立的3个Pod副本启动nginx容器
  • volumeClaimTemplates 将通过 PersistentVolumes 驱动提供的 PersistentVolumes 来提供稳定的存储。需要由管理员事先创建,本次创建的是NFS存储创建参考:https://www.cnblogs.com/minseo/p/12456987.html

  Pod选择器

  必须设置StatefulSet的.spec.selector字段,使之匹配其在.spec.template.metadata.labels 中设置的标签。在 Kubernetes 1.8 版本之前,被忽略 .spec.selector 字段会获得默认设置值。在 1.8 和以后的版本中,未指定匹配的 Pod 选择器将在创建 StatefulSet 期间导致验证错误。

  Pod标识

  StatefulSet Pod 具有唯一的标识,该标识包括顺序标识、稳定的网络标识和稳定的存储。该标识和 Pod 是绑定的,不管它被调度在哪个节点上。

  有序索引

  对于具有 N 个副本的 StatefulSet,StatefulSet 中的每个 Pod 将被分配一个整数序号,从 0 到 N-1,该序号在 StatefulSet 上是唯一的。

  稳定的网络 ID

  StatefulSet 中的每个 Pod 根据 StatefulSet 的名称和 Pod 的序号派生出它的主机名。组合主机名的格式为$(StatefulSet 名称)-$(序号)。上例将会创建三个名称分别为 web-0、web-1、web-2 的 Pod

  StatefulSet 可以使用 headless 服务 控制它的 Pod 的网络域。管理域的这个服务的格式为: $(服务名称).$(命名空间).svc.cluster.local,其中 cluster.local 是集群域。 一旦每个 Pod 创建成功,就会得到一个匹配的 DNS 子域,格式为:$(pod 名称).$(所属服务的 DNS 域名),其中所属服务由 StatefulSet 的 serviceName 域来设定。

  下面给出一些选择集群域、服务名、StatefulSet 名、及其怎样影响 StatefulSet 的 Pod 上的 DNS 名称的示例:

Cluster Domain Service (ns/name) StatefulSet (ns/name) StatefulSet Domain Pod DNS Pod Hostname
cluster.local default/nginx default/web nginx.default.svc.cluster.local web-{0..N-1}.nginx.default.svc.cluster.local web-{0..N-1}
cluster.local foo/nginx foo/web nginx.foo.svc.cluster.local web-{0..N-1}.nginx.foo.svc.cluster.local web-{0..N-1}
kube.local foo/nginx foo/web nginx.foo.svc.kube.local web-{0..N-1}.nginx.foo.svc.kube.local web-{0..N-1}
注意: 集群域会被设置为 cluster.local,除非有其他配置。

  稳定的存储

  Kubernetes 为每个 VolumeClaimTemplate 创建一个 PersistentVolume。在上面的 nginx 示例中,每个 Pod 将会得到基于 StorageClass my-storage-class 提供的 1 Gib 的 PersistentVolume。如果没有声明 StorageClass,就会使用默认的 StorageClass。当一个 Pod 被调度(重新调度)到节点上时,它的 volumeMounts 会挂载与其 PersistentVolumeClaims 相关联的 PersistentVolume。请注意,当 Pod 或者 StatefulSet 被删除时,与 PersistentVolumeClaims 相关联的 PersistentVolume 并不会被删除。要删除它必须通过手动方式来完成。

  Pod名称标签

  当 StatefulSet 控制器 创建 Pod 时,它会添加一个标签 statefulset.kubernetes.io/pod-name,该标签设置为 Pod 名称。这个标签允许您给 StatefulSet 中的特定 Pod 绑定一个 Service。

  查看该标签

# kubectl get pod --show-labels
NAME                                    READY   STATUS             RESTARTS   AGE   LABELS
db-0                                    0/1     CrashLoopBackOff   13         68m   controller-revision-hash=db-86458bcd44,project=java-demo,run=mysql,statefulset.kubernetes.io/pod-name=db-0
nfs-client-provisioner-7db87779-jdp99   1/1     Running            0          71m   app=nfs-client-provisioner,pod-template-hash=7db87779
web-0                                   1/1     Running            0          56m   app=nginx,controller-revision-hash=web-5d84f996d,statefulset.kubernetes.io/pod-name=web-0
web-1                                   1/1     Running            0          56m   app=nginx,controller-revision-hash=web-5d84f996d,statefulset.kubernetes.io/pod-name=web-1
web-2                                   1/1     Running            0          56m   app=nginx,controller-revision-hash=web-5d84f996d,statefulset.kubernetes.io/pod-name=web-2

  部署和扩缩保证

  • 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为 0..N-1
  • 当删除 Pod 时,它们是逆序终止的,顺序为 N-1..0
  • 在将缩放操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
  • 在 Pod 终止之前,所有的继任者必须完全关闭。

  StatefulSet 不应将 pod.Spec.TerminationGracePeriodSeconds 设置为 0。这种做法是不安全的,要强烈阻止。

  在上面的 nginx 示例被创建后,会按照 web-0、web-1、web-2 的顺序部署三个 Pod。在 web-0 进入 Running 和 Ready 状态前不会部署 web-1。在 web-1 进入 Running 和 Ready 状态前不会部署 web-2。如果 web-1 已经处于 Running 和 Ready 状态,而 web-2 尚未部署,在此期间发生了 web-0 运行失败,那么 web-2 将不会被部署,要等到 web-0 部署完成并进入 Running 和 Ready 状态后,才会部署 web-2。

  如果用户想将示例中的 StatefulSet 收缩为 replicas=1,首先被终止的是 web-2。在 web-2 没有被完全停止和删除前,web-1 不会被终止。当 web-2 已被终止和删除、web-1 尚未被终止,如果在此期间发生 web-0 运行失败,那么就不会终止 web-1,必须等到 web-0 进入 Running 和 Ready 状态后才会终止 web-1。

  Pod管理策略

  在 Kubernetes 1.7 及以后的版本中,StatefulSet 允许您不要求其排序保证,同时通过它的 .spec.podManagementPolicy 域保持其唯一性和身份保证。 在 Kubernetes 1.7 及以后的版本中,StatefulSet 允许您放宽其排序保证,同时通过它的 .spec.podManagementPolicy 域保持其唯一性和身份保证。

  OrderedReady Pod 管理

  OrderedReady Pod 管理是 StatefulSet 的默认设置。它实现了上面描述的功能。

  Parallel Pod 管理

  Parallel Pod 管理让 StatefulSet 控制器并行的启动或终止所有的 Pod,启动或者终止其他 Pod 前,无需等待 Pod 进入 Running 和 ready 或者完全停止状态。

  更新策略 

  在 Kubernetes 1.7 及以后的版本中,StatefulSet 的 .spec.updateStrategy 字段让您可以配置和禁用掉自动滚动更新 Pod 的容器、标签、资源请求或限制、以及注解。

  关于删除策略 

  OnDelete 更新策略实现了 1.6 及以前版本的历史遗留行为。当 StatefulSet 的 .spec.updateStrategy.type 设置为 OnDelete 时,它的控制器将不会自动更新 StatefulSet 中的 Pod。用户必须手动删除 Pod 以便让控制器创建新的 Pod,以此来对 StatefulSet 的 .spec.template 的变动作出反应。

  滚动更新  

  RollingUpdate 更新策略对 StatefulSet 中的 Pod 执行自动的滚动更新。在没有声明 .spec.updateStrategy 时,RollingUpdate 是默认配置。 当 StatefulSet 的 .spec.updateStrategy.type 被设置为 RollingUpdate 时,StatefulSet 控制器会删除和重建 StatefulSet 中的每个 Pod。 它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。它会等到被更新的 Pod 进入 Running 和 Ready 状态,然后再更新其前身。

  分区

  通过声明 .spec.updateStrategy.rollingUpdate.partition 的方式,RollingUpdate 更新策略可以实现分区。如果声明了一个分区,当 StatefulSet 的 .spec.template 被更新时,所有序号大于等于该分区序号的 Pod 都会被更新。所有序号小于该分区序号的 Pod 都不会被更新,并且,即使他们被删除也会依据之前的版本进行重建。如果 StatefulSet 的 .spec.updateStrategy.rollingUpdate.partition 大于它的 .spec.replicas,对它的 .spec.template 的更新将不会传递到它的 Pod。 在大多数情况下,您不需要使用分区,但如果您希望进行阶段更新、则这些分区会非常有用。

  强制回滚

  在默认 Pod 管理策略(OrderedReady) 时使用 滚动更新 ,可能进入需要人工干预才能修复的损坏状态。

  如果更新后 Pod 模板配置进入无法运行或就绪的状态(例如,由于错误的二进制文件或应用程序级配置错误),StatefulSet 将停止回滚并等待。

  在这种状态下,仅将 Pod 模板还原为正确的配置是不够的。由于已知问题,StatefulSet 将继续等待损坏状态的 Pod 准备就绪(永远不会发生),然后再尝试将其恢复为正常工作配置。

  恢复模板后,还必须删除 StatefulSet 尝试使用错误的配置来运行的 Pod。这样,StatefulSet 才会开始使用被还原的模板来重新创建 Pod。

  部署StatefulSet

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

  目标

  StatefulSets 旨在与有状态的应用及分布式系统一起使用。然而在 Kubernetes 上管理有状态应用和分布式系统是一个宽泛而复杂的话题。为了演示 StatefulSet 的基本特性,并且不使前后的主题混淆,你将会使用 StatefulSet 部署一个简单的 web 应用。

  在阅读本教程后,你将熟悉以下内容:

  • 如何创建StatefulSet
  • StatefulSet怎样管理它的Pods
  • 如何删除StatefulSet
  • 如何对StatefulSet进行扩容/缩容
  • 如果更新一个StatefulSet的Pods

  创建StatefulSet

  需要有动态存储卷本次私有NFS搭建,搭建完毕以后使用命令查看

# kubectl get storageClass
NAME                  PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   fuseim.pri/ifs   Delete          Immediate           false                  120m

  需要使用两个终端窗口。在一个终端中使用kubectl get来检查StatefulSet创建Pods情况

kubectl get pods -w -l app=nginx

  在另一个终端中,使用 kubectl apply来创建定义在 web.yaml 中的 Headless Service 和 StatefulSet。

kubectl apply -f web.yaml
service/nginx created
statefulset.apps/web created

  上面的命令创建了两个 Pod,每个都运行了一个 NGINX web 服务器。获取 nginx Service 和 web StatefulSet 来验证是否成功的创建了它们。

kubectl get service nginx
NAME    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   None         <none>        80/TCP    2m8s
kubectl get statefulset web
NAME   READY   AGE
web    2/2     2m10s

  顺序创建Pod

  对于一个拥有 N 个副本的 StatefulSet,Pod 被部署时是按照 {0 …… N-1} 的序号顺序创建的。在第一个终端中使用 kubectl get 检查输出。这个输出最终将看起来像下面的样子。

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     Pending   0          2s
web-0   0/1     ContainerCreating   0          2s
web-0   1/1     Running             0          4s
web-1   0/1     Pending             0          0s
web-1   0/1     Pending             0          0s
web-1   0/1     Pending             0          2s
web-1   0/1     ContainerCreating   0          2s
web-1   1/1     Running             0          4s

  请注意在 web-0 Pod 处于 Running和Ready 状态后 web-1 Pod 才会被启动。

原文地址:https://www.cnblogs.com/minseo/p/12540281.html

时间: 2024-11-08 21:07:37

Kubernetes控制器之StatefulSet的相关文章

kubernetes学习控制器之StatefulSet控制器

StatefulSet介绍 一.StatefulSet概述StatefulSet是用来管理stateful(有状态)应用的StatefulSet管理Pod时,确保Pod有一个按序增长的ID与Deployment最大的不同是StatefulSet始终将一系列不变的名字分配给Pod.这些Pod从一个模板创建,但是并不能相互替换二.StatefulSet使用场景对于有如下要求的应用程序,StatefulSet非常适用需要稳定.唯一的网络标识(dnsname)每个Pod始终对应各自的存储路径(Persi

Kubernetes 控制器之 Service 讲解(七)

一.背景介绍 我们这里准备三台机器,一台master,两台node,采用kubeadm的方式进行安装的,安装过程大家可以参照我之前的博文. IP 角色 版本 192.168.1.200 master kubeadm v1.13.0 192.168.1.201 node01 kubeadm v1.13.0 192.168.1.202 node02 kubeadm v1.13.0 我们不应该期望 Kubernetes Pod 是健壮的,而是要假设 Pod 中的容器很可能因为各种原因发生故障而死掉.D

Kubernetes 控制器之 Deployment 介绍(六)

一.Deployment.ReplicaSet.Pod之间的关系 我们接着前面的文章说,如果不清楚的请查看之前的博文:http://blog.51cto.com/wzlinux/2322616 前面我们已经了解到,Kubernetes 通过各种 Controller 来管理 Pod 的生命周期.为了满足不同业务场景,Kubernetes 开发了 Deployment.ReplicaSet.DaemonSet.StatefuleSet.Job 等多种 Controller.我们首先学习最常用的 D

Kubernetes控制器之ReplicaSet

参考:https://www.jianshu.com/p/fd8d8d51741e https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicaset/ 说到ReplicaSet对象,得先说说ReplicationController(简称为RC).在旧版本的Kubernetes中,只有ReplicationController对象.它的主要作用是确保Pod以你指定的副本数运行,即如果有容器异常退出,会自动创建新的 Po

k8s中的pod控制器之Deployment、DaemonSet、StatefulSet

pod控制器分类:1.ReplicationController2.ReplicaSet3.Deployment4.StatefulSet5.DaemonSet6.Job,Cronjob7.HPApod控制器:一般包括3部分1.标签选择器2.期望的副本数(DaemonSet控制器不需要)3.pod模板deploy控制器构建于rs控制器之上,新特性包括:1.事件和状态查看2.回滚3.版本记录4.暂停和启动5.支持两种自动更新方案Recreate删除重建RollingUpdate回滚升级(默认方式)

Kubernetes的pod控制器之DaemonSet

DaemonSet 顶级参数介绍 [[email protected] manifests]# kubectl explain ds KIND: DaemonSet VERSION: extensions/v1beta1 DESCRIPTION: DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for more informati

Kubernetes进阶之StatefulSet有状态部署

K8s有状态应用部署目录:分为两类1.Headless Service2.StatefulSet ? 部署有状态应用 ? 解决Pod独立生命周期,保持Pod启动顺序和唯一性 稳定,唯一的网络标识符,持久存储 有序,优雅的部署和扩展.删除和终止 有序,滚动更新 应用场景:数据库 说在前面的话,像我们的Mysql或者Redis了,Zookerper等等这些适不适合部署在K8s中,其实呢不是太适合,但部署在里面也可以,比如部署一个Mysql来讲吧,部署到k8s中还是很容易的就一个Mysql实例,就像部

菜鸟学四轴控制器之1:插补是啥东西

之前看过运动控制芯片的手册,包括了NOVA的MCX314和PCL6045等,知道插补的概念. 但是插补到底是啥玩意,其实一直是有点疑惑的,然后就傻乎乎的去问一些专家,他们的说法是: 插补可以同时多轴输出,速度很快.然后就不知道问啥了. 基于我之前做步进电机的经验,以及测试步进电机驱动器的经验,我一般情况下都是通过单片机发一个固定脉冲来测试驱动器的性能.如果需要测试电机各种速度下的力矩特性,最多采用了S加减速曲线,在我看来,要画一个直线,那太简单了,直接X轴和Y轴同时给不同速度的脉冲不就OK了么?

菜鸟学四轴控制器之2:逐点比较法

逐点比较法是基准脉冲插补算法中,最简单和直接的一种方式. 简单粗暴,速度快! 可以实现直线插补,圆形插补和其他的插补,比如椭圆形等. 逐点比较法,顾名思义,就是每走一步都要将加工点的瞬时坐标同规定的图形轨迹相比较,判断其偏差,然后决定下一步的走向,如果加工点走到图形外面去了,那么下一步就要向图形里面走:如果加工点在图形里面,那么下一步就要向图形外面走,以缩小偏差.这样就能得出一个非常接近规定图形的轨迹,最大偏差不超过一个脉冲当量. 所以说,一般的雕刻机应该可以满足要求吧,关键是速度也快啊,比如说