Understanding StatefulSets and Deployments in Kubernetes

在Kubernetes中,部署和管理应用程序是一个核心功能。Stateless applications(无状态应用程序)和Stateful applications(有状态应用程序)需要不同的管理策略。本文将探讨Kubernetes中Deployments和StatefulSets的概念,以及它们如何应用于不同类型的应用程序。

无状态应用程序与Deployments

无状态应用程序是指任何实例(或Pod)都可以被替换或扩展,而不需要任何唯一标识或存储持久性。Web服务器、微服务和批处理应用程序是使用Deployments的经典例子。Deployments的关键特性包括:

  • 无状态性:Deployment中的Pod是可互换的,不保留任何状态。这意味着如果一个Pod失败,可以在不影响应用程序的情况下启动一个新的Pod。
  • 滚动更新:Deployments可以通过逐渐用新Pod替换旧Pod来实现零停机时间更新应用程序。
  • ReplicaSet管理:Deployments管理ReplicaSets,确保始终运行正确数量的Pod。

以下是一个Deployment的YAML示例:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.21.0 ports: - containerPort: 80

有状态应用程序与StatefulSets

StatefulSets是为需要持久存储、唯一网络标识符和稳定、持久身份的有状态应用程序设计的。与Deployments不同,StatefulSets管理一组Pod的部署和扩展,其中每个Pod都是唯一的,并在重新启动时保持一致的身份。StatefulSets的关键特性包括:

  • 稳定的Pod名称:StatefulSet中的每个Pod都基于其顺序获得稳定的、唯一的标识符(例如,pod-name-0, pod-name-1)。
  • 有序、优雅的部署和扩展:Pod按顺序创建、更新或删除,确保应用程序的状态得以保留。
  • 持久卷:StatefulSets与PersistentVolumeClaims(PVCs)一起工作,即使Pod被删除或重新调度,也能保留数据。

以下是一个StatefulSet的YAML示例:

apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: serviceName: "mysql" replicas: 3 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0 ports: - containerPort: 3306 volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: mysql-persistent-storage spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi

StatefulSets与Deployments的关键区别

以下是StatefulSets和Deployments之间的一些关键区别:

特性 StatefulSets Deployments
Pod身份 每个Pod都有稳定的、唯一的身份。 Pod是可互换的,无状态。
存储 与Persistent Volumes一起工作以保留数据。 通常用于临时存储。
网络身份 每个Pod都有稳定的主机名和网络身份。 Pod共享一个公共服务名称。
扩展 Pod按顺序上下扩展。 Pod并行上下扩展。
用例 数据库、分布式系统(例如Kafka、Zookeeper)。 无状态应用程序(例如Web服务器、API)。

何时使用StatefulSets与Deployments

当需要为每个Pod维护一个唯一的身份,保留持久存储,并确保有序的部署和扩展时,使用StatefulSets。例如数据库(例如MySQL、Cassandra)、分布式系统(例如Kafka、Zookeeper)以及不能容忍随机Pod重启的有状态应用程序。

对于无状态应用程序,其中Pod可以被替换而不影响应用程序的整体状态,使用Deployments。例如Web服务器、API和微服务,其中状态不在Pod本身中保留。

演示:使用StatefulSets部署有状态应用程序

让通过一个演示来部署一个MySQL数据库,使用StatefulSet在Kubernetes中。

  1. 创建StatefulSet
  2. 将使用前面提供的YAML示例来部署一个MySQL数据库。将YAML文件保存为mysql-statefulset.yaml并应用它:

    kubectl apply -f mysql-statefulset.yaml
  3. 验证StatefulSet
  4. 检查StatefulSet的状态,确保Pod按顺序创建:

    kubectl get statefulsets
  5. 检查Pods
  6. 列出由StatefulSet创建的Pods:

    kubectl get pods -l app=mysql
  7. 检查持久卷
  8. 验证为每个Pod创建的持久卷:

    kubectl get pvc

演示:使用Deployments部署无状态应用程序

现在,让使用Deployment部署一个Nginx Web服务器。

  1. 创建Deployment
  2. 使用前面提供的YAML示例来部署一个Nginx服务器。将YAML文件保存为nginx-deployment.yaml并应用它:

    kubectl apply -f nginx-deployment.yaml
  3. 验证Deployment
  4. 检查Deployment的状态,确保它正在运行所需数量的副本:

    kubectl get deployments
  5. 检查Pods
  6. 列出由Deployment创建的Pods:

    kubectl get pods -l app=nginx
  7. 测试滚动更新
  8. 为了演示Deployments的强大功能,让执行一个滚动更新。编辑nginx-deployment.yaml文件中的nginx镜像版本为1.21.1:

    image: nginx:1.21.1

    应用更新:

    kubectl apply -f nginx-deployment.yaml

    监控滚动状态:

    kubectl rollout status deployment/nginx-deployment

StatefulSets和Deployments都是Kubernetes中的强大工具,每种工具服务于不同类型的工作负载。Deployments非常适合需要快速扩展和频繁更新的无状态应用程序,而StatefulSets对于顺序和Pod身份重要的有状态应用程序至关重要。通过理解这些差异并为工作负载应用正确的Kubernetes对象,可以确保应用程序既健壮又可扩展。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485