• k8s配置StatefulSet解读


    什么是StatefulSet?
    直接参考原博客:k8s配置StatefulSet

    • StatefulSet和Deployment一样,可以保证集群中运行指定个数的pod,也支持横向扩展,但每个pod都是不可互换的。无论pod被怎样调度,它们的标记都不会改变,StatefulSet所创建的pod都是有状态的,所以pod重新调度之后,和它绑定的存储仍然是原先那个

    StatefulSet的一些限制和要求
    pod的存储必须使用StorageClass关联的PVC提供,或者由管理员预先创建好。
    删除StatefulSet或者是减小StatefulSet的replicas,k8s不会自动删除和已终止运行的pod绑定的数据卷。这样做是为了保证数据安全。
    为了确保StatefulSet管理的每个pod的网络标识不同,需要创建对应的headless service。
    当StatefulSet被删除的时候,它不能保证所有被管理的pod都停止运行。因此,在删除StatefulSet之前,需要先将它scale到0个pod。
    pod管理策略使用默认的OrderedReady,进行滚动升级的时候可能会出现问题,需要手工修复。
    StatefulSet的描述文件

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      annotations:
        auther: bigcc
      name: test-service
      namespace: default
    spec:
      serviceName: test-service
      replicas: 1
      selector:
        matchLabels:
          app: test-service
      template:
        metadata:
          labels:
            app: test-service
            env: t1
            sys: test
        spec:
          containers:
          - name: test-service
            image: harbor.com/test-service:latest
            imagePullPolicy: Always
            livenessProbe:
              initialDelaySeconds: 30
              periodSeconds: 60
              timeoutSeconds: 5
              tcpSocket:
                port: 80
            readinessProbe:
              initialDelaySeconds: 30
              periodSeconds: 60
              timeoutSeconds: 5
              httpGet:
                scheme: HTTP
                port: 9260
                path: /health
            env:
            - name: JAVA_OPTS
              value: -Didc=t1 -Denv=UAT -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/test-service
                -XX:+UseParallelGC -XX:MaxGCPauseMillis=1500 -XX:GCTimeRatio=9 -XX:+DisableExplicitGC
                -Dfile.encoding=UTF8 -Xms2048m -Xmx2048m -Xss512k
                -Dskywalking.agent.service_name=test-service-t1 -Dskywalking.collector.backend_service=10.1.1.1:11800
                -Dnoah.app.home=/usr/local/test-service/ -Dnoah.app.name=test-service -Dnoah.cat.servers=cathome.test.bigcc.com
                -Dnoah.host.type=Container -Dnoah.app.env=SIT -Dnoah.app.idc=aliyun -Dnoah.app.cluster=t1
            - name: CONFIG
              value: --eureka.client.serviceUrl.defaultZone=http://10.1.1.1:8761/eureka/
            - name: POD_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.podIP
            lifecycle:
              preStop:
                exec:
                  command:
                  - /bin/sh
                  - -c
                  - curl -X PUT http://10.1.1.1:8761/eureka/apps/test-service/${POD_IP}:9260/status?value=OUT_OF_SERVICE;sleep
                    120
            resources:
              limits:
                memory: 4Gi
                cpu: 2000m
              requests:
                memory: 2048Mi
                cpu: 1000m
            ports:
            - containerPort: 9260
              protocol: TCP
            volumeMounts:
            - name: logdata
              mountPath: /usr/local/test-service/logs/
          - name: logtail
            image: harbor.com/tool/logtail:latest
            command:
            - sh
            - -c
            - /usr/local/ilogtail/run_logtail.sh 10
            livenessProbe:
              exec:
                command:
                - /etc/init.d/ilogtaild
                - status
              initialDelaySeconds: 30
              periodSeconds: 30
            resources:
              limits:
                memory: 512Mi
              requests:
                memory: 512Mi
            env:
            - name: ALIYUN_LOGTAIL_USER_ID
              value: '12345678'
            - name: ALIYUN_LOGTAIL_USER_DEFINED_ID
              value: test-service-t1
            - name: ALIYUN_LOGTAIL_CONFIG
              value: /etc/ilogtail/conf/cn-shanghai/ilogtail_config.json
            - name: ALIYUN_LOG_ENV_TAGS
              value: _pod_name_|_pod_ip_|_namespace_|_node_name_|_node_ip_
            - name: _pod_name_
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: _pod_ip_
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: _namespace_
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: _node_name_
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: _node_ip_
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            volumeMounts:
            - name: logdata
              mountPath: /usr/local/test-service/logs/
          volumes:
          - name: logdata
            emptyDir: {}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128

    pod标识
    StatefulSet中每个pod的标识都是不同的。pod标识包含一个整数序号,固定的网络标识和存储标识。无论pod被调度到哪个节点运行,这些标识始终会跟随这个pod,如果StatefulSet运行了n个pod,这些pod会被编号,从0到n - 1。
    网络标识
    建立了对应的headless service之后,StatefulSet每个pod对应的DNS遵循如下的命名规则:
    ( s t a t e f u l s e t n a m e ) − (statefulset name)- (statefulsetname)(ordinal). ( s e r v i c e n a m e ) . (service name). (servicename).(namespace).svc.cluster.local
    #例如:web-0.nginx.default.svc.cluster.local
    存储标识
    每个pod都分配了一个单独的PV,PV和pod是强关联的。如果pod意外停止,无论再次启动的时候被调度到了何处,它仍然绑定到之前相同的PV上。如果这个pod,甚至是StatefulSet被删除,PV也不会被自动删除,需要手工操作。
    pod命名标签
    StatefulSet创建pod的时候会自动为pod添加一个statefulset.kubernetes.io/pod-name标签。可用于专门为某个特定的pod绑定service。
    StatefulSet的部署和扩缩容
    需要注意如下几点:

    StatefulSet创建pod的时候是串行化按照顺序执行,从0创建到n-1。
    删除pod的时候(比如缩容),按照相反的方向操作,即先删除pod n-1,在删除pod n-2,直到pod0。
    创建StatefulSet或者是扩容的之后,当且仅当一个pod运行成功进入就绪状态的时候,下一个pod才会开始创建。
    同理,StatefulSet缩容的时候,当且仅当一个pod彻底停止之后,下一个pod才会开始停止过程。
    StatefulSet不应该配置pod.Spec.TerminationGracePeriodSeconds为0,会有潜在的问题。
    Pod管理策略
    配置项位于.spec.podManagementPolicy。用来配置pod的创建和销毁是否可以并行操作。有如下两个配置值:

    OrderedReady:pod安装顺序创建和销毁。且每个pod的创建和销毁都必须要求前一个pod已经完全创建或销毁完毕。这个是默认的行为。
    Parallel:允许同时创建和销毁多个pod,不必等待前一个pod创建或销毁完毕。仅仅对扩容缩容有效,pod update过程不受影响。
    升级策略
    用来配置滚动升级的行为。配置项位于.spec.updateStrategy。
    可供配置的值如下:

    OnDelete:.spec.updateStrategy.type设置为OnDelete时,如果pod发生更新,StatefulSet不会更新已经运行的pod,必须将这些pod手工删除。新创建出来的pod是已更新过的pod。
    RollingUpdate:如果没有配置.spec.updateStrategy,默认使用这个配置。.spec.updateStrategy.type设置为RollingUpdate时,如果发生pod更新,StatefulSet会挨个删除并重新创建所有的pod。操作的顺序为从pod n-1 到 pod0,。即先删除pod n-1,等它彻底停止后,创建新的pod n-1。等pod n-1进入ready状态后,删除pod n-2 ……以此类推,直到操作完pod0。
    partition:配置一个.spec.updateStrategy.rollingUpdate.partition整数值。发生更新的时候,所有序号大于等于partition的pod会更新,所有序号小于partition的pod不会更新。即便是把序号小于partition的pod删除了,pod还是会按照之前的版本创建,不会更新。
    强制回滚
    如果滚动升级发生问题,某个pod总是无法进入就绪状态,StatefulSet会停止滚动升级,进入等待状态。发生这种情况的时候,仅仅将pod template修改正确是不够的。必须手工将无法启动的pod删除掉,StatefulSet会重新以正确的配置创建pod。否则StatefulSet仍会处于无限等待状态。
    需要注意
    StatefulSet会最大程度确保序号相同的pod同时只运行1个。
    比如说这个场景:

    集群中某个节点突然和集群失去网络联系,这个节点又恰好运行了某StatefulSet的一个pod。此时,这个pod不会立刻停止运行,状态会改变为Unknown。
    如果操作集群其他正常节点,手工删除这个pod,这个pod也不会真正删除,仅会被标记为删除(mark for deletion)。这时候k8s不会创建序号相同的pod,直到那个失去连接的节点重新连接到集群,k8s才会把这个pod删除,并创建出新的序号相同的pod。
    如果需要强制删除这个pod,可以执行如下命令(web-0为要强制删除的pod名称):
    kubectl delete po web-0 --force --grace-period 0

  • 相关阅读:
    mysql详细优化建议(谈谈你的SQL优化经验)
    计算机毕业设计之java+springboot基于vue的篮球竞赛预约平台
    DiffusionDet:第一个用于物体检测的扩散模型(DiffusionDet: Diffusion Model for Object Detection)
    Win10玩游戏老是弹回桌面的解决方法
    模型剪枝初级方法
    Heap (mathematics)
    R 语言patchwork包拼图间隙
    CompletableFuture异步编排(两任务组合——两个任务必须都完成才触发另一个任务 )
    vue3+ts withDefaults的使用
    力扣 -- 377. 组合总和 Ⅳ
  • 原文地址:https://blog.csdn.net/u013078871/article/details/126824797