zoukankan      html  css  js  c++  java
  • Kubernetes Conditions

    1、概述

    绝大部分Kubernetes资源对象都包含status.conditions字段,用来表示资源状态,比如deployment资源中的status.conditions如下所示:

    conditions:
      - lastTransitionTime: "2021-12-27T01:50:58Z"
        lastUpdateTime: "2021-12-27T01:50:58Z"
        message: Deployment has minimum availability.
        reason: MinimumReplicasAvailable
        status: "True"
        type: Available
      - lastTransitionTime: "2021-12-27T01:50:54Z"
        lastUpdateTime: "2021-12-27T01:50:58Z"
        message: ReplicaSet "nginx-v1-68b775fc4b" has successfully progressed.
        reason: NewReplicaSetAvailable
        status: "True"
        type: Progressing
    

    deployment 的 conditions 状况默认只有两个,它是由Deployment controller生成,一是达到最小的可用副本数就变为 True,另一个是新的 rs 可用了就变为 True。

    以上conditions的信息是很容易读懂的,然而有个问题曾经让我很困惑,那就是:

    • conditionsstatus到底有什么区别?
    • conditions的设计原则是什么?在设计API扩展时,该如何定义conditions

    本节会先从conditions的设计原则讲起,再介绍一些设计conditions时的一些经验总结。

    2、conditions设计原则

    conditions寄居于资源对象的status字段中,与status其他字段值一样都用来表示资源的状态。不过conditions的设计初衷是提供一种通用的数据结构表示资源的状态,它通常能够提供比status其他字段更详细的信息(比如状态切换时间、更新时间),conditions实际上是一种扩展机制,外部监控程序可以根据conditions无差别地监控各种资源的状态,而不必过分关注资源对象status中的其他信息。

    通常status.conditions字段类型为切片,切片中的每个元素表示资源的某个状态,该状态由特定的控制器更新,比如Deployment控制器会更新deployment对象的status.conditions信息。conditions作为扩展机制,它还支持第三方控制器增加新的状态。通常status.conditions中的信息由控制器根据资源的status其他字段计算出来。

    3、condition字段内容

    通常一个condition必须包含type(状态类型)和status(状态值)两个信息。在Kubernetes v1.19版之前,关于condition并没有统一的标准,导致众多API都自行定义了condition。比如:

    • Deployment使用的Condition为type DeploymentCondition struct;
    • Pod使用的Condition为type PodCondition struct;

    庆幸的是,在Kubernetesv1.19版本社区提供了一个标准的condition类型定义,由于兼容性考虑,Kubernetes既有的API不一定能采用这一标准类型,但对于后续新增的API将会使用这一标准类型,并且笔者建议用户设计的CRD扩展也应使用这一标准类型。

    标准的condition类型定义如下所示:

    type ConditionStatus string
    
    const (
    	ConditionTrue    ConditionStatus = "True"
    	ConditionFalse   ConditionStatus = "False"
    	ConditionUnknown ConditionStatus = "Unknown"
    )
    
    type Condition struct {
    	// 类型(使用驼峰风格),如”Available“。
    	Type string
    	// 状态(枚举值:”True“、”False“和”Unknown“)。
    	Status ConditionStatus
    	// 观察到的generation。
    	// 如果ObservedGeneration 比metada.generation小,说明不是最新状态。
    	// +optional
    	ObservedGeneration int64
    	// 上次变化时间
    	LastTransitionTime Time
    	// 状态变化原因(使用驼峰风格),如”NewReplicaSetAvailable“
    	Reason string
    	// 描述信息,如”Deployment has minimum availability“
    	Message string `json:"message" protobuf:"bytes,6,opt,name=message"`
    }

    标准的condition类型定义对condition的各个字段做了进一步约定。除了ObservedGeneration是可选的以外,其他字段都是必填的。

    4、condition设计约定

    为了让condition起到最大的作用,需要遵守一定的设计约定:

    约定一:condition定义要有明确的信息

    每个condition需要传递一个用户关心的明确信息,用户读取到该信息不需要再根据资源的其他状态来揣测和计算。

    约定二:condition需要保持兼容

    condition一旦被定义,它就成了API中的一部分,需要跟API一样提供稳定性保证。如果需要新的condition仍然可以增加(没有破坏兼容性),但既有的condition是否能够改变就需要根据API成熟度来决定,比如stable的API不可以改变,alpha的API可以改变。

    约定三:condition需要控制器第一次处理资源时更新

    控制器需要尽快地更新condition状态值(condition.status),即便该状态值为Unknown,这么做的好处是可以让其他组件了解到控制器正在调谐这个资源。

    然而,并不是所有的控制器都能遵守这个约定,即控制器并不会报告特定的condition(此时该condition状态值可能为Unknown),可能该condition还无法确定,需要在下一次调谐时决定。此种情况下,外部组件无法读取到特定的condition,可以假设该conditionUnknown

    约定四:condition类型名需要确保可读性

    condition类型名要使用人类可读的名称,而且尽量避免出现双重否定的语境。例如,类型名Ready比使用Failed要好,因为condition状态为False时,Failed = False将出现双重否定,不如Ready = False容易理解。

    约定五:condition不要定义成状态机

    condition需要描述当前资源的确定状态,而不是当前资源状态机中的状态。通俗地讲,condition类型需要使用形容词(如Ready)或过去动词(Succeeded),而不是使用当前运行时(如Deploying)。

    5、常用资源Conditions解释(持续更新)

    5.1 Pod conditions

    Pod 的 conditions 表示了 Pod 的一些条件,是一个数组。pod的 conditions 状况默认有4个,它是由Pod controller生成,里面包含一些 Pod 必须满足的条件,只有所有的条件为 True 时,Pod 才可以提供服务。

    • PodScheduled:Pod 已经被调度到某节点;
    • ContainersReady:Pod 中所有容器都已就绪;
    • Initialized:所有的 Init容器都已成功启动;
    • Ready:Pod 可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中。
    字段名称描述
    type Pod 状况的名称
    status 表明该状况是否适用,可能的取值有 "True", "False" 或 "Unknown"
    lastProbeTime 上次探测 Pod 状况时的时间戳
    lastTransitionTime Pod 上次从一种状态转换到另一种状态时的时间戳
    reason 机器可读的、驼峰编码(UpperCamelCase)的文字,表述上次状况变化的原因
    message 人类可读的消息,给出上次状态转换的详细信息

    使用readinessGates自定义 Pod 状况信息 

    FEATURE STATE: Kubernetes v1.14 [stable]

    你的应用可以向 PodStatus 中注入额外的反馈或者信号:Pod Readiness(Pod 就绪态)。 要使用这一特性,可以设置 Pod 规约中的 readinessGates 列表,为 kubelet 提供一组额外的状况供其评估 Pod 就绪态时使用。

    就绪态门控基于 Pod 的 status.conditions 字段的当前值来做决定。 如果 Kubernetes 无法在 status.conditions 字段中找到某状况,则该状况的状态值默认为 "False"。

    这里是一个例子(更详细例子参见:【k8s】Pod-readinessGates):

    kind: Pod
    ...
    spec:
      readinessGates:
        - conditionType: "www.example.com/feature-1"
    status:
      conditions:
        - type: Ready                              # 内置的 Pod 状况
          status: "False"
          lastProbeTime: null
          lastTransitionTime: 2018-01-01T00:00:00Z
        - type: "www.example.com/feature-1"        # 额外的 Pod 状况
          status: "False"
          lastProbeTime: null
          lastTransitionTime: 2018-01-01T00:00:00Z
      containerStatuses:
        - containerID: docker://abcd...
          ready: true
    ...

    命令 kubectl patch 不支持修改对象的状态。 如果需要设置 Pod 的 status.conditions,应用或者 Operators 需要使用 PATCH 操作。 你可以使用 Kubernetes 客户端库 之一来编写代码,针对 Pod 就绪态设置定制的 Pod 状况。

    对于使用定制状况的 Pod 而言,只有当下面的陈述都适用时,该 Pod 才会被评估为就绪:

    • Pod 中所有容器都已就绪;
    • readinessGates 中的所有状况都为 True 值。 

    参考:https://my.oschina.net/renhc/blog/4809076

    参考:https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

    参考:https://www.cnblogs.com/jiangbo44/p/14589407.html

  • 相关阅读:
    Delegate(委托与事件)
    eclipse2020-06创建属于自己的JSP模板(图文)
    eclipse没有新建web项目的解决问题
    my97datepicker实现日期改变立刻触发函数
    jetty启动项目后js修改后无法保存
    js连续的日期判断,判断相差几天
    同步和异步
    面试题
    MYSQL 数据库名、表名、字段名查询
    Spring-MVC
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/15736028.html
Copyright © 2011-2022 走看看