• Kubernetes学习笔记(九):StatefulSet--部署有状态的多副本应用


    StatefulSet如何提供稳定的网络标识和状态

    ReplicaSet中的Pod都是无状态,可随意替代的。又因为ReplicaSet中的Pod是根据模板生成的多副本,无法对每个副本都指定单独的PVC。

    来看一下StatefulSet如何解决的。

    提供稳定的网络标识

    StatefulSet创建Pod都有一个从零开始的顺序索引,这会体现在Pod的名称和主机名上,同样也会体现在Pod对应的固定存储上。所以这些名字是可预先知道的,不同于ReplicaSet的随机生成名字。

    因为他们的名字都是固定的,而且彼此状态都不同,通常会操作他们其中的一个。如此情况,一般都会创建一个与之对应的headless Service,通过这个Service,每个Pod将拥有独立的DNS记录。

    扩容一个StatefulSet会使用下一个顺序索引创建一个新的Pod,缩容会删除索引值最高的。并且缩容任何时候只会操作一个Pod。

    如何提供稳定的存储

    StatefulSet可以拥有一个或多个PVC模板,这些PVC会在创建Pod前创建出来,绑定到一个Pod实例上。

    扩容的时候会创建一个Pod以及若干个PVC,删除的时候只会删除Pod。StatefulSet缩容时不会删除PVC,扩容时会重新挂上。

    使用StatefulSet

    定义三个PV

    定义pv-(a|b|c)

    # stateful-pv-list.yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-a
    spec:
      capacity:
        storage: 1Mi
      accessModes:
      - ReadWriteOnce
      persistentVolumeReclaimPolicy: Recycle
      hostPath:
        path: /tmp/pva
    ---
    apiVersion: v1
    kind: PersistentVolume
    # 以下忽略
    

    headless的Service

    # stateful-service-headless.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: rwfile
    spec:
      clusterIP: None
      selector:
        app: rwfile
      ports:
      - port: 80
    

    定义StatefulSet

    先创建两个Pod副本。使用volumeClaimTemplates定义了PVC模板。

    # stateful.yaml
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: rwfile
    spec:
      replicas: 2
      serviceName: rwfile
      selector:
        matchLabels:
         app: rwfile
      template:
        metadata:
          labels:
            app: rwfile
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/orzi/rwfile
            name: rwfile
            ports:
            - containerPort: 8000
            volumeMounts:
            - name: data
              mountPath: /tmp/data
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          resources:
            requests:
              storage: 1Mi
          accessModes:
          - ReadWriteOnce
    

    创建三个PV,一个headless的Service,一个StatefulSet

    -> [root@kube0.vm] [~] k create -f stateful-pv-list.yaml
    persistentvolume/pv-a created
    persistentvolume/pv-b created
    persistentvolume/pv-c created
    
    -> [root@kube0.vm] [~] k create -f stateful-service-headless.yaml
    service/rwfile created
    
    -> [root@kube0.vm] [~] k create -f stateful.yaml
    statefulset.apps/rwfile created
    

    查看

    -> [root@kube0.vm] [~] k get all -o wide
    NAME                    READY   STATUS      RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
    pod/rwfile-0            1/1     Running     0          12s   10.244.1.52   kube1.vm   <none>           <none>
    pod/rwfile-1            1/1     Running     0          8s    10.244.2.56   kube2.vm   <none>           <none>
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
    service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   81s   <none>
    service/rwfile       ClusterIP   None         <none>        80/TCP    23s   app=rwfile
    
    NAME                      READY   AGE   CONTAINERS   IMAGES
    statefulset.apps/rwfile   2/2     12s   rwfile       registry.cn-hangzhou.aliyuncs.com/orzi/rwfile
    

    查看PV和PVC,可以看到已经有两个PVC绑定了PV

    -> [root@kube0.vm] [~] k get pv,pvc -o wide
    NAME                    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                   STORAGECLASS   REASON   AGE     VOLUMEMODE
    persistentvolume/pv-a   1Mi        RWO            Recycle          Bound       default/data-rwfile-0                           7m20s   Filesystem
    persistentvolume/pv-b   1Mi        RWO            Recycle          Bound       default/data-rwfile-1                           7m20s   Filesystem
    persistentvolume/pv-c   1Mi        RWO            Recycle          Available                                                   7m20s   Filesystem
    
    NAME                                  STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE     VOLUMEMODE
    persistentvolumeclaim/data-rwfile-0   Bound    pv-a     1Mi        RWO                           6m55s   Filesystem
    persistentvolumeclaim/data-rwfile-1   Bound    pv-b     1Mi        RWO                           6m51s   Filesystem
    

    请求Pod

    启动代理

    -> [root@kube0.vm] [~] k proxy
    Starting to serve on 127.0.0.1:8001
    

    发送请求

    -> [root@kube0.vm] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/ -d "a=123"
    data stored in : rwfile-0
    
    -> [root@kube0.vm] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/
    a=123
    

    删除测试

    删除rwfile-0,然后查看,从时间上看确实是被删除重建的。

    -> [root@kube0.vm] [~] k delete po rwfile-0
    pod "rwfile-0" deleted
    
    -> [root@kube0.vm] [~] k get po
    NAME                READY   STATUS      RESTARTS   AGE
    rwfile-0            1/1     Running     0          7s
    rwfile-1            1/1     Running     0          19m
    

    看一下之前存储的数据还在不在

    -> [root@kube0.vm] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/
    a=123
    

    还是在的,此次测试实际上也证明了StatefulSet提供了稳定的网络标识和存储。

    发现StatefulSet的伙伴节点

    使用DNS解析headless的Service的FQDN。
    例子以后再写吧。。

    如何处理节点失效

    除非确定节点无法运行或者不会在访问,否则不要强制删除有状态的Pod

    k delete pod rwfile-0 --force --grace-period 0
    

    小结

    • StatefulSet创建Pod都有一个从零开始的顺序索引
    • 通常会创建一个与StatefulSet对应的headless Service。
    • 扩容一个StatefulSet会使用下一个顺序索引创建一个新的Pod,缩容会删除索引值最高的。
    • 新建StatefulSet需要指定headless ServiceName和volumeClaimTemplates。
    • 使用DNS发现StatefulSet的伙伴节点
    • 强制删除:k delete pod rwfile-0 --force --grace-period 0
  • 相关阅读:
    今天分享一个参数转Python字典的案例
    Django 列表搜索后,进行数据编辑,保存后返回搜索前的页面 && 多条件搜索
    django 中多条件搜索
    selenium 对滑动验证框的处理
    django 中使用request请求失败,requests.exceptions.ConnectionError: HTTPConnectionPool(host='xxx', port=80):
    java Spring boot 单元测试 @Autowired 注入为空
    Vue中显示js格式插件vue-json-viewer
    Vue-cli项目中过滤器使用
    Vue 中权限校验
    Vue平台项目问题汇总
  • 原文地址:https://www.cnblogs.com/flhs/p/12967876.html
Copyright © 2020-2023  润新知