首页 > 其他分享 >Kubernetes StatefulSet 实操整理

Kubernetes StatefulSet 实操整理

时间:2022-11-02 23:56:22浏览次数:39  
标签:web StatefulSet Kubernetes master01 nginx Running 实操 Pod

StatefulSet

StatefulSet 用来管理有状态应用的工作负载 API 对象。

和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。

使用 StatefulSet

StatefulSet 对于需要满足以下一个或多个需求的应用程序很有价值:

  • 稳定的、唯一的网络标识符。
  • 稳定的、持久的存储。
  • 有序的、优雅的部署和扩缩。
  • 有序的、自动的滚动更新

限制

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

nginx-sts.yaml

[root@master01 stateful-set]# vim nginx-sts.yaml
[root@master01 stateful-set]# cat nginx-sts.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 # 必须匹配 .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # 默认值是 1
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: nginx # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx:1.15.2
        ports:
        - containerPort: 80
          name: web
  • 名为 nginx 的 Headless Service 用来控制网络域名
  • 名为 web 的 StatefulSet 有一个 Spec,它表明将在独立的 3 个 Pod 副本中启动 nginx 容器。
  • volumeClaimTemplates 将通过 PersistentVolume 制备程序所准备的 PersistentVolumes 来提供稳定的存储

创建

[root@master01 stateful-set]# kubectl create  -f nginx-sts.yaml 
service/nginx created
statefulset.apps/web created

查看状态

[root@master01 stateful-set]# kubectl get po
NAME    READY   STATUS              RESTARTS   AGE
nginx   1/1     Running             2          3d20h
web-0   1/1     Running             0          5s
web-1   0/1     ContainerCreating   0          1s
[root@master01 stateful-set]# kubectl get svc 
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d
nginx        ClusterIP   None         <none>        80/TCP    13s
[root@master01 stateful-set]# kubectl get po
NAME    READY   STATUS              RESTARTS   AGE
nginx   1/1     Running             2          3d20h
web-0   1/1     Running             0          17s
web-1   1/1     Running             0          13s
web-2   0/1     ContainerCreating   0          9s

扩容

[root@master01 stateful-set]# kubectl scale --replicas=5 sts web 
statefulset.apps/web scaled
[root@master01 stateful-set]# kubectl get po
NAME    READY   STATUS              RESTARTS   AGE
nginx   1/1     Running             2          3d20h
web-0   1/1     Running             0          95s
web-1   1/1     Running             0          91s
web-2   1/1     Running             0          87s
web-3   0/1     ContainerCreating   0          3s

Pod 选择算符

必须设置 StatefulSet 的 .spec.selector 字段,使之匹配其在 .spec.template.metadata.labels 中设置的标签。 未指定匹配的 Pod 选择算符将在创建 StatefulSet 期间导致验证错误。

VolumeClaimTemplates

可以设置 .spec.volumeClaimTemplates, 它可以使用 PersistentVolume 制备程序所准备的 PersistentVolumes 来提供稳定的存储

最短就绪秒数

特性状态: Kubernetes v1.25 [stable]

.spec.minReadySeconds 是一个可选字段。 它指定新创建的 Pod 应该在没有任何容器崩溃的情况下运行并准备就绪,才能被认为是可用的。 这用于在使用滚动更新策略时检查滚动的进度。 该字段默认为 0(Pod 准备就绪后将被视为可用)

Pod 标识

StatefulSet Pod 具有唯一的标识,该标识包括顺序标识、稳定的网络标识和稳定的存储。 该标识和 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 Service 控制它的 Pod 的网络域。管理域的这个服务的格式为: $(服务名称).$(名字空间).svc.cluster.local,其中 cluster.local 是集群域。

一旦每个 Pod 创建成功,就会得到一个匹配的 DNS 子域,格式为: $(pod 名称).$(所属服务的 DNS 域名),其中所属服务由 StatefulSet 的 serviceName 域来设定。

测试
  1. 启动busybox
cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
EOF
  1. 查询
[root@master01 stateful-set]# kubectl exec -it busybox -- sh 
/ # nslookup web-0.nginx
Server:		10.96.0.10
Address:	10.96.0.10:53

** server can't find web-0.nginx: NXDOMAIN

取决于集群域内部 DNS 的配置,有可能无法查询一个刚刚启动的 Pod 的 DNS 命名。 当集群内其他客户端在 Pod 创建完成前发出 Pod 主机名查询时,就会发生这种情况。 负缓存 (在 DNS 中较为常见) 意味着之前失败的查询结果会被记录和重用至少若干秒钟, 即使 Pod 已经正常运行了也是如此。
如果需要在 Pod 被创建之后及时发现它们,可使用以下选项:

直接查询 Kubernetes API(比如,利用 watch 机制)而不是依赖于 DNS 查询
缩短 Kubernetes DNS 驱动的缓存时长(通常这意味着修改 CoreDNS 的 ConfigMap,目前缓存时长为 30 秒)

[root@master01 ~]# kubectl get po -owide
NAME      READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
busybox   1/1     Running   0          96s     172.18.71.23     master03   <none>           <none>
nginx     1/1     Running   3          3d22h   172.31.112.150   master01   <none>           <none>
web-0     1/1     Running   1          65m     172.21.231.149   node02     <none>           <none>
web-1     1/1     Running   1          64m     172.20.59.210    master02   <none>           <none>
web-2     1/1     Running   1          64m     172.31.112.152   master01   <none>           <none>


[root@master01 ~]# kubectl exec  busybox -n default -- nslookup web-0.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 172.21.231.149 web-0.nginx.default.svc.cluster.local

稳定的存储

对于 StatefulSet 中定义的每个 VolumeClaimTemplate,每个 Pod 接收到一个 PersistentVolumeClaim

Pod 名称标签

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

部署和扩缩保证

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

Pod 管理策略

StatefulSet 允许你放宽其排序保证, 同时通过它的 .spec.podManagementPolicy 域保持其唯一性和身份保证。

OrderedReady Pod 管理

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

并行 Pod 管理

Parallel Pod 管理让 StatefulSet 控制器并行的启动或终止所有的 Pod, 启动或者终止其他 Pod 前,无需等待 Pod 进入 Running 和 Ready 或者完全停止状态。 这个选项只会影响扩缩操作的行为,更新则不会被影响。

更新策略

StatefulSet 的 .spec.updateStrategy 字段让你可以配置和禁用掉自动滚动更新 Pod 的容器、标签、资源请求或限制、以及注解。有两个允许的值:

OnDelete

当 StatefulSet 的 .spec.updateStrategy.type 设置为 OnDelete 时, 它的控制器将不会自动更新 StatefulSet 中的 Pod。 用户必须手动删除 Pod 以便让控制器创建新的 Pod,以此来对 StatefulSet 的 .spec.template 的变动作出反应。

RollingUpdate

RollingUpdate 更新策略对 StatefulSet 中的 Pod 执行自动的滚动更新。这是默认的更新策略

滚动更新

当 StatefulSet 的 .spec.updateStrategy.type 被设置为 RollingUpdate 时, StatefulSet 控制器会删除和重建 StatefulSet 中的每个 Pod。 它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。

Kubernetes 会等到被更新的 Pod 进入 Running 和 Ready 状态,然后再更新其前身。 如果你设置了 .spec.minReadySeconds(查看最短就绪秒数), 控制平面在 Pod 就绪后会额外等待一定的时间再执行下一步

分区滚动更新

通过声明 .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。

删除

级联删除

删除 sts 同时删除 pod

默认为级联删除

[root@master01 stateful-set]# kubectl get po
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          6m45s
nginx     1/1     Running   3          3d22h
web-0     1/1     Running   1          70m
web-1     1/1     Running   1          70m
web-2     1/1     Running   1          70m
[root@master01 stateful-set]# kubectl get svc 
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d
nginx        ClusterIP   None         <none>        80/TCP    70m
[root@master01 stateful-set]# kubectl get sts 
NAME   READY   AGE
web    3/3     70m
[root@master01 stateful-set]# kubectl delete sts web 
statefulset.apps "web" deleted
[root@master01 stateful-set]# kubectl get po 
NAME      READY   STATUS        RESTARTS   AGE
busybox   1/1     Running       0          7m12s
nginx     1/1     Running       3          3d22h
web-1     0/1     Terminating   1          70m
web-2     0/1     Terminating   1          70m
[root@master01 stateful-set]# kubectl get po 
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          7m24s
nginx     1/1     Running   3          3d22h

非级联删除

删除 sts 不同时删除 pod

[root@master01 stateful-set]# kubectl get po
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          8m32s
nginx     1/1     Running   3          3d22h
web-0     1/1     Running   0          14s
web-1     1/1     Running   0          11s
web-2     1/1     Running   0          7s
[root@master01 stateful-set]# kubectl get sts 
NAME   READY   AGE
web    3/3     26s
[root@master01 stateful-set]# kubectl delete sts web --cascade=false #非级联删除 
warning: --cascade=false is deprecated (boolean value) and can be replaced with --cascade=orphan.
statefulset.apps "web" deleted
[root@master01 stateful-set]# kubectl get po 
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          9m25s
nginx     1/1     Running   3          3d22h
web-0     1/1     Running   0          67s
web-1     1/1     Running   0          64s
web-2     1/1     Running   0          60s
[root@master01 stateful-set]# kubectl get sts 
No resources found in default namespace.

标签:web,StatefulSet,Kubernetes,master01,nginx,Running,实操,Pod
From: https://www.cnblogs.com/arvinhuang/p/16852985.html

相关文章

  • kubernetes集群架构
    Master:管理(控制)节点,相当于公司的管理层Master节点主要由APIServer、Controller-Manager和Scheduler三个组件,以及一个用于存储集群状态的Etcd存储服务组成Nod......
  • apifox生成kubernetes-api文档
    前言:尽管多数时候,我们都是通过客户端库(如client-go),而非原生的API进行来操作kubernetes资源,但是对于学习API库,能够直接操作显然再好不过了。通过apifox,我们能够实现这个目的......
  • 内存马的攻防博弈实操
    一、概述一文看懂内存马概述:内存马是无文件攻击的一种常用手段,随着攻防演练热度越来越高:攻防双方的博弈,流量分析、EDR等专业安全设备被蓝方广泛使用,传统的文件上传的websh......
  • kubernetes的yml
    kubernetes的yml1:创建namespace文件po.yml内容如下apiVersion:v1kind:Namespacemetadata:name:po 命令:kubectlapply-fpo.yml 删除namespace......
  • 关于 NGINX Kubernetes Gateway,你需要知道的 5 件事
    原文作者:IlyaKrutovofF5原文链接:​​​关于NGINXKubernetesGateway,你需要知道的5件事​​转载来源:NGINX官方网站在过去的几年里,F5NGINX帮助您成功走完了Kuberne......
  • 收下这份实操案例,还怕不会用Jmeter接口测试工具?!
    01简介每天进步一点点,关注我们哦,每天分享测试技术文章本文章出自【码同学软件测试】码同学公众号:自动化软件测试,领取资料可加:magetest码同学抖音号:小码哥聊软件测试J......
  • Kubernetes_Deployment全解析(无状态的Pod)
    前言一、创建Deployment1.1创建DeploymentapiVersion:apps/v1kind:Deploymentmetadata:name:nginx-deploymentlabels:app:nginxspec:repl......
  • 深入剖析 Kubernetes-4 容器持久化存储
    1PV&PVC&StorageClass1.1概念PV描述的是持久化存储数据卷。PVC描述的是Pod所希望使用的持久化存储的属性。StorageClass其实就是创建PV的模板。用户创建的P......
  • Kubernetes Deployment 实操整理
    Deployment用于部署无状态的服务。一般不直接管理Pod或者ReplicaSet。创建DeploymentDeployment文件apiVersion:apps/v1kind:Deploymentmetadata:name:nginx......
  • 系统架构与设计(5)- Kubernetes(K8s)
    Kubernetes,也被称为K8s或Kube,是谷歌推出的业界最受欢迎的容器管理/运维工具(容器编排器)。它是一套自动化容器管理/运维的开源平台,包括部署、调度和节点集群的扩展等。使......