Kubernetes(简称K8s)是一个开源的容器编排引擎,用于自动化应用程序的部署、扩展和管理。在Kubernetes中,StatefulSet是一种用于管理有状态应用的控制器,与无状态应用的Deployment不同,它确保了每个Pod都有一个唯一的标识和稳定的存储。
StatefulSet的设计目标是支持有状态应用程序的部署和扩展。它主要有以下几个核心特点:
稳定的网络标识:每个Pod在StatefulSet中的名字是稳定的,即使重启也不会改变。Pod的名字格式为<statefulset name>-<ordinal>
,例如mysql-0
、mysql-1
。
稳定的存储:每个Pod都可以有一个或多个PVC(Persistent Volume Claim),这些PVC在Pod重启或重新调度时依然保持不变。
有序部署和缩放:StatefulSet按照顺序创建和删除Pod,例如,只有在mysql-0
成功创建并运行后,才会创建mysql-1
。同样,当缩减时,mysql-2
会先被删除,接着是mysql-1
。
有序更新:在进行滚动更新时,StatefulSet会按顺序更新Pod,确保每个Pod都更新并稳定运行后再更新下一个。
StatefulSet适用于需要以下特性的应用程序:
有状态服务:如数据库(MySQL、PostgreSQL)、分布式文件系统(HDFS、GlusterFS)等。
分布式系统:如Zookeeper、Kafka、Elasticsearch等。
需要稳定标识和存储的应用:如需持久化数据并且需要保证Pod在重启后可以恢复到之前状态的应用。
在Kubernetes中,通过StatefulSet来部署一个MySQL集群是一个典型的应用场景。下面是一个简单的配置示例:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
ports:
- containerPort: 3306
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-persistent-storage
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "nfs-client" #存储类名,改为集群中已存在的
resources:
requests:
storage: 1Gi
其中storageClassName
可以通过kubectl get sc
获取。如下图:
上述配置将创建一个MySQL集群,其中包含3个实例,每个实例都有一个独立的持久存储卷。每个Pod在集群中有一个唯一的名字,如mysql-0
、mysql-1
和mysql-2
,并且这些名字在Pod重启时保持不变。
等了十几分钟这个StatefulSet
还没部署完,通过查看Pod的日志文件,发现镜像拉取成功,如下图:
通过上述事件信息发现,是后端存储的问题,于是,通过kubectl logs -f pods/mysql-0
查看其中一个Pod的日志信息,如下:
通过上述的日志信息,可以发现是没有权限导致启动MySQL服务器失败,由于我后端存储采用的是NFS。
rw
:客户端对共享的目录可读写
ro
:客户端对共享的目录只读不可写
sync
:同步模式,也就是把内存的数据实时写入硬盘,但这样会降低磁盘效率
async
:非同步模式,也就是每隔一段时间才会把内存的数据写入硬盘,能保证磁盘效率,但当异常宕机/断电时,会丢失内存里的数据
no_root_squash
:客户端挂载NFS共享目录后,客户端上的root用户不受这些挂载选项的限制,权限很大
root_squash
:跟no_root_squash相反,客户端上的root用户受到这些挂载选项的限制,被当成普通用户
all_squash
:客户端上的所有用户在使用NFS共享目录时都被限定为一个普通用户
anonuid
:上面的几个squash用于把客户端的用户限定为普通用户,而anouid用于限定这个普通用户的uid,这个uid与服务端的/etc/passwd文件相对应。
修改后重启NFS服务器,重启部署StatefulSet
服务,结果如下:
虽然StatefulSet和DaemonSet都是Kubernetes中的控制器,但它们用于不同的场景并具有不同的特性:
StatefulSet:主要用于管理有状态应用,确保Pod有稳定的网络标识和存储,并且按照顺序部署和更新。
DaemonSet:用于在每个节点上运行一个Pod,适合需要全局运行在所有节点上的系统服务和守护进程。
选择哪种控制器取决于具体应用的需求。例如,如果需要在每个节点上运行一个日志收集器,则应该使用DaemonSet;如果需要管理一个有状态的数据库集群,则应使用StatefulSet。
StatefulSet为在Kubernetes上管理有状态应用程序提供了强大的支持。通过提供稳定的网络标识和持久化存储,StatefulSet可以确保应用程序在扩展、更新和重启时保持数据的一致性和持久性。无论是部署数据库、分布式系统还是其他需要稳定标识和存储的应用,StatefulSet都能为其提供可靠的解决方案。通过实际案例,我们可以看到StatefulSet在生产环境中的应用和优势,为开发者和运维人员提供了有力的工具。
联系客服