状态集(StatefulSets)和部署(Deployments)是用于管理应用程序的两种核心 Kubernetes 资源。部署是无状态应用程序的理想选择,它能确保任何 pod 都能被另一个 pod 取代,而不会影响应用程序。另一方面,StatefulSets 专为有状态应用而设计,在这种应用中,pod 的顺序和身份至关重要。


下面的示例演示了如何在 Kubernetes 中同时创建部署和有状态集。这将有助于说明管理无状态与有状态应用程序的不同之处。

【代码清单】

# Deployment Example
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.17.4
     ports:
      - containerPort: 80
---
# StatefulSet Example
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: web
spec:
 serviceName: "nginx"
 replicas: 3
 selector:
  matchLabels:
   app: nginx
 template:
  metadata:
   labels:
     app: nginx
  spec:
   containers:
    - name: nginx
     image: nginx:1.17.4
     ports:
      - containerPort: 80
 volumeClaimTemplates:
 - metadata:
   name: www
  spec:
   accessModes: ["ReadWriteOnce"]
   resources:
     requests:
      storage: 1Gi

【执行结果】

部署: 应用部署清单时,Kubernetes 将创建 3 个 nginx pod 的副本,所有副本都是相同的,可以互换替换,没有特定顺序或身份: 
StatefulSet:应用 StatefulSet 清单时,Kubernetes 将创建 3 个 nginx pod 的副本,但每个副本都有一个唯一标识(如 web-0、web-1、web-2)。
这些 pod 是按顺序创建的,如果删除一个 pod,它将以相同的身份重新创建。

StatefulSets 可管理一组 pod 的部署和扩展,并为这些 pod 的排序和唯一性提供保证。这对于数据库等应用来说至关重要,因为数据库的状态保存在磁盘上,而 pod 需要有稳定的持久存储(由 PersistentVolumeClaims 提供)。在部署中,所有 pod 都可以互换,非常适合横向扩展应用程序,而无需担心每个 pod 的具体身份: Pod 身份(持久性)、特定顺序、稳定的网络标识符: 无状态、可互换的 pod,是负载平衡服务的理想选择。

【小知识】

在 StatefulSet 中,pod 的主机名来自 StatefulSet 名称和 pod 的序号索引(如 web-0),这样 pod 就能被其他资源一致地寻址。