状态集(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 就能被其他资源一致地寻址。