k8s StatefulSet

在 Kubernetes 的世界中,ReplicaSet 和 Deployment 主要用于处理无状态的服务,无状态服务的需求往往非常简单并且轻量,每一个无状态节点存储的数据在重启之后就会被删除,虽然这种服务虽然常见,但是我们仍然需要有状态的服务来实现一些特殊的需求,StatefulSet 就是 Kubernetes 为了运行有状态服务引入的资源,例如 Zookeeper、Kafka 等。

这篇文章会介绍 Kubernetes 如何在集群中运行有状态服务,同时会分析这些有状态服务 StatefulSet 的同步过程以及实现原理。

概述

StatefulSet 是用于管理有状态应用的工作负载对象,与 ReplicaSet 和 Deployment 这两个对象不同,StatefulSet 不仅能管理 Pod 的对象,还它能够保证这些 Pod 的顺序性和唯一性。

与 Deployment 一样,StatefulSet 也使用规格中声明的 template 模板来创建 Pod 资源,但是这些 Pod 相互之间是不能替换的;除此之外 StatefulSet 会为每个 Pod 设置一个单独的持久标识符,这些用于标识序列的标识符在发生调度时也不会丢失。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

如果我们在 Kubernetes 集群中创建如上所示的 StatefulSet 对象,会得到以下结果,Kubernetes 不仅会创建 StatefulSet 对象,还会自动创建两个 Pod 副本:

$ kubectl get statefulsets.apps
kNAME   READY   AGE
web    2/2     2m27s

$ kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          2m31s
web-1   1/1     Running   0          105s

$ kubectl get persistentvolumes
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS       REASON   AGE
pvc-19ef374f-39d1-11e9-b870-9efb418608da   1Gi        RWO            Delete           Bound    default/www-web-1   do-block-storage            21m
pvc-fe53d5f7-39d0-11e9-b870-9efb418608da   1Gi        RWO            Delete           Bound    default/www-web-0   do-block-storage            21m

$ kubectl get persistentvolumeclaims
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
www-web-0   Bound    pvc-fe53d5f7-39d0-11e9-b870-9efb418608da   1Gi        RWO            do-block-storage   21m
www-web-1   Bound    pvc-19ef374f-39d1-11e9-b870-9efb418608da   1Gi        RWO            do-block-storage   21m

除此之外,上述 YAML 文件中的 volumeClaimTemplates 配置还会创建持久卷PersistentVolume 和用于绑定持久卷和 Pod 的 PersistentVolumeClaim 资源;
两个 Pod 对象名中包含了它们的序列号,该序列号会在 StatefulSet 存在的时间内保持不变,哪怕 Pod 被重启或者重新调度,也不会出现任何的改变。

StatefulSet 的拓扑结构和其他用于部署的资源其实比较类似,比较大的区别在于 StatefulSet 引入了 PV 和 PVC 对象来持久存储服务产生的状态,这样所有的服务虽然可以被杀掉或者重启,但是其中的数据由于 PV 的原因不会丢失。

实现原理

与 ReplicaSet 和 Deployment 资源一样,StatefulSet 也使用控制器的方式实现,它主要由 StatefulSetControllerStatefulSetControlStatefulPodControl 三个组件协作来完成 StatefulSet 的管理,StatefulSetController 会同时从 PodInformerReplicaSetInformer 中接受增删改事件并将事件推送到队列中:

控制器 StatefulSetController 会在 Run 方法中启动多个 Goroutine 协程,这些协程会从队列中获取待处理的 StatefulSet 资源进行同步,接下来我们会先介绍 Kubernetes 同步 StatefulSet 的过程。

原文

https://draveness.me/kubernetes-statefulset

你可能感兴趣的:(k8s StatefulSet)