为什么需要StatefulSet

ReplicaSet 通过一个 pod 模板创建多个 pod 副本。 这些副本除了它们的名字和 IP 地址不同外, 没有别的差异。如果 pod 模板里描述了一个关联到特定持久卷声明 的数据卷,那么 ReplicaSet 的所有副本都将共享这个持久卷声明 ,也就是绑定到同持久卷声明 ,也就是绑到同一个声明的持久卷
image.png
因为是在 pod 模板里关联声明的,又会依据 pod 模板创建多个 pod 副本,则不能对每个副本都指定独立的持久卷声明 。 所以也不能通过一个 ReplicaSet 来运行一个每个实例都需要独立存储的分布式数据存储服务,至少通过单个 ReplicaSet 是做不到的。

RelicaSet 或 ReplicationCon仕oiler 管理的 pod 副本都是无状态的,任何时候它们都可以被一个全新的 pod 替换。 然而有状态的 pod 需要不同的方法,当一个有状态的 pod 挂掉后 ( 或者它所在的节点故障),这个 pod 实例需要在别的节点上重建,但是新的实例必须与被替换的实例拥有相同的名称、网络 标识和状态。 这就是 StatefulSet 如何管理 pod 的。
image.png

当一个 Statefulset 管理的一个 pod 实例消失,Statefulset 会保证重启一个新的 pod 实例替换它,这与 ReplicaSet 类似。 但与 ReplicaSet 不同的是,新的 pod 会拥有与之前 pod 完全一致的名称和主机名
image.png

缩容一个 Statefulset 将会最先删除最高索引值 的实例,所以缩容的结果是可预知的。
image.png

像 Statefulset 创 建 pod 一样, Statefulset 也 需要创建持久卷声明 。 所以一个 Statefulset 可以拥有一个或多个卷声明模板, 这些持久卷声明会在创建 pod 前创建出来, 绑定到一个 pod 实例上。
image.png

使用StatefulSet

为了部署你的应用,需要创建两个(或三个〉不同类型的对象 :

  • 存储你数据文件的持久卷(当集群不支持持久卷的动态供应时,需要手动创建)
  • Statefulset 必需的一个控制 Service
  • StatefulSet 本身
  1. cat > myapp-statefulSet.yaml << EOF
  2. apiVersion: apps/v1
  3. kind: StatefulSet
  4. metadata:
  5. name: web
  6. spec:
  7. serviceName: "web"
  8. replicas: 3
  9. selector:
  10. matchLabels:
  11. app: web
  12. template:
  13. metadata:
  14. labels:
  15. app: web
  16. spec:
  17. terminationGracePeriodSeconds: 10
  18. containers:
  19. - name: nginx
  20. image: ikubernetes/myapp:v1
  21. ports:
  22. - containerPort: 80
  23. name: web
  24. ---
  25. apiVersion: v1
  26. kind: Service
  27. metadata:
  28. name: web
  29. namespace: default
  30. labels:
  31. app: web
  32. spec:
  33. selector:
  34. app: web
  35. clusterIP: None
  36. ports:
  37. - port: 80
  38. targetPort: 80
  39. protocol: TCP
  40. name: http
  41. EOF

image.png

image.png

解析service

dig  -t A   {service}.{namespace}.svc.cluster.local @kube-dns

image.png

image.png