Kubernetes StatefulSet


2019年11月27日 15:54:41   751 次浏览

前面介绍的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配置文件:

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:

kubectl create -f nginx-headless-service.yml

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

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的创建过程:

可以看到,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目录:

发表评论

邮箱地址不会被公开。 必填项已用*标注