zoukankan      html  css  js  c++  java
  • 十,StatefulSet简介及简单使用

    StatefulSet简介

    有状态应用副本集
    

    为什么要用statefulset控制器

    有状态和无状态

    无状态的, 更关注的是群体

    有状态的, 更关注的是个体

    有状态应用集的特点:

    1. 稳定且需要唯一的网络标识符;
      • 如: Redis集群,
        在Redis集群中,它是通过槽位来存储数据的,假如:第一个节点是01000,第二个节点是10012000,第三个节点2001~3000...等等,这就使得Redis集群中每个节点要通过ID来标识自己,如:
        第二个节点宕机了,重建后它必须还叫第二个节点,或者说第二个节点叫R2,它必须还叫R2,这样在获取1001~2000槽位的数据时,才能找到数据,否则Redis集群将无法找到这段数据。
    2. 稳定且持久的存储;
      • 可实现持久存储,新增或减少pod,存储不会随之发生变化。
    3. 要求有序, 平滑的部署和扩展;
      • 如 MySQL集群,要先启动主节点, 若从节点没有要求,则可一起启动,若从节点有启动顺序要求,可先启动第一个从节点,接着第二从节点等;这个过程就是有顺序,平滑安全的启动。
    4. 要求有序, 平滑的终止和删除;
      • 我们先终止从节点,若从节点是有启动顺序的,那么关闭时,也要按照逆序终止,即启动时是从S1~S4以此启动,则关闭时,则是先关闭S4,然后时S3,依次关闭,最后在关闭主节点。
    5. 有序的滚动更新;
      • MySQL在更新时,应该先更新从节点,全部的从节点都更新完了,最后在更新主节点,因为新版本一般可兼容老版本,但是一定要注意,若新版本不兼容老版本就很很麻烦

    statefulset的组成:

    1. headless service 用于定义网络标识(DNS)
    2. StatefulSet 控制器,用于定义具体应用
    3. volumeClaimTemplate 存储卷申请模板,用于创建PV

    简单测试 使用 StatefulSet

    创建基础的PV

    [root@master configmap]# cat ../volume/pv-demo.yaml 
    apiVersion: v1
    kind: PersistentVolume
    metadata: 
      name: pv001
      labels:
        name: pv001
    spec:
      nfs:
        path: /data/volumes/v1
        server: 172.27.1.241
      accessModes: ["ReadWriteMany", "ReadWriteOnce"]
      capacity:
        storage: 5Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata: 
      name: pv002
      labels:
        name: pv002
    spec:
      nfs:
        path: /data/volumes/v2
        server: 172.27.1.241
      accessModes: ["ReadWriteOnce"]
      capacity:
        storage: 5Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata: 
      name: pv003
      labels:
        name: pv003
    spec:
      nfs:
        path: /data/volumes/v3
        server: 172.27.1.241
      accessModes: ["ReadWriteMany", "ReadWriteOnce"]
      capacity:
        storage: 5Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata: 
      name: pv004
      labels:
        name: pv004
    spec:
      nfs:
        path: /data/volumes/v4
        server: 172.27.1.241
      accessModes: ["ReadWriteMany", "ReadWriteOnce"]
      capacity:
        storage: 10Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata: 
      name: pv005
      labels:
        name: pv005
    spec:
      nfs:
        path: /data/volumes/v5
        server: 172.27.1.241
      accessModes: ["ReadWriteMany", "ReadWriteOnce"]
      capacity:
        storage: 10Gi
    [root@master volume]# kubectl apply -f pv-demo.yaml 
    persistentvolume/pv001 created
    persistentvolume/pv002 created
    persistentvolume/pv003 created
    persistentvolume/pv004 created
    persistentvolume/pv005 created
    [root@master volume]# kubectl get pv -o wide
    NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   VOLUMEMODE
    pv001   5Gi        RWO,RWX        Retain           Available                                   5s    Filesystem
    pv002   5Gi        RWO            Retain           Available                                   5s    Filesystem
    pv003   5Gi        RWO,RWX        Retain           Available                                   5s    Filesystem
    pv004   10Gi       RWO,RWX        Retain           Available                                   5s    Filesystem
    pv005   10Gi       RWO,RWX        Retain           Available                                   5s    Filesystem
    

    StatefulSet 清单

    [root@master manifests]# cat statefulset-demo.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp-svc
      namespace: default
      labels:
        app: myapp                  # service 名称
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None               # 配置headless service
      selector:
        app: myapp-pod              # 匹配Pod 标签
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: myapp
    spec:
      serviceName: myapp            # 名称
      replicas: 3                   # 三个副本
      selector:
        matchLabels:
          app: myapp-pod            # 匹配Pod 
      template:
        metadata:
          labels:
            app: myapp-pod
        spec:
          containers:
          - name: myapp
            image: ikubernetes/myapp:v1
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: myappdata
              mountPath: /usr/shar/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: myappdata                   # pvc名称
        spec:
          accessModes: ["ReadWriteOnce"]    # 权限
          resources:
            requests:
              storage: 5Gi                  # pv 大小
    

    创建

    [root@master manifests]# kubectl apply -f statefulset-demo.yaml 
    service/myapp-svc unchanged
    statefulset.apps/myapp created
    [root@master manifests]# kubectl get sts
    NAME    READY   AGE
    myapp   3/3     5s
    [root@master manifests]# kubectl get pods
    NAME      READY   STATUS    RESTARTS   AGE
    myapp-0   1/1     Running   0          92s
    myapp-1   1/1     Running   0          91s
    myapp-2   1/1     Running   0          32s
    

    StatefulSet 会自动创建pvc, 然后去绑定对应符合要求的PV

    [root@master manifests]# kubectl get pvc
    NAME                STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    myappdata-myapp-0   Bound    pv002    5Gi        RWO                           2m42s
    myappdata-myapp-1   Bound    pv003    5Gi        RWO,RWX                       66s
    myappdata-myapp-2   Bound    pv001    5Gi        RWO,RWX                       7s
    [root@master manifests]# kubectl get pv
    NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                       STORAGECLASS   REASON   AGE
    pv001   5Gi        RWO,RWX        Retain           Bound       default/myappdata-myapp-2                           20m
    pv002   5Gi        RWO            Retain           Bound       default/myappdata-myapp-0                           20m
    pv003   5Gi        RWO,RWX        Retain           Bound       default/myappdata-myapp-1                           20m
    pv004   10Gi       RWO,RWX        Retain           Available                                                       20m
    pv005   10Gi       RWO,RWX        Retain           Available                                                       20m
    

    statefulset管理pod的启停顺序

    • 有序部署:部署StatefulSet时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态。
    • 有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。
    • 有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态

    statefulset管理策略

    • OrderedReady:上述的启停顺序,默认设置。

      spec:
        podManagementPolicy: OrderedReady
      
    • Parallel:告诉StatefulSet控制器并行启动或终止所有Pod,并且在启动或终止另一个Pod之前不等待前一个Pod变为Running and Ready或完全终止。

      spec:
        podManagementPolicy: Parallel
      
    扩容pod实验(顺序增加)
    [root@master manifests]# kubectl scale sts myapp --replicas=5  #扩容到5个pod
    [root@master manifests]# kubectl get pvc
    NAME                STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    myappdata-myapp-0   Bound    pv002    5Gi        RWO                           14m
    myappdata-myapp-1   Bound    pv003    5Gi        RWO,RWX                       14m
    myappdata-myapp-2   Bound    pv001    5Gi        RWO,RWX                       14m
    myappdata-myapp-3   Bound    pv004    10Gi        RWO,RWX                       7s
    myappdata-myapp-4   Bound    pv005    10i        RWO,RWX                       7s
    
    
    
    缩减pod实验(逆序减小,从最后的开始缩减)
    [root@master manifests]# kubectl scale sts myapp --replicas=2  #缩减到2个pod
    [root@master manifests]# kubectl get pvc
    NAME                STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    myappdata-myapp-0   Bound    pv002    5Gi        RWO                           14m
    myappdata-myapp-1   Bound    pv003    5Gi        RWO,RWX                       14m
    
    

    statefulSet的更新策略:

    kubectl explain sts.spec.updateStrategy.rollingUpdate
    

    partition: 这种更新策略的含义是, 若当前statefulSet的副本数为5个,则Pod名为pod-0~pod-4,那么此时定义partition=4, 就意味着我要更新大于等于4的Pod,而只有pod-4的ID 4 是大于等于4的,所以只有pod-4会被更新,其它不会,这就是金丝雀更新。若后期发现pod-4更新后,工作一切正常,那么就可以调整partition=0,这样只要大于等于0的pod ID都将被更新。

    金丝雀更新

    修改滚动更新策略,查看效果

    kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":2}}}}'
    #修改statefulset的image
    kubectl set image sts/myapp myapp=ikubernetes/myapp:v2
    
    #查看已经修改成功了
    [root@master statfulset]# kubectl get sts myapp -o wide
    NAME    READY   AGE   CONTAINERS   IMAGES
    myapp   4/4     16h   myapp        ikubernetes/myapp:v2
    

    因为策略写的是从第二个容器开始更新

    通过命令kubectl get pod myapp-1 -o yaml可以看到2之前的image没有改变

    通过命令kubectl get pod myapp-2 -o yaml可以看到2之后的image都已经改变了

    #再重新把partition改为0, 则把之前的pod的image都修改生效了
    kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":0}}}}'
    
    [root@master statfulset]# kubectl get pods -l app=myapp-pod -o custom-columns=NAME:metadata.name,IMAGE:spec.containers[0].image
    NAME      IMAGE
    myapp-0   ikubernetes/myapp:v2
    myapp-1   ikubernetes/myapp:v2
    myapp-2   ikubernetes/myapp:v2
    myapp-3   ikubernetes/myapp:v2
    

    暂存更新操作

    分区更新操作
    将spec.updateStrategy.rollingUpdate.partition设置为Pod副本数量时,即意味着所有Pod资源都不会处于可直接更新的分区内,直到partition小于Pod数时,才会开始更新

    此时,即便删除某Pod,也会按旧版本进行重建,即暂存状态的更新对所有Pod资源均不产生影响

    使用go-template自定义资源输出信息

    kubectl get pod myapp-1 -o go-template --template='{{.status.podIP}}'
    [root@master statfulset]# kubectl get pod myapp-1 -o go-template --template='{{range .spec.containers}}{{.image}}{{end}}'
    ikubernetes/myapp:v2
    

    因为这里查看containers的image信息是一个列表信息, 所以要用到range

    关于更多的go-template的使用方法, 可以参考这位老哥写的博客: https://www.bbsmax.com/A/gAJGgjX3JZ/

    访问测试:pod_name.service.ns_name.svc.cluster.local (myapp-2.myapp.default.svc.cluster.local)

  • 相关阅读:
    VS2013中使用本地IIS+域名调试ASP.NET项目
    layui框架中layer父子页面交互的方法分析
    Layer组件多个iframe弹出层打开与关闭及参数传递
    Android新版本特性以及注意事项
    【Android Studio安装部署系列】三十、从Android studio2.2.2升级到Android studio3.0之路
    【Android Studio安装部署系列】二十八、Android Studio查看其它APP的布局结构
    【Android Studio安装部署系列】二十七、Android studio修改项目名称和包名
    Beetle简单构建TCP服务
    【Android Studio安装部署系列】十三、Android studio添加和删除Module 2
    LeetCode242——Valid Anagram
  • 原文地址:https://www.cnblogs.com/peng-zone/p/11671413.html
Copyright © 2011-2022 走看看