Kubernetes StatefulSet

前面介绍的Pod管理对象,如RC/RS、Deployment、DaemonSet等都是面向无状态服务的,而对于有状态的应用,比如MySQL集群,MongoDB集群等,则可以使用StatefulSet来完成。有状态的应用集群通常有以下这些特点:

  1. 每个节点都有固定的身份ID,通过这个ID,集群中的成员可以相互发现并通信;

  2. 集群的规模是比较固定的,集群规模不能随意变动;

  3. 集群中的每个节点都是有状态的,通常会持久化数据到永久存储中。

StatefulSet特性

通过StatefulSet搭建的集群通常有以下这些特性:

  1. StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员。假设StatefulSet的名称为nginx,那么第1个Pod叫nginx-0,第2个叫nginx-1,以此类推;

  2. StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态。

  3. StatefulSet里的Pod采用稳定的持久化存储卷,通过PV或PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷(为了保证数据的安全);

  4. 配合Headless Service使用,用于发现和控制Pod实例数量。

StatefulSet实践

下面使用StatefulSet搭建个Nginx集群,持久化存储使用上一节搭建的名称为managed-nfs-storage的StorageClass。

创建nginx-headless-service.yml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
name: nginx
spec:
ports:
- port: 80
targetPort: 80
clusterIP: None # 表明为Headleass Service
selector:
role: web-app

创建该Headless Service:

1
kubectl create -f nginx-headless-service.yml

接着创建nginx-statefulset.yml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-sc
spec:
serviceName: "nginx" # 对应刚刚创建的Headless Service名称
replicas: 3
selector:
matchLabels:
role: web-app
template:
metadata:
labels:
role: web-app
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: nginx-persistent-storage # 和下面的pvc名称对应
volumeClaimTemplates: # pvc模板
- metadata:
name: nginx-persistent-storage # pvc名称
spec:
storageClassName: managed-nfs-storage # 指定StorageClass名称
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 100Mi

创建该StatefulSet,观察pod的创建过程:

QQ截图20191127163115.png

可以看到,pod的创建是严格one by one的,因为我们定义的StatefulSet的名称位nginx-sc,所以Pod的名称分别位nginx-sc-0、nginx-sc-1和nginx-sc-2。

查看对应的PVC和PV:

QQ截图20191127163428.png

状态为Bound。

删除Pod,再次观察Pod的创建过程:

QQ截图20191127172411.png

可以看到顺序性是严格保证的。

进入到Pod内部,查看其hostname:

QQ截图20191127172632.png

hostname和pod名称一致。

到192.168.33.13的/nfs目录下可以看到挂载了三个nginx目录:

QQ截图20191127172826.png

《Kubernetes权威指南(第4版)》读书笔记

请作者喝瓶肥宅水🥤

0