- 后端
- 云原生
- 容器编排
【免费下载链接】python
Official Python client library for kubernetes
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_version | apiVersion | str | 对象的 API 版本 schema(本资源为v1)。服务端会将可识别的 schema 转换为最新内部值,遇到无法识别的值可能拒绝请求 |
kind | kind | str | REST 资源类型字符串,CamelCase,不可更新;服务端可依据提交请求的端点推断它 |
metadata | metadata | V1ObjectMeta | 对象元数据(名称、命名空间、labels、annotations、resourceVersion 等) |
subsets | subsets | List[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 地址,字段如下:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
hostname | str | 否 | 该端点的主机名 |
ip | str | 是 | 端点的 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_name | str | 否 | 承载该端点的节点,可用于判断端点是否位于本节点(局部性调度),别名nodeName |
target_ref | V1ObjectReference | 否 | 指向该端点背后的对象(如 Pod),别名targetRef |
注意ip是唯一带校验约束的强必填字段,构造对象时若缺失或使用非法地址范围会被 pydantic 拒绝。
3.3 CoreV1EndpointPort —— 单个端口的元组描述
CoreV1EndpointPort 描述单个端口:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
app_protocol | str | 否 | 应用层协议提示,遵循 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 |
name | str | 否 | 端口名,必须与对应ServicePort.name一致,且必须是 DNS_LABEL;仅当只有一个端口时可省略 |
port | int | 是 | 端点端口号 |
protocol | str | 否 | 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
相关推荐
深入解析 Kubernetes Python 异步客户端 V1ReplicaSet 模型:字段、序列化与 API 实战
深入解析 Kubernetes Python 异步客户端 V1ReplicaSet 模型:字段、序列化与 API 实战 本篇技术指南聚焦于 Kubernetes
后端云原生容器编排python-kubernetes aio 客户端中 V1StatefulSet 模型详解:字段、序列化与异步用法
python kubernetes aio 客户端中 V1StatefulSet 模型详解:字段、序列化与异步用法 V1StatefulSet 是 kubern
后端云原生容器编排Kubernetes Python 异步客户端 V1PodTemplateList 模型深度解析:字段结构、序列化与 PodTemplate 列表查询实战
Kubernetes Python 异步客户端 V1PodTemplateList 模型深度解析:字段结构、序列化与 PodTemplate 列表查询实战 本文
后端云原生容器编排
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考