k8s 环境下, 应用状态机设计

959 阅读3分钟

背景介绍

公司的产品最近通过K8S的方式做了自动化部署运维功能, 需要在前端实时的展示应用的状态, 并结合用户的操作, 给用户相应的反馈

比如稳定状态有: Running Stopped Degraded Panic 用户触发某 action 后的过渡状态有: Starting Stopping Deleting Updating

实现方式

状态分为了两种, 稳定状态和过渡状态。 他们分别是不同的实现方式

稳定状态是底层应用业务接口结合 k8s 轮询状态同步给上层的

过渡状态是另外创建的一个 task 对象来实现的, 具体下面会讲到

status_machine.jpg

上图中有说明,其中红线部分是用户触发的操作, 用户触发某 action 后, 应用会进入过渡状态。 黑色线条是底层实时同步的稳定状态的变化过程。 其中每个圆圈就表示一种状态,每条边就是一个操作。

既然已经有了底层状态同步, 为什么还需要 task 这么一个对象呢?

type Task struct {
	TaskID           string              `json:"task_id,omitempty"`
	Type             TaskType            `json:"type,omitempty"`
	Namespace        string              `json:"namespace,omitempty"`
	ClusterID        string              `json:"cluster_id,omitempty"`
	Image            string              `json:"image,omitempty"`
	Replicas         int32               `json:"replicas,omitempty"`
	StorageClassName string              `json:"storage_class_name,omitempty"`
	StorageClassSize string              `json:"storage_class_size,omitempty"` 
	Labels           map[string]string   `json:"labels,omitempty"`
	Env              map[string]string   `json:"env,omitempty"`
	License          []byte              `json:"license,omitempty"`
	Certificate      v1beta2.Certificate `json:"certificate,omitempty"`
	LogType          string              `json:"log_type,omitempty"`
	LogConfig        map[string]string   `json:"log_config,omitempty"`
	MetricConfig     map[string]string   `json:"metric_config,omitempty"`
	ResourceLimits   ResourceLimits      `json:"resource_limit,omitempty"`
	Network          NetworkConfig       `json:"network_config,omitempty"`
	ImagePullSecrets []ImagePullSecret   `json:"image_pull_secrets,omitempty"`
}

type TaskStatus struct {
	// TaskID
	TaskID string `json:"task_id"`

	// Task Status: TASK_STATUS_PENDING, TASK_STATUS_RUNNING, etc..
	Status uint8 `json:"status"`

	// string progress
	Progress string `json:"progress"`

	// auto generated if it is nil, or the provided value will be honored
	Updated *time.Time `json:"updated"`
}

// application stable status
const (
	APP_STATUS_RUNNING = iota + 1
	// replicas of the cluster less than expected
	APP_STATUS_DEGRADED
	// cluster stopped
	APP_STATUS_STOPPED
	// cluster deleted
	APP_STATUS_NOT_EXISTED
)

稳定状态说明

其中,常量部分是应用的稳定状态。 稳定状态是底层根据 K8S api 拿到的 Replicas 和 ExpectReplicas 做对比后确定的。 比如用户期望是 3 备份的应用服务, 但实际上是 2 备份的应用, 那么说明应用处于 APP_STATUS_DEGRADED 状态; 而如果是 0 备份, 那么就是 APP_STATUS_STOPPED 状态; 又或者应用对应的 Deployment 或者 Statefulset 对象都不存在, 那么也是 APP_STATUS_STOPPED 状态

如果这个应用对应的 namespace 都不存在, 那么说明该应用是 APP_STATUS_NOT_EXISTED 状态

这里有些名称是 K8S 里的概念, 具体可以自己搜索查询

过渡状态说明

这里一个 task 表示一个用户触发的 action 。 比如 Create、Stop、 Start、 Delete 等等, 这些 action 都一个个用户的操作, 那么用户操作后, 应用就会进入过渡状态; 至于过渡状态的进度, 则是由 TaskStatus 对象实时反馈

其中, TaskStatus.Status 用来表示该 action 的 task 进展状态, 比如 准备中 进行中 已完成 异常 等等。 而 TaskStatus.Progress 用来表示该 action 的 task 进展百分比进度条, 比如 10% 90% 100%, 方便前端给用户实时的进展反馈

总的状态判断逻辑

用户看到的状态, 是通过如下流程图得到的, 结合了 Task 和 K8s+应用健康检查

status_check.jpg

这种判断逻辑的好处是,既实时反映了应用的状态, 同时又对用户的 action 操作提供了可视化反馈