【K8S系列】深入解析StatefulSet(二)

本文涉及的产品
云解析 DNS,旗舰版 1个月
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 【K8S系列】深入解析StatefulSet(二)

1 前情提要

1.1 StatefulSet 两种状态

StatefulSet 的设计,它把真实世界里的应用状态,抽象为了两种:

  • 拓扑状态
  • 存储状态

在前面一篇文章中,我们已经了解了拓扑状态,今天主要学习一下存储状态


2 PVC

StatefulSet 对存储状态的管理机制,主要使用的是一个叫作 Persistent Volume Claim 的功能。所以我们需要先来看下这个功能的介绍与使用。

2.1 PVC基本介绍

持久卷(Persistent Volume)是一种独立于 Pod 的存储资源。持久卷可以独立于 Pod 的生命周期存在,并且可以在 Pod 重新调度后仍然保留数据。

Kubernetes 中,要使用持久卷,需要创建一个持久卷声明(Persistent Volume Claim)

Persistent Volume Claim (PVC) 是一种用于声明对持久存储资源的需求的资源对象

PVC 允许将应用程序和存储资源的生命周期分开,以便在应用程序重新部署或迁移时保留持久存储数据

2.2 PVC 的工作原理

Persistent Volume Claim(PVC)是在 Kubernetes 中定义一个存储资源的方式。PVC 允许 Pod 请求特定大小和访问模式的存储。

PVC 实际上是一个声明,它声明了 Pod 需要的存储资源。

Kubernetes 系统会根据 PVC 的要求选择或创建一个相应的持久卷来满足 Pod 的需求

如果 PV 满足 PVC 的要求,则将 PV 绑定到 PVC,并将 PVC 暴露给应用程序使用。

PVC 可以在多个 Pod 之间共享,但每次只能绑定到一个 PV 上。

2.3 PVC 的访问模式

PVC 的访问模式指定了允许哪些节点以哪种方式使用持久卷。以下是 PVC 的三种访问模式:

  • ReadWriteOnce:允许单个节点以读写模式挂载持久卷。
  • ReadOnlyMany:允许多个节点以只读模式挂载持久卷。
  • ReadWriteMany:允许多个节点以读写模式挂载持久卷。

需要注意的是,不是所有的存储插件都支持所有的访问模式。因此,在使用 PVC 的时候,需要确保所使用的存储插件支持所需的访问模式。

2.4 PVC 和 Pod 的关系

  1. 关系:PVC 和 Pod 是紧密相关的。
  2. 请求:一个 Pod 可以请求一个或多个 PVC,并将 PVC 挂载到容器中。
  3. 挂载:在 Pod 被调度到节点上时,Kubernetes 系统会为 Pod 中声明的每个 PVC 创建一个持久卷,并将其挂载到 Pod 上。
  4. 删除当 Pod 被删除时,与之关联的 PVC 不会被删除,这些 PVC 可以在之后的 Pod 中继续使用

2.5 代码示例

2.5.1 yaml 示例

下面是一个 PVC 的 YAML 文件示例:

apiVersion: v1
kind: PersistentVolumeClaim # PVC资源类型
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

在这个示例中,创建了一个名为 my-pvc 的 PVC,并指定了访问模式为 ReadWriteOnce,请求的存储容量为 1Gi。

2.5.2 PVC 的 Pod yaml

接下来,可以创建一个使用这个 PVC 的 Pod。

下面是一个使用 my-pvc 的 Pod 的 YAML 文件示例:

apiVersion: v1
kind: Pod                   #资源类型
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
    volumeMounts:
    - name: my-pvc-volume
      mountPath: /data
  volumes:
  - name: my-pvc-volume     #当前pod对应的pvc名称
    persistentVolumeClaim:
      claimName: my-pvc     #使用刚刚创建声明的pvc

在这个示例中,创建了一个名为 my-pod 的 Pod,并将其容器的 /data 目录挂载到 my-pvc-volume 卷中。该卷使用 my-pvc PVC。

Tips:

当创建 my-pod Pod 时,Kubernetes 会自动扫描所有可用的 PV,并选择一个 PV 来满足 my-pvc PVC 的要求

如果找到了可用的 PV,则将其绑定到 my-pvc,并将 my-pvc-volume 卷挂载到容器中的 /data 目录。

2.6 结论

PVC 是 Kubernetes 中非常有用的资源对象,它允许将应用程序和存储资源的生命周期分开,并在应用程序重新部署或迁移时保留持久存储数据

通过上面的示例,可以了解如何创建 PVC,并将其用于 Pod。

拓展一下:

Kubernetes 中 PVC 和 PV 的设计,实际上类似于“接口”和“实现”的思想

  1. 开发者只要知道并会使用“接口”,即:PVC;
  2. 而运维人员则负责给“接口”绑定具体的实现,即:PV。

这种解耦就避免了因为向开发者暴露过多的存储系统细节而带来的隐患。

此外,这种职责的分离,往往也意味着出现事故时可以更容易定位问题和明确责任,从而避免“扯皮”现象的出现。

3 存储状态

3.1 问题

思考一下这个问题:

3.2 问题解答

前面已经了解到,当 Pod 被删除时,与之关联的 PVC 不会被删除,这些 PVC 可以在之后的 Pod 中继续使用。

来看下StatefulSet 怎么做到的

首先:

StatefulSet 的控制器直接管理的是 Pod。

因为,StatefulSet 里的不同 Pod 实例,不像 ReplicaSet 中那样都是完全一样的,而是有了细微区别的。

比如,每个 Pod 的 hostname、名字等都是不同的、携带了编号的。而 StatefulSet 区分这些实例的方式,就是通过在 Pod 的名字里加上事先约定好的编号。


其次:

Kubernetes 通过 Headless Service,为这些有编号的 Pod,在 DNS 服务器中生成带有同样编号的 DNS 记录

只要 StatefulSet 能够保证这些 Pod 名字里的编号不变,那么 Service 里类似于

web-0.nginx.default.svc.cluster.local 这样的 DNS 记录也就不会变,而这条记录解析出来的 Pod 的 IP 地址,则会随着后端 Pod 的删除和再创建而自动更新。这是 Service 机制本身的能力,不需要 StatefulSet 操心。

最后:

StatefulSet 还为每一个 Pod 分配并创建一个同样编号的 PVC

这样,Kubernetes 就可以通过 Persistent Volume 机制为这个 PVC 绑定上对应的 PV,从而保证了每一个 Pod 都拥有一个独立的 Volume。

在这种情况下,即使 Pod 被删除,它所对应的 PVC 和 PV 依然会保留下来

所以,当这个 Pod 被重新创建出来之后,Kubernetes 会为它找到同样编号的 PVC,挂载这个 PVC 对应的 Volume,从而获取到以前保存在 Volume 里的数据。

3.3 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
        volumeMounts:
        - name: mypvc
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates: #pvc声明
  - metadata:
      name: mypvc
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

在这个yaml中:添加了一个 volumeClaimTemplates 字段。

它跟 Deployment 里 Pod 模板(PodTemplate)的作用类似。凡是被这个 StatefulSet 管理的 Pod,都会声明一个对应的 PVC;

而这个 PVC 的定义,就来自于 volumeClaimTemplates 这个模板字段。更重要的是,这个 PVC 的名字,会被分配一个与这个 Pod 完全一致的编号。

这个自动创建的 PVC,与 PV 绑定成功后,就会进入 Bound 状态,这就意味着这个 Pod 可以挂载并使用这个 PV 了。

3.4 创建

使用 kubectl create 创建了 StatefulSet 之后,就会看到 Kubernetes 集群里出现了两个 PVC:

kubectl create -f statefulset.yaml

3.5 查看结果

执行创建命令:

kubectl get pvc -l app=nginx

结果如下:

NAME        STATUS    VOLUME                                     CAPACITY   ACCESSMODES   AGE
mypvc-web-0   Bound     pvc-15c268c7-b507-11e6-932f-42010a800002   1Gi        RWO           48s
mypvc-web-1   Bound     pvc-15c79307-b507-11e6-932f-42010a800002   1Gi        RWO           48s

前面已讲到过,这个 StatefulSet 创建出来的所有 Pod,都会声明使用编号的 PVC

可以看到,这些 PVC,都以“<PVC 名字 >-<StatefulSet 名字 >-< 编号 >”的方式命名,并且处于 Bound 状态。


3.6 总结

1. 可以看出StatefulSet 其实就是一种特殊的 Deployment,它的特别之处在于,赋予了pod在整个集群里唯一的、可被的访问身份主要通过它对创建的每个 Pod 都进行了编号

2. 就是这个编号给了pod一个唯一的身份,并且,这个编号还会体现在 Pod 的名字和 hostname 等标识信息上,这不仅代表了 Pod 的创建顺序,也是 Pod 的重要网络标识

有了编号后,StatefulSet 就使用 Kubernetes 里的两个标准功能:

  1. Headless Service
  2. PV/PVC

实现了对 Pod 的拓扑状态和存储状态的维护。


4 投票


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3月前
|
Kubernetes 容器 Perl
【Azure K8S | AKS】在AKS中创建 StatefulSet 示例
【Azure K8S | AKS】在AKS中创建 StatefulSet 示例
|
3月前
|
Kubernetes API 调度
Kubernetes 架构解析:理解其核心组件
【8月更文第29天】Kubernetes(简称 K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用。它提供了一个可移植、可扩展的环境来运行分布式系统。本文将深入探讨 Kubernetes 的架构设计,包括其核心组件如何协同工作以实现这些功能。
320 0
|
9天前
|
运维 Kubernetes Cloud Native
Kubernetes云原生架构深度解析与实践指南####
本文深入探讨了Kubernetes作为领先的云原生应用编排平台,其设计理念、核心组件及高级特性。通过剖析Kubernetes的工作原理,结合具体案例分析,为读者呈现如何在实际项目中高效部署、管理和扩展容器化应用的策略与技巧。文章还涵盖了服务发现、负载均衡、配置管理、自动化伸缩等关键议题,旨在帮助开发者和运维人员掌握利用Kubernetes构建健壮、可伸缩的云原生生态系统的能力。 ####
|
7天前
|
存储 Kubernetes 调度
【赵渝强老师】K8s中Deployment控制器与StatefulSet控制器的区别
K8s中的Deployment控制器用于管理无状态应用程序,关注Pod数量、更新方式等;而StatefulSets控制器则管理有状态应用程序,提供持久存储和唯一标识符,适用于需要稳定网络标识符和持久化存储的场景。两者的主要区别在于是否维护状态和顺序。
|
7天前
|
存储 Kubernetes 调度
【赵渝强老师】K8s的有状态控制器StatefulSet
在Kubernetes中,StatefulSets用于部署有状态应用程序,提供持久存储和唯一标识符。与Deployment不同,StatefulSets确保Pod的标识符在重新调度后保持不变,适用于需要稳定网络标识符和持久存储的场景。本文介绍了StatefulSets的创建、扩容与缩容、更新与回滚等操作,并提供了具体示例和视频讲解。
|
7天前
|
存储 Kubernetes 调度
深度解析Kubernetes中的Pod生命周期管理
深度解析Kubernetes中的Pod生命周期管理
|
24天前
|
存储 Kubernetes 监控
深度解析Kubernetes在微服务架构中的应用与优化
【10月更文挑战第18天】深度解析Kubernetes在微服务架构中的应用与优化
91 0
|
1月前
|
存储 Kubernetes NoSQL
k8s学习--资源控制器StatefulSet详细解释与应用
StatefulSet 是 Kubernetes 中用于管理有状态应用的控制器,提供稳定的网络标识符和持久化存储能力。相较于 Deployment、DaemonSet 等无状态服务控制器,StatefulSet 支持有状态服务如 MySQL、Redis 等集群的部署和管理。本文详细介绍 StatefulSet 的概念、特点及部署方法,并通过具体示例展示了如何配置 NFS 存储及 StatefulSet 应用,确保每个 Pod 拥有独立且持久的数据存储空间。
|
3月前
|
存储 Kubernetes 网络协议
在K8S中,Deployment和Statefulset有何区别?
在K8S中,Deployment和Statefulset有何区别?
|
3月前
|
Kubernetes 负载均衡 网络协议
在K8S中,DNS组件有什么特性?
在K8S中,DNS组件有什么特性?

推荐镜像

更多