☰
python-kubernetes aio 客户端中 V1StatefulSet 模型详解:字段、序列化与异步用法
2026/10/10 5:48:33 网站建设 项目流程
  • 后端
  • 云原生
  • 容器编排

【免费下载链接】python

Official Python client library for kubernetes

项目地址:https://gitcode.com/gh_mirrors/python1/python
点击查看免费下载

V1StatefulSet是 kubernetes Python 客户端(aio 异步版本)中对应 Kubernetesapps/v1StatefulSet 资源的 Pydantic 数据模型。本文基于仓库中的 API 参考文档 kubernetes.aio.client.models.v1_stateful_set.rst 及其背后的生成代码 v1_stateful_set.py,完整讲解该模型的字段构成、spec/status子模型、序列化与别名处理机制,并给出在异步客户端(kubernetes.aio)中创建、更新和滚动回滚 StatefulSet 的可运行示例,帮助你把官方文档骨架落地为实际可用的异步运维代码。

1. 参考文档与模型的位置

仓库中的 API 参考文档 kubernetes.aio.client.models.v1_stateful_set.rst 通过 Sphinx 的automodule指令直接引用kubernetes.aio.client.models.v1_stateful_set模块:

kubernetes.aio.client.models.v1\_stateful\_set module ===================================================== .. automodule:: kubernetes.aio.client.models.v1_stateful_set :members: :show-inheritance: :undoc-members:

也就是说,文档页呈现的内容完全由源码中的类定义、字段声明与 docstring 决定。同族的参考文档还包括:

  • kubernetes.aio.client.models.v1_stateful_set_spec.rst
  • kubernetes.aio.client.models.v1_stateful_set_status.rst
  • kubernetes.aio.client.models.v1_stateful_set_condition.rst
  • kubernetes.aio.client.models.v1_stateful_set_list.rst

对应的源码文件位于kubernetes/aio/client/models/目录下,均由 OpenAPI Generator 根据 swagger.json(OpenAPI 版本release-1.37,见模块头部注释)生成,文件内明确标注 "Do not edit the class manually",即生产环境中不应手工修改这些模型文件。

2. V1StatefulSet 顶层字段

在 v1_stateful_set.py 中,V1StatefulSet继承自 PydanticBaseModel,其类 docstring 给出了资源语义:

StatefulSet represents a set of pods with consistent identities. Identities are defined as:

  • Network: A single stable DNS and hostname.
  • Storage: As many VolumeClaims as requested.

The StatefulSet guarantees that a given network identity will always map to the same storage identity.

即 StatefulSet 为 Pod 提供稳定的网络身份(DNS/主机名)和稳定的存储身份(与 Pod 一一对应的 PVC)。顶层共 5 个字段:

Python 字段线上 JSON 字段(alias)类型是否必填说明
api_versionapiVersionOptional[StrictStr]否对象表示的版本化 schema,如"apps/v1"
kindkindOptional[StrictStr]否REST 资源类型,如"StatefulSet"
metadatametadataOptional[V1ObjectMeta]否标准元数据(name、namespace、labels 等)
specspecV1StatefulSetSpec是StatefulSet 规约,唯一不可省略的字段
statusstatusOptional[V1StatefulSetStatus]否由控制器维护的当前状态

两个 ClassVar 属性辅助框架工作:

openapi_types: ClassVar[Dict[str, str]] = { "api_version": "str", "kind": "str", "metadata": "V1ObjectMeta", "spec": "V1StatefulSetSpec", "status": "V1StatefulSetStatus" } attribute_map: ClassVar[Dict[str, str]] = { "api_version": "apiVersion", "kind": "kind", "metadata": "metadata", "spec": "spec", "status": "status" }

openapi_types记录字段到类型的映射,attribute_map记录 Python 属性名到线上 JSON 键名的映射(蛇形命名 ↔ 驼峰命名),这是 OpenAPI Generator python 系模板的通用约定。

2.1 模型配置:别名验证与未知字段拒绝

v1_stateful_set.py 中的model_config值得注意:

model_config = ConfigDict( validate_by_name=True, validate_by_alias=True, validate_assignment=True, extra="forbid", protected_namespaces=(), )
  • validate_by_name=True+validate_by_alias=True:构造和反序列化时,字段既可以用 Python 名(api_version)也可以用线上 alias(apiVersion)传入,二者等价;
  • extra="forbid":传入未声明的字段会直接触发 Pydantic 校验错误,这能尽早发现字段拼写错误,但也意味着客户端模型比集群旧、而返回了新增字段时(或集群比客户端新)会抛校验异常——examples/rollout-statefulset.py 头部的注释正是这个原因:

If your kubernetes version is lower than 1.22 (exclude 1.22), the kubernetes-client version must be lower than 1.22 ... Because new feature 'AvailableReplicas' for StatefulSetStatus is supported in native kubernetes since version 1.22, mismatch version between kubernetes and kubernetes-client will raise exception ValueError.

即模型与集群版本不匹配时,V1StatefulSetStatus.available_replicas这类字段可能引起异常,选型时需注意客户端版本与集群 API 版本的兼容。

3. V1StatefulSetSpec:规约字段逐项解析

spec子模型定义在 v1_stateful_set_spec.py。字段及 docstring 语义如下:

Python 字段线上字段类型说明
replicasreplicasOptional[int]期望副本数;不指定时默认为 1
selectorselectorV1LabelSelector必填。Pod 选择器,决定该 StatefulSet 管理哪些 Pod
service_nameserviceNameOptional[str]治理该 StatefulSet 的 Service 名称,必须在 StatefulSet 之前创建,负责网络身份;Pod 的 DNS 形如pod-specific-string.serviceName.default.svc.cluster.local
templatetemplateV1PodTemplateSpec必填。Pod 模板
volume_claim_templatesvolumeClaimTemplatesOptional[List[V1PersistentVolumeClaim]]模板化 PVC 列表;列表中每个 claim 必须在 template 的某个容器里有同名volumeMount;同名 claim 优先于 template 中的 volume
pod_management_policypodManagementPolicyOptional[str]OrderedReady(默认):按 pod-0、pod-1… 顺序创建并等待就绪,缩容时反向删除;Parallel:并行创建、缩容时一次性删除全部
update_strategyupdateStrategyOptional[V1StatefulSetUpdateStrategy]更新策略,默认RollingUpdate
revision_history_limitrevisionHistoryLimitOptional[int]保留的 ControllerRevision 历史数量,默认 10
min_ready_secondsminReadySecondsOptional[int]新 Pod 创建后需连续 Ready 且无容器崩溃的最短秒数,默认 0
ordinalsordinalsOptional[V1StatefulSetOrdinals]副本序号起点,见 3.1
persistent_volume_claim_retention_policypersistentVolumeClaimRetentionPolicyOptional[V1StatefulSetPersistentVolumeClaimRetentionPolicy]PVC 保留策略,见 3.2

3.1 ordinals:副本序号起点

v1_stateful_set_ordinals.py 中只有一个字段start:

start is the number representing the first replica's index. It may be used to number replicas from an alternate index (eg: 1-indexed) over the default 0-indexed names, or to orchestrate progressive movement of replicas from one StatefulSet to another. If set, replica indices will be in the range[.spec.ordinals.start, .spec.ordinals.start + .spec.replicas). If unset, defaults to 0.

即默认 Pod 编号从0开始(pod-0…pod-N-1);设置ordinals.start后可从其他索引编号,典型场景是把副本从一个 StatefulSet 渐进迁移到另一个。

3.2 PVC 保留策略

v1_stateful_set_persistent_volume_claim_retention_policy.py 提供两个正交维度:

  • when_deleted(线上字段whenDeleted):StatefulSet 被删除时对volumeClaimTemplates生成的 PVC 的处理。默认Retain(PVC 不受影响),设为Delete则一并删除;
  • when_scaled(线上字段whenScaled):StatefulSet缩容时的处理。默认Retain,设为Delete则删除超出目标副本数的 Pod 对应的 PVC。

3.3 updateStrategy:更新策略与 maxUnavailable

v1_stateful_set_update_strategy.py 中的type字段说明:

Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate.

RollingUpdate具体参数在 v1_rolling_update_stateful_set_strategy.py 中,核心是max_unavailable(线上字段maxUnavailable):

The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). ... This can not be 0. Defaults to 1.

支持绝对数或百分比两种写法,不能为 0,默认 1;docstring 同时提示该设置对OrderedReady策略可能不完全生效(因为 OrderedReady 本身就要求严格顺序)。

4. V1StatefulSetStatus:状态字段与 Condition

状态子模型定义在 v1_stateful_set_status.py:

Python 字段线上字段类型说明
replicasreplicasint必填。StatefulSet 控制器创建的 Pod 总数
ready_replicasreadyReplicasOptional[int]处于 Ready 条件的 Pod 数
current_replicascurrentReplicasOptional[int]由currentRevision版本创建的 Pod 数
updated_replicasupdatedReplicasOptional[int]由updateRevision版本创建的 Pod 数
available_replicasavailableReplicasOptional[int]可用 Pod 数(Ready 至少 minReadySeconds);Kubernetes 1.22+ 引入
current_revisioncurrentRevisionOptional[str]生成序列[0, currentReplicas)内 Pod 的 StatefulSet 版本
update_revisionupdateRevisionOptional[str]生成序列[replicas-updatedReplicas, replicas)内 Pod 的版本
observed_generationobservedGenerationOptional[int]控制器观测到的最新 generation(API Server 在变更时更新)
collision_countcollisionCountOptional[int]控制器创建新 ControllerRevision 名称时的哈希碰撞计数
conditionsconditionsOptional[List[V1StatefulSetCondition]]最新状态观测条件列表

V1StatefulSetCondition(v1_stateful_set_condition.py)包含四个字段:

  • type:条件类型(如Ready);
  • status:True/False/Unknown;
  • last_transition_time(线上lastTransitionTime):条件最近一次状态跳变的时间(datetime类型);
  • reason/message:跳变原因与补充信息。

在脚本中判断就绪与否,通常就是轮询status.conditions里type == "Ready"且status == "True"的条目,或比较ready_replicas与replicas。

5. 序列化机制:to_dict / to_json / from_dict

这一部分是 aio 客户端模型相对老版同步客户端的关键变化:所有模型改为 PydanticBaseModel,并在模块级提供了一组兼容工具函数(见 v1_stateful_set.py)。

5.1 from_dict / from_json:反序列化

v1_stateful_set.py 中:

@classmethod def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of V1StatefulSet from a dict""" if obj is None: return None if not isinstance(obj, dict): return cls.model_validate(obj) obj = _cast(Dict[str, Any], cls.__preprocess_input_names(obj, remove_hidden_storage_names=True)) _obj = cls.model_validate({ "apiVersion": obj.get("apiVersion"), "kind": obj.get("kind"), "metadata": V1ObjectMeta.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None, "spec": V1StatefulSetSpec.from_dict(obj["spec"]) if obj.get("spec") is not None else None, "status": V1StatefulSetStatus.from_dict(obj["status"]) if obj.get("status") is not None else None }) return _obj

三个要点:

  1. 递归构造:metadata、spec、status分别交给对应子模型的from_dict,形成整棵资源树的对象图;
  2. spec的“必填”是软约束:from_dict中obj.get("spec") is not None else None会把缺失的 spec 映射为None,真正的必填性由 Pydantic 在model_validate时把关;
  3. __preprocess_input_names:把蛇形键名归一到驼峰键名(例如输入里写api_version会自动搬到apiVersion),保证两种写法都能通过校验。

from_json(cls, json_str)则等价于cls.from_dict(json.loads(json_str))。

5.2 to_dict / to_json:序列化与别名

def to_dict(self, serialize: bool = False) -> Dict[str, Any]: """Return all declared model fields using public or wire names.""" return { ("apiVersion" if serialize else "api_version"): _to_legacy_value(getattr(self, "api_version", None), serialize), ("kind" if serialize else "kind"): _to_legacy_value(getattr(self, "kind", None), serialize), ("metadata" if serialize else "metadata"): _to_legacy_value(getattr(self, "metadata", None), serialize), ("spec" if serialize else "spec"): _to_legacy_value(getattr(self, "spec", None), serialize), ("status" if serialize else "status"): _to_legacy_value(getattr(self, "status", None), serialize), }
  • serialize=False(默认):返回 Python 属性名(api_version),且嵌套值原样带出;
  • serialize=True:键名转换为线上 wire 名(apiVersion),并递归调用嵌套模型的to_dict(serialize=True)(经由_to_legacy_value),这是发往 API Server 的 payload 形态。

to_json则走另一条“现代投影”路径(v1_stateful_set.py):

def to_json(self) -> str: to_openapi_to_dict = _get_openapi_to_dict(self) if to_openapi_to_dict is not None: return json.dumps(to_jsonable_python(to_openapi_to_dict(self))) return json.dumps(to_jsonable_python(self.to_dict()))

其内部__openapi_generator_modern_projection(通过setattr与to_dict互相引用,避免占住模型成员名)基于self.model_dump(by_alias=True, exclude_none=True),并显式对metadata、spec、status调用子模型的转换,保证输出为驼峰键、剔除None字段、可直接json.loads往返。模块里那对“互相验证函数引用”的_get_openapi_to_dict(v1_stateful_set.py)用于确认拿到的是生成代码自身的to_dict,防止子类覆写后误伤,从源码结构看这是为保证“继承的生成方法”与“投影方法”配对一致而设的防护。

to_str()返回pprint.pformat(self.to_dict()),__repr__直接复用,因此print(sts)会输出格式化字典,便于调试。

5.3 相等性比较

__eq__定义为仅当对方也是同类型且to_dict()相等时成立(v1_stateful_set.py),跨类型比较一律为False。写断言或去重逻辑时可以放心用==。

6. 在 aio 异步客户端中使用 V1StatefulSet

kubernetes.aio与同步客户端kubernetes的模型、API 结构一一对应,但调用是async/await的。异步示例可参照 examples_asyncio/list_pods.py 的骨架:

import asyncio from kubernetes.aio import client, config from kubernetes.aio.client.api_client import ApiClient async def main(): await config.load_kube_config() # 上下文管理器会自动关闭 http session async with ApiClient() as api: apps_v1 = client.AppsV1Api(api) core_v1 = client.CoreV1Api(api) # 1. 先创建 headless Service(spec.service_name 要求先存在) svc = client.V1Service( api_version="v1", kind="Service", metadata=client.V1ObjectMeta(name="redis-test-svc"), spec=client.V1ServiceSpec( selector={"app": "redis"}, cluster_ip="None", # headless type="ClusterIP", ports=[client.V1ServicePort(port=6379, target_port=6379)] )) await core_v1.create_namespaced_service(namespace="default", body=svc) # 2. 构造 V1StatefulSet(aio 模型,字段与同步版一致) template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels={"app": "redis"}), spec=client.V1PodSpec(containers=[client.V1Container( name="sts-redis", image="redis", image_pull_policy="IfNotPresent", ports=[client.V1ContainerPort(container_port=6379)])])) sts = client.V1StatefulSet( api_version="apps/v1", kind="StatefulSet", metadata=client.V1ObjectMeta(name="statefulset-redis"), spec=client.V1StatefulSetSpec( replicas=3, service_name="redis-test-svc", selector=client.V1LabelSelector(match_labels={"app": "redis"}), template=template, pod_management_policy="OrderedReady", revision_history_limit=10)) created = await apps_v1.create_namespaced_stateful_set(namespace="default", body=sts) print(created.to_str()) # 3. 更新镜像并 patch(等价于触发滚动更新) live = await apps_v1.read_namespaced_stateful_set("statefulset-redis", "default") live.spec.template.spec.containers[0].image = "redis:6.2" await apps_v1.patch_namespaced_stateful_set( name="statefulset-redis", namespace="default", body=live) # 4. 回滚:读取指定 ControllerRevision,将其 data patch 回去 revs = await apps_v1.list_namespaced_controller_revision("default") owned = [r for r in revs.items if r.metadata.owner_references and r.metadata.owner_references[0].kind == "StatefulSet" and r.metadata.owner_references[0].name == "statefulset-redis"] target = sorted(owned, key=lambda r: r.revision)[0] cr = await apps_v1.read_namespaced_controller_revision(target.metadata.name, "default") await apps_v1.patch_namespaced_stateful_set( name="statefulset-redis", namespace="default", body=cr.data) if __name__ == "__main__": asyncio.run(main())

上述流程与同步版示例 examples/rollout-statefulset.py 完全对应:先建 headless Service,再建 StatefulSet,改镜像触发滚动更新,最后通过list_namespaced_controller_revision+owner_references找到目标修订版本并把controller_revision.data作为 patch body 实现回滚。aio 版本的两点差异:

  1. API 实例需要传入ApiClient(如client.AppsV1Api(api)),且所有方法均为协程,需要await;
  2. 建议在async with ApiClient() as api:上下文中运行,退出时自动关闭底层 httpx session,避免连接泄漏。

此外,构造时若用蛇形键名(如{"service_name": ...})传入 dict,__preprocess_input_names会将其归一为驼峰键名,因此from_dict同时兼容两种命名风格;但未知字段会被extra="forbid"拒绝,升级集群后拉取新字段前建议同步升级客户端版本。

7. 小结

  • 参考文档 kubernetes.aio.client.models.v1_stateful_set.rst 是纯automodule页,真实内容即 v1_stateful_set.py 中的 Pydantic 模型定义;
  • V1StatefulSet仅 5 个顶层字段,但通过spec/status两个子模型覆盖了副本数、选择器、Headless Service 绑定、Pod 模板、PVC 模板、更新策略、序号起点、保留策略与完整状态观测;
  • 模型统一采用“Python 蛇形名 + 线上驼峰 alias”的双向映射,validate_by_name/alias双验证、extra="forbid"严格拒绝未知字段;
  • to_dict(serialize=...)、to_json、from_dict分别覆盖本地调试、发往 API Server 的 payload 构造与响应反序列化三条路径;
  • 在kubernetes.aio中使用时,V1StatefulSet与同步版字段一致,差异仅在 API 调用改为await且需注入ApiClient,可参考 examples_asyncio/list_pods.py 的异步骨架与 examples/rollout-statefulset.py 的 StatefulSet 生命周期操作(含基于 ControllerRevision 的回滚)。
  • 后端
  • 云原生
  • 容器编排

【免费下载链接】python

Official Python client library for kubernetes

项目地址:https://gitcode.com/gh_mirrors/python1/python
点击查看免费下载

相关推荐

上一篇:终极指南:如何用StreamFX打造专业级OBS直播特效
下一篇:StreamFX完整指南:零门槛打造专业级直播特效的终极教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询