前面介绍的Pod管理对象,如RC/RS、Deployment、DaemonSet等都是面向无状态服务的,而对于有状态的应用,比如MySQL集群,MongoDB集群等,则可以使用StatefulSet来完成。有状态的应用集群通常有以下这些特点:
每个节点都有固定的身份ID,通过这个ID,集群中的成员可以相互发现并通信;
集群的规模是比较固定的,集群规模不能随意变动;
集群中的每个节点都是有状态的,通常会持久化数据到永久存储中。
StatefulSet特性
通过StatefulSet搭建的集群通常有以下这些特性:
StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员。假设StatefulSet的名称为nginx,那么第1个Pod叫nginx-0,第2个叫nginx-1,以此类推;
StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态。
StatefulSet里的Pod采用稳定的持久化存储卷,通过PV或PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷(为了保证数据的安全);
配合Headless Service使用,用于发现和控制Pod实例数量。
StatefulSet实践
下面使用StatefulSet搭建个Nginx集群,持久化存储使用上一节搭建的名称为managed-nfs-storage的StorageClass。
创建nginx-headless-service.yml配置文件:
1 | apiVersion: v1 |
创建该Headless Service:
1 | kubectl create -f nginx-headless-service.yml |
接着创建nginx-statefulset.yml配置文件:
1 | apiVersion: apps/v1 |
创建该StatefulSet,观察pod的创建过程:
可以看到,pod的创建是严格one by one的,因为我们定义的StatefulSet的名称位nginx-sc,所以Pod的名称分别位nginx-sc-0、nginx-sc-1和nginx-sc-2。
查看对应的PVC和PV:
状态为Bound。
删除Pod,再次观察Pod的创建过程:
可以看到顺序性是严格保证的。
进入到Pod内部,查看其hostname:
hostname和pod名称一致。
到192.168.33.13的/nfs目录下可以看到挂载了三个nginx目录:
《Kubernetes权威指南(第4版)》读书笔记