☰
深入解析 Kubernetes Python 客户端 aio 异步模型 V1Endpoints:结构、弃用替代与实战序列化
2026/10/10 1:53:24 网站建设 项目流程
  • 后端
  • 云原生
  • 容器编排

【免费下载链接】python

Official Python client library for kubernetes

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

V1Endpoints是 Kubernetes Python 官方客户端(kubernetes)中core/v1组下的Endpoints 资源异步模型类,位于kubernetes.aio异步包中,用于以类型安全的方式表达一个 Service 背后的实际 Pod 地址集合。本文以 doc/source/kubernetes.aio.client.models.v1_endpoints.rst 文档为骨架,结合 模型源码 与CoreV1Api的读写方法,完整讲解该模型的字段语义、四层嵌套结构(Endpoints → EndpointSubset → EndpointAddress / EndpointPort)、JSON 序列化细节,以及它自 v1.33 起被discovery.k8s.io/v1的 EndpointSlice 取代的迁移背景,并给出可运行的异步 CRUD 示例。

一、文档定位与模型概况

doc/source/kubernetes.aio.client.models.v1_endpoints.rst是 Sphinx 自动生成的 API 参考页,通过automodule指令(.. automodule:: kubernetes.aio.client.models.v1_endpoints,含:members:、:show-inheritance:、:undoc-members:)把整个模块的公开成员与 docstring 渲染成文档。因此该页面的"内容主体"即V1Endpoints类及其继承自 pydanticBaseModel的全部能力。

从源码头部可以看到,该模块由OpenAPI Generator根据 Kubernetes OpenAPI 规范(release-1.37)自动生成,并显式标注"Do not edit the class manually"。这意味着其字段集合、类型与 docstring 直接对应 Kubernetes API 服务端契约,是客户端与 API Server 之间的强类型映射。

在异步包中,V1Endpoints通过 kubernetes/aio/client/init.py 导出(同时导出的还有V1EndpointsList),因此日常使用可以直接写from kubernetes.aio.client import V1Endpoints,也可以像生成代码示例那样按模块路径导入from kubernetes.aio.client.models.v1_endpoints import V1Endpoints。同步包 kubernetes/client/models/v1_endpoints.py 中同样存在该模型,二者结构一致、命名空间不同。

二、核心类 V1Endpoints 的字段语义

源码中类 docstring 给出了权威定义:

Endpoints is a collection of endpoints that implement the actual service. ... Endpoints is a legacy API and does not contain information about all Service features. Use discoveryv1.EndpointSlice for complete information about Service endpoints. Deprecated: This API is deprecated in v1.33+.

也就是说,V1Endpoints承载的是一个命名空间内、与某 Service 同名的端点集合对象。模型一共只有 4 个字段,全部可选(Optional):

字段(Python)序列化别名(wire 名)类型语义
api_versionapiVersionstr对象的 API 版本 schema(本资源为v1)。服务端会将可识别的 schema 转换为最新内部值,遇到无法识别的值可能拒绝请求
kindkindstrREST 资源类型字符串,CamelCase,不可更新;服务端可依据提交请求的端点推断它
metadatametadataV1ObjectMeta对象元数据(名称、命名空间、labels、annotations、resourceVersion 等)
subsetssubsetsList[V1EndpointSubset]构成该 Service 的地址与端口分组集合,见下文

关于openapi_types与attribute_map

源码中保留了两个类变量:openapi_types声明每个属性对应的类型("api_version": "str"、"metadata": "V1ObjectMeta"、"subsets": "List[V1EndpointSubset]"),attribute_map声明 Python 属性名与 JSON wire 名称的映射(如api_version → apiVersion)。这两个映射配合 pydantic 的AliasChoices校验别名,实现了"Python 侧可用蛇形命名、序列化时自动切换为 camelCase"的双向兼容。

值得注意的 pydantic 配置(model_config = ConfigDict(...)):

  • validate_by_name=True与validate_by_alias=True:按字段名和别名双重校验;
  • validate_assignment=True:对象创建后再赋属性值也会被校验;
  • extra="forbid":拒绝未声明的多余字段,这是"字段契约严格"的保证;
  • protected_namespaces=():避免字段名与 pydantic 内部命名空间冲突。

三、四层嵌套结构:从 Endpoints 到地址与端口

V1Endpoints的实质内容在subsets,其嵌套关系为:

V1Endpoints └── subsets: List[V1EndpointSubset] ├── addresses: List[V1EndpointAddress] ├── not_ready_addresses: List[V1EndpointAddress] └── ports: List[CoreV1EndpointPort]

3.1 V1EndpointSubset —— 共享同一组端口的一批地址

源码 v1_endpoint_subset.py 的 docstring 用笛卡尔积精确定义了子集语义:

EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports.

例如给定Addresses = [10.10.1.1, 10.10.2.2]、Ports = [a:8675, b:309],则展开后的端点集合等价于a: [10.10.1.1:8675, 10.10.2.2:8675]与b: [10.10.1.1:309, 10.10.2.2:309]。

该类的三个字段:

  • addresses: List[V1EndpointAddress]—— 提供相关端口且标记为 ready的 IP 地址,负载均衡器与客户端可以放心使用;
  • not_ready_addresses: List[V1EndpointAddress]—— 提供相关端口但尚未 ready的地址(正在启动、最近未通过就绪/存活探针等),序列化别名为notReadyAddresses;
  • ports: List[CoreV1EndpointPort]—— 相关地址上可用的端口号列表。

V1Endpointsdocstring 补充了一条重要约束:"No address will appear in both Addresses and NotReadyAddresses in the same subset",即同一子集内地址不会同时在 ready 与 not-ready 两组中出现;而一个地址若因来自不同容器而同时具备 ready 与 not-ready 的端口,则会被拆到不同子集中展示——这也是"Addresses are placed into subsets according to the IPs they share"的落点。

3.2 V1EndpointAddress —— 单个 IP 的元组描述

V1EndpointAddress 描述一个独立 IP 地址,字段如下:

字段类型必填说明
hostnamestr否该端点的主机名
ipstr是端点的 IP。不允许 loopback(127.0.0.0/8、::1)、link-local(169.254.0.0/16、fe80::/10)以及 link-local 组播(224.0.0.0/24、ff02::/16)
node_namestr否承载该端点的节点,可用于判断端点是否位于本节点(局部性调度),别名nodeName
target_refV1ObjectReference否指向该端点背后的对象(如 Pod),别名targetRef

注意ip是唯一带校验约束的强必填字段,构造对象时若缺失或使用非法地址范围会被 pydantic 拒绝。

3.3 CoreV1EndpointPort —— 单个端口的元组描述

CoreV1EndpointPort 描述单个端口:

字段类型必填说明
app_protocolstr否应用层协议提示,遵循 Kubernetes label 语法:无前缀协议名保留给 IANA 标准服务名(RFC-6335);Kubernetes 预定义前缀名包括kubernetes.io/h2c(明文 HTTP/2 先验知识)、kubernetes.io/ws(明文 WebSocket)、kubernetes.io/wss(TLS WebSocket);其他协议使用实现自定义前缀如mycompany.com/my-custom-protocol。别名appProtocol
namestr否端口名,必须与对应ServicePort.name一致,且必须是 DNS_LABEL;仅当只有一个端口时可省略
portint是端点端口号
protocolstr否IP 层协议,必须为UDP、TCP或SCTP,默认TCP

四、序列化与反序列化:pydantic + OpenAPI 双轨机制

该模型类除了继承 pydanticBaseModel外,还实现了一组 OpenAPI Generator 标准的辅助方法,源码中可见完整实现:

  • to_dict(serialize=False):返回所有声明字段,serialize=False时用 Python 蛇形键(api_version、not_ready_addresses、app_protocol),serialize=True时用 wire 名(apiVersion、notReadyAddresses、appProtocol)。这是发送给 API Server 前的标准路径。
  • to_json():返回使用**别名(alias)**的 JSON 字符串,内部经由to_jsonable_python处理 pydantic 对象。
  • from_json(json_str)/from_dict(obj):反向构造实例。from_dict内部先调用__preprocess_input_names把api_version之类蛇形键规整为apiVersion,再对metadata递归调用V1ObjectMeta.from_dict、对subsets逐项调用V1EndpointSubset.from_dict,形成完整的嵌套反序列化链。
  • __eq__/__ne__:基于to_dict()结果比较对象相等性。
  • to_str()/__repr__:用pprint.pformat输出可读表示。

此外,源码还通过setattr在to_dict与__openapi_generator_modern_projection之间建立互逆引用(_OPENAPI_GENERATOR_TO_DICT = "_openapi_generator_to_dict"),以保证子类继承的生成方法不丢失,并配合_to_openapi_value、_to_legacy_value实现旧式 dict 与现代 pydantic 模型之间的递归转换。对普通用户而言,只需要记住:构造用字段名(蛇形或 camelCase 均可),发送用to_dict(serialize=True)或直接传模型对象,接收用from_dict/from_json。

一个完整的构造示例(对应模块 docstring 中"mysvc"的例子):

from kubernetes.aio.client import ( V1Endpoints, V1EndpointSubset, V1EndpointAddress, CoreV1EndpointPort, ) subsets = [ V1EndpointSubset( addresses=[ V1EndpointAddress(ip="10.10.1.1"), V1EndpointAddress(ip="10.10.2.2"), ], ports=[ CoreV1EndpointPort(name="a", port=8675), CoreV1EndpointPort(name="b", port=309), ], ), V1EndpointSubset( addresses=[V1EndpointAddress(ip="10.10.3.3")], ports=[ CoreV1EndpointPort(name="a", port=93), CoreV1EndpointPort(name="b", port=76), ], ), ] ep = V1Endpoints( api_version="v1", kind="Endpoints", metadata=..., # V1ObjectMeta,需设置 name="mysvc" 与 namespace subsets=subsets, ) print(ep.to_json()) # 输出带 camelCase 别名的 JSON ep2 = V1Endpoints.from_json(ep.to_json()) # 往返无损 assert ep == ep2

五、在 CoreV1Api 中读写 Endpoints 的异步方法

V1Endpoints模型的真正应用场景是配合kubernetes.aio.client.api.core_v1_api.CoreV1Api使用。core_v1_api.py 中为该资源提供了完整的 CRUD + 列表 + watch 方法,每个方法都有_with_http_info(返回ApiResponse[V1Endpoints])与_without_preload_content(返回原始RESTResponseType)变体:

方法HTTP 语义请求体 / 返回类型
create_namespaced_endpoints(namespace, body, ...)POST 创建body:V1Endpoints→V1Endpoints
read_namespaced_endpoints(name, namespace, ...)GET 读取→V1Endpoints
replace_namespaced_endpoints(name, namespace, body, ...)PUT 整体替换body:V1Endpoints→V1Endpoints
patch_namespaced_endpoints(name, namespace, body, ...)PATCH 局部更新body:Dict/List[Dict]/BaseModel→V1Endpoints
delete_namespaced_endpoints(name, namespace, ...)DELETE 删除→object
list_namespaced_endpoints(namespace, ...)GET 列表→V1EndpointsList
list_endpoints_for_all_namespaces(...)GET 全命名空间列表→V1EndpointsList

这些方法统一支持若干可选参数,理解它们有助于写出生产级代码:

  • pretty:"true"时输出美化打印,默认"false"(除非 User-Agent 表明是浏览器或 curl/wget 等命令行工具);
  • dry_run:值为All时执行所有 dry-run 阶段但不持久化;
  • field_manager:变更的 actor 标识,要求少于 128 字符且仅含可打印字符,apply 请求必填;
  • field_validation:Ignore(v1.23 前默认,静默丢弃未知字段)/Warn(v1.23+ 默认,逐字段返回 warning 头)/Strict(遇到未知字段直接失败);
  • force:仅用于 apply 请求(application/apply-patch),强制重新获取被他人占有的冲突字段;
  • 列表方法还支持label_selector、field_selector、limit+_continue分页、resource_version/resource_version_match一致性读取、watch、allow_watch_bookmarks、send_initial_events(与resourceVersionMatch搭配,先发合成事件同步当前状态再进入流式监听)、timeout_seconds等。

删除方法另有grace_period_seconds(0 表示立即删除,nil 表示使用资源默认宽限期)、propagation_policy(Orphan/Background/Foreground,与orphan_dependents二选一,后者已在 1.7 起标记弃用)等参数。

一个完整的异步 CRUD 示例(基于 examples_asyncio 目录中的异步用法模式):

import asyncio from kubernetes import config from kubernetes.aio.client import ApiClient, CoreV1Api, V1Endpoints async def main(): await config.load_kube_config() # 或使用 in_cluster_config() async with ApiClient() as api: v1 = CoreV1Api(api) ep = V1Endpoints( api_version="v1", kind="Endpoints", subsets=[...], # 见上一节的构造方式 ) # 创建 created = await v1.create_namespaced_endpoints( namespace="default", body=ep, pretty="true", ) # 读取 got = await v1.read_namespaced_endpoints( name=created.metadata.name, namespace="default", ) # 局部 patch(JSON Patch 形式) patched = await v1.patch_namespaced_endpoints( name=got.metadata.name, namespace="default", body=[{"op": "add", "path": "/subsets/-", "value": {"addresses": [{"ip": "10.10.4.4"}], "ports": [{"name": "c", "port": 8080}]}}], ) # 删除 await v1.delete_namespaced_endpoints( name=got.metadata.name, namespace="default", ) asyncio.run(main())

注意:本仓库的 aio 包依赖pydantic(见 requirements-asyncio.txt),异步客户端还依赖aiohttp,安装与用法可参考 kubernetes/aio/README.md 以及 kubernetes/aio/docs/V1Endpoints.md。

六、弃用背景:从 Endpoints 迁移到 EndpointSlice

模型 docstring 明确声明"Deprecated: This API is deprecated in v1.33+. Use discoveryv1.EndpointSlice",同时解释了原因:Endpoints 是 legacy API,并不包含 Service 的全部特性信息,要获取完整的 Service 端点信息应使用discoveryv1.EndpointSlice。V1EndpointSubset、V1EndpointAddress、CoreV1EndpointPort的 docstring 也都标注了同样的弃用提示(Deprecated: This API is deprecated in v1.33+)。

这意味着:

  • 在 Kubernetes v1.33+ 集群上,新功能(如 Topology、Endpoint 上的 per-endpoint 条件、appProtocol 扩展等)不会完整地回填到 Endpoints 对象中;
  • 长期维护的客户端代码应规划迁移到DiscoveryV1Api+V1EndpointSlice(仓库中同样生成了 V1EndpointSlice 模型 与对应的discovery_v1_api.py);
  • 但 Endpoints 对象仍由 API Server 自动维护、与同名 Service 一一对应,存量系统在不依赖新特性的前提下依旧可以继续读取。

在写新代码时建议:查询端点信息优先使用 EndpointSlice(信息更全),对存量 Endpoints 的读写则继续使用本文介绍的V1Endpoints模型。

七、小结

V1Endpoints是kubernetes.aio异步包中表达 Service 端点集合的强类型模型:

  • 四字段结构(api_version、kind、metadata、subsets),全部可选、extra="forbid"严格校验;
  • 嵌套层次清晰:subsets → addresses / not_ready_addresses / ports,地址与端口做笛卡尔积展开;
  • 提供 pydantic 与 OpenAPI 双轨序列化:to_dict(serialize=True/False)、to_json、from_json、from_dict均可在模型与 wire JSON 之间无损往返;
  • 由CoreV1Api的create/read/replace/patch/delete/list系列异步方法驱动,支持pretty、dry_run、field_manager、field_validation、watch 与分页等标准参数;
  • 自 v1.33 起标记弃用,新项目应转向discoveryv1.EndpointSlice,存量代码可继续安全使用。

如需继续深入,可阅读 模型源码、嵌套模型 V1EndpointSubset、异步 API 参考 与 doc/html/kubernetes.aio.client.models.v1_endpoints.html 渲染出的完整 API 文档。

  • 后端
  • 云原生
  • 容器编排

【免费下载链接】python

Official Python client library for kubernetes

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

相关推荐

上一篇:go-echarts 生态集成指南:templ、GoNB 与 insyra 的实战落地
下一篇:终极指南:5步快速部署LangChain .NET智能对话框架

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

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

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

立即咨询