首页 >后端开发 >Golang >Kubernetes Statefulsets 初学者指南

Kubernetes Statefulsets 初学者指南

Susan Sarandon
Susan Sarandon原创
2024-12-06 12:02:12946浏览

StatefulSets 是 Kubernetes 中用于管理有状态应用程序的 API 对象。 Kubernetes中有两种类型的应用程序,有状态应用程序和无状态应用程序。有两种方法可以部署这些应用程序:

  • 部署(对于无状态应用程序)
  • StatefulSets(用于有状态应用程序)

什么是有状态应用程序?

那些维护某种形式的持久状态或数据的应用程序称为有状态应用程序。它们与无状态应用程序的关键特征是这些应用程序不依赖于本地存储数据,并且它们不将每个请求视为独立的。他们管理交互之间的数据。有时无状态应用程序连接到有状态应用程序以将请求转发到数据库。

什么是无状态应用程序?

那些不在本地维护任何形式的持久状态或数据的应用程序称为无状态应用程序。在无状态应用程序中,每个请求或交互都是独立处理的。这些应用程序被设计为高度可扩展、易于管理和容错,因为与有状态应用程序不同,它们不必跟踪过去的交互或请求。

无状态应用程序使用部署组件进行部署。部署是 pod 的抽象,允许您复制应用程序,这意味着它允许您运行同一无状态应用程序的 1、5、10 或 n 个相同的 pod。

什么是 StatefulSet?

简单地说,StatefulSets 是专门用于有状态应用程序的 Kubernetes 组件。这些是用于管理有状态应用程序的工作负载 API 对象。它们管理一组 Pod 的部署和扩展(创建更多副本或删除它们),StatefulSet 还负责这些 Pod 的排序和唯一性。 StatefulSet 在 Kubernetes 1.9 版本中发布。

StatefulSets 将代表具有不同(唯一)、持久身份和弹性主机名(稳定)的 Pod 集合。它使您可以确定扩展和部署的顺序。在了解 StatefulSet 之前,您必须了解 Kubernetes Deployment。

这是一个名为 web 的 StatefulSet 示例:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.k8s.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

何时使用 StatefulSet

Kubernetes 中的 StatefulSet 非常适合部署需要稳定、唯一的网络标识符、持久存储以及有序、优雅的部署和扩展的有状态应用程序。它们适用于需要一致身份和存储的数据库、键值存储和消息队列等应用程序。

有状态和无状态应用程序的示例

考虑一个连接到 MongoDB 数据库的 Node.js 应用程序。当请求到达 Node.js 应用程序时,它会独立处理该请求,并且不依赖于先前的数据来执行此操作。它根据请求本身的有效负载处理请求。此 Node.js 应用程序是无状态应用程序的示例。现在请求要么更新数据库中的一些数据,要么从数据库中查询一些数据。当node.js将该请求转发到MongoDB时,MongoDB会根据数据的先前状态更新数据或从其存储中查询数据。对于每个请求,它都需要处理数据,并且它取决于可用的最新数据或状态,而 Node.js 只是数据更新或查询的传递,它只处理代码。因此,node.js 应用程序应该是无状态应用程序,而 MongoDB 应用程序必须是有状态应用程序。

有时无状态应用程序连接到有状态应用程序以将请求转发到数据库。这是无状态应用程序将请求转发到有状态应用程序的一个很好的示例。

如何在 Kubernetes 中创建 StatefulSet

这里是有关如何使用 StatefulSet 以及 StatefulSet 的一些基本操作的分步教程。

创建 Nginx StatefulSet 应用程序

第 1 步. 创建 StatefulSet 文件。您可以通过输入以下命令来做到这一点:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.k8s.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

步骤 2. 在代码编辑器中打开此文件并将以下代码写入其中:

touch example-statefulset.yaml

第 3 步。 现在我们必须创建一个服务文件和一个 PersistentVolumeClaim 文件。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: gfg-example-statefulset
  annotations:
    description: "This is an example statefulset"
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "gfg-example-service"
  replicas: 3 # remember this, we will have 3 identical pods running
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      volumes:
      - name: www
        persistentVolumeClaim:
          claimName: myclaim

为 StatefulSet 应用程序创建服务

步骤 4. 在服务文件中输入以下代码:

touch example-service.yaml
touch example-persistentVolumeChain.yaml

为应用程序创建 PersistentVolumeClaim

第 5 步. 将以下代码输入到 PersistentVolumeClaim 文件中:

apiVersion: v1
kind: Service
metadata:
  name: gfg-example-service
  annotations:
    description: "this is an example service"
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

现在让我们应用这些更改。

步骤 6. 在终端中输入以下命令来创建 gfg-example-statefulset:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 8Gi # This means we are requesting for 8 GB of storage

这将创建我们的 gfg-example-statefulset,您将得到类似的结果:

Beginners guide to Kubernetes Statefulsets

现在,如果我们通过命令在终端中搜索 StatefulSets

kubectl create -f example-statefulset.yaml

我们将在列表中找到我们的 gfg-example-statefulset。

Beginners guide to Kubernetes Statefulsets

步骤 7. 在终端中输入以下命令以创建 gfg-example-service。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.k8s.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

这将创建一个名为“gfg-example-service”的服务

第 8 步。 让我们检查我们的 pod 和服务,要获取 pod 列表,请在终端中输入以下命令:

touch example-statefulset.yaml

您将获得我们通过在 example-stateful-set.yaml 文件中定义三个副本创建的三个 gfg-pod 的列表。您将得到类似的输出:

Beginners guide to Kubernetes Statefulsets

要检查服务列表,请在终端中输入以下命令:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: gfg-example-statefulset
  annotations:
    description: "This is an example statefulset"
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "gfg-example-service"
  replicas: 3 # remember this, we will have 3 identical pods running
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      volumes:
      - name: www
        persistentVolumeClaim:
          claimName: myclaim

这将为您提供类似的输出:

Beginners guide to Kubernetes Statefulsets

StatefulSet 上的一些操作

添加 StatefulSet: 要将 StatefulSet 添加到 Kubernetes 集群,请使用命令 kubectl create -f [StatefulSet file name],将 [StatefulSet file name] 替换为名称您的 StatefulSet 清单文件。

touch example-service.yaml
touch example-persistentVolumeChain.yaml

删除 StatefulSet: 要在 Kubernetes 中删除 StatefulSet,可以使用 kubectl delete statefulset [name] 命令,其中 [name] 是您想要的 StatefulSet 的名称删除。

apiVersion: v1
kind: Service
metadata:
  name: gfg-example-service
  annotations:
    description: "this is an example service"
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

编辑 StatefulSet: 命令 kubectl edit statefulset [name] 允许您通过打开编辑器直接从命令行修改 StatefulSet 的配置。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 8Gi # This means we are requesting for 8 GB of storage

副本扩展: kubectl scale 命令将名为 [StatefulSet name] 的 StatefulSet 中的副本数量缩放为指定的 [副本数量]。

kubectl create -f example-statefulset.yaml

第 9 步。 现在让我们扩大我们的 pod 并检查它是否有效!要将 Pod 扩展到 6 个 Pod,请输入以下命令:

kubectl get statefulsets

这将创建另外 3 个 pod,并且 pod 数量现在为 6,要获取 pod 列表,请输入以下命令:

kubectl apply -f example-service.yaml

您将得到类似的输出:

Beginners guide to Kubernetes Statefulsets

第 10 步。 现在让我们将 Pod 缩小到 3 个,为此输入相同的命令,只需将副本数更改回 3:

kubectl get pods

现在如果我们检查 pod 列表

kubectl get services

您将看到只有 3 个 pod 正在运行:

Beginners guide to Kubernetes Statefulsets

通过这种方式,我们可以创建 StatefulSet,放大它们,然后缩小它们。确保在关闭终端之前删除 StatefulSet 和服务。要了解 kubectl 的更多命令,请参阅 Kubectl Command Cheat Sheet。

有状态应用程序如何工作?

在MySQL等有状态应用中,多个Pod不能同时读写数据,以避免数据不一致。
其中一个 pod 被指定为 master pod,负责写入和更改数据,而其他 pod 被指定为 Slave pod,只允许读取数据。
每个 Pod 都有自己的数据存储副本,确保数据隔离和独立。
采用同步机制来确保所有 pod 具有相同的数据状态,当 master pod 更改数据时,从属 pod 会更新其数据存储。
持续同步对于维持有状态应用程序中所有 pod 之间的数据一致性是必要的。

示例:
假设我们有一个 MySQL 主 pod 和两个从 pod。现在,当新的 Pod 副本加入现有设置时会发生什么?因为现在新的 Pod 也需要创建自己的存储并负责同步,它首先克隆前一个 Pod 中的数据,然后开始持续同步以侦听主 Pod 的任何更新。因为每个 Pod 都有自己的数据存储(持久卷),该数据存储由自己的物理存储备份,其中包括同步数据和 Pod 的状态。每个 Pod 都有自己的状态,其中包含有关它是主 Pod 还是从属 Pod 的信息以及其他单独的特征。所有这些都存储在 Pod 自己的存储中。因此,当 pod 死亡并被持久 pod 替换时。标识符可确保存储卷重新连接到替换 Pod。这样即使集群崩溃,也能保证数据不丢失。

结论

在本文中我们讨论了如何使用 Kubernetes StatefulSets。 StatefulSet 是用于部署有状态应用程序的 Kubenetes 组件。有状态应用程序是那些维护某种形式的持久状态或数据的应用程序。一个很好的例子是任何带有数据库的应用程序。我们讨论了如何使用 StatefulSet 部署有状态应用程序。之后我们讨论了有状态应用程序如何工作?最后我们讨论了 StatefulSet 和部署之间的区别,它基本上围绕着部署用于部署无状态应用程序和 StatefulSet 用于部署有状态应用程序这一点。我们将通过解决一些常见问题解答来结束本文。

Kubernetes StatefulSets - 常见问题解答

如何增加 Kubernetes 中的卷大小?

要增加 Kubernetes 中的卷大小,您需要通过更改存储大小来修改 PersistentVolumeClaim (PVC) 规范。然后,Kubernetes 会自动配置额外的存储来满足新的大小要求,前提是底层存储类支持动态配置。

何时在 Kubernetes 中使用 hostPath?

Kubernetes 中的 hostPath 卷类型适用于需要直接在 pod 内访问节点文件系统上的文件或目录的场景。它通常用于访问特定于节点的资源或在同一节点上的容器之间共享数据。

PVC StatefulSet 和部署有什么区别?

StatefulSet 中的 PersistentVolumeClaims (PVC) 用于为各个 Pod 提供稳定、持久的存储,确保 Pod 重新启动时数据的持久性和身份。相比之下,部署通常使用临时卷,适用于不需要数据持久性的无状态应用程序。

我们可以使用 StatefulSet 部署无状态应用程序吗?

虽然技术上可行,但不建议使用 StatefulSet 部署无状态应用程序。 StatefulSet 专为需要稳定、唯一标识符和持久存储的有状态应用程序而设计。使用 StatefulSet 部署无状态应用程序可能会带来不必要的复杂性和资源开销。

无状态比有状态更好吗?

这取决于应用程序的具体要求。无状态应用程序更易于管理和水平扩展,而有状态应用程序可维护数据完整性,并且更适合某些工作负载,例如数据库或消息传递系统。

以上是Kubernetes Statefulsets 初学者指南的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn