- 后端
- 云原生
- 容器编排
【免费下载链接】python
Official Python client library for kubernetes
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_version | apiVersion | Optional[StrictStr] | 否 | 对象表示的版本化 schema,如"apps/v1" |
kind | kind | Optional[StrictStr] | 否 | REST 资源类型,如"StatefulSet" |
metadata | metadata | Optional[V1ObjectMeta] | 否 | 标准元数据(name、namespace、labels 等) |
spec | spec | V1StatefulSetSpec | 是 | StatefulSet 规约,唯一不可省略的字段 |
status | status | Optional[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 字段 | 线上字段 | 类型 | 说明 |
|---|---|---|---|
replicas | replicas | Optional[int] | 期望副本数;不指定时默认为 1 |
selector | selector | V1LabelSelector | 必填。Pod 选择器,决定该 StatefulSet 管理哪些 Pod |
service_name | serviceName | Optional[str] | 治理该 StatefulSet 的 Service 名称,必须在 StatefulSet 之前创建,负责网络身份;Pod 的 DNS 形如pod-specific-string.serviceName.default.svc.cluster.local |
template | template | V1PodTemplateSpec | 必填。Pod 模板 |
volume_claim_templates | volumeClaimTemplates | Optional[List[V1PersistentVolumeClaim]] | 模板化 PVC 列表;列表中每个 claim 必须在 template 的某个容器里有同名volumeMount;同名 claim 优先于 template 中的 volume |
pod_management_policy | podManagementPolicy | Optional[str] | OrderedReady(默认):按 pod-0、pod-1… 顺序创建并等待就绪,缩容时反向删除;Parallel:并行创建、缩容时一次性删除全部 |
update_strategy | updateStrategy | Optional[V1StatefulSetUpdateStrategy] | 更新策略,默认RollingUpdate |
revision_history_limit | revisionHistoryLimit | Optional[int] | 保留的 ControllerRevision 历史数量,默认 10 |
min_ready_seconds | minReadySeconds | Optional[int] | 新 Pod 创建后需连续 Ready 且无容器崩溃的最短秒数,默认 0 |
ordinals | ordinals | Optional[V1StatefulSetOrdinals] | 副本序号起点,见 3.1 |
persistent_volume_claim_retention_policy | persistentVolumeClaimRetentionPolicy | Optional[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 字段 | 线上字段 | 类型 | 说明 |
|---|---|---|---|
replicas | replicas | int | 必填。StatefulSet 控制器创建的 Pod 总数 |
ready_replicas | readyReplicas | Optional[int] | 处于 Ready 条件的 Pod 数 |
current_replicas | currentReplicas | Optional[int] | 由currentRevision版本创建的 Pod 数 |
updated_replicas | updatedReplicas | Optional[int] | 由updateRevision版本创建的 Pod 数 |
available_replicas | availableReplicas | Optional[int] | 可用 Pod 数(Ready 至少 minReadySeconds);Kubernetes 1.22+ 引入 |
current_revision | currentRevision | Optional[str] | 生成序列[0, currentReplicas)内 Pod 的 StatefulSet 版本 |
update_revision | updateRevision | Optional[str] | 生成序列[replicas-updatedReplicas, replicas)内 Pod 的版本 |
observed_generation | observedGeneration | Optional[int] | 控制器观测到的最新 generation(API Server 在变更时更新) |
collision_count | collisionCount | Optional[int] | 控制器创建新 ControllerRevision 名称时的哈希碰撞计数 |
conditions | conditions | Optional[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三个要点:
- 递归构造:
metadata、spec、status分别交给对应子模型的from_dict,形成整棵资源树的对象图; spec的“必填”是软约束:from_dict中obj.get("spec") is not None else None会把缺失的 spec 映射为None,真正的必填性由 Pydantic 在model_validate时把关;__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 版本的两点差异:
- API 实例需要传入
ApiClient(如client.AppsV1Api(api)),且所有方法均为协程,需要await; - 建议在
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
相关推荐
Kubernetes Python 客户端 V1APIServiceList 模型详解:APIService 列表对象的字段、序列化与异步用法
Kubernetes Python 客户端 V1APIServiceList 模型详解:APIService 列表对象的字段、序列化与异步用法 V1APISer
后端云原生容器编排Kubernetes Python 客户端 V1DaemonSetCondition 模型详解:DaemonSet 状态条件的类型、字段与序列化用法
Kubernetes Python 客户端 V1DaemonSetCondition 模型详解:DaemonSet 状态条件的类型、字段与序列化用法 导读 V1
后端云原生容器编排Kubernetes Python 异步客户端 V1Deployment 模型全解析:从字段语义到序列化与实战
Kubernetes Python 异步客户端 V1Deployment 模型全解析:从字段语义到序列化与实战 导读 V1Deployment 是 Kubern
后端云原生容器编排
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考