{"id":16476503,"url":"https://github.com/poneding/multi-version-api-sample","last_synced_at":"2026-05-15T02:04:22.299Z","repository":{"id":187884785,"uuid":"674301948","full_name":"poneding/multi-version-api-sample","owner":"poneding","description":"Kubernetes 多版本 API 示例。","archived":false,"fork":false,"pushed_at":"2023-08-12T14:17:57.000Z","size":42,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-11T05:47:15.085Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/poneding.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-03T15:54:51.000Z","updated_at":"2023-08-03T15:55:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"26d574a0-22d6-4225-932f-d3ea173104f8","html_url":"https://github.com/poneding/multi-version-api-sample","commit_stats":null,"previous_names":["poneding/multi-version-api-sample"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/poneding%2Fmulti-version-api-sample","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/poneding%2Fmulti-version-api-sample/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/poneding%2Fmulti-version-api-sample/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/poneding%2Fmulti-version-api-sample/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/poneding","download_url":"https://codeload.github.com/poneding/multi-version-api-sample/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241144812,"owners_count":19917357,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T12:42:48.533Z","updated_at":"2026-05-15T02:04:19.763Z","avatar_url":"https://github.com/poneding.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# multi-version-api-sample\n\n多版本 API 编程示例。\n\n示例说明：\n\n一开始，我们创建了 v1 版本的 User API 资源，Spec 里面包含两个字段：FullName 和 Age。\n\n后来根据新的需求，我们需要将 FullName 字段拆分成 FirstName 和 LastName 字段，这时候我们就需要创建 v2 版本的 User API 资源，Spec 里面包含三个字段：FirstName、LastName 和 Age。\n\n我们升级了 API 之后，之前的使用 FullName 创建 User 的方式我们仍然需要支持，做到 API 的向下兼容。\n\n## 背景\n\nAPI 不断的迭代，会出现多个版本的 API，需要集群同时支持多个版本的 API 以向下兼容。\n\n## 开始\n\n### 生成项目\n\n参照脚本 `gen_project.sh` 生成项目。\n\n### 编写不同版本的 API\n\n例如 编写 `sampleapis.poneding.com/v1` 和 `sampleapis.poneding.com/v2` 版本的 `user` API。\n\n存在多版本 API 时，需要使用 `// +kubebuilder:storageversion` 注释指定默认的存储版本。例如在 `v2.User` 的结构体上添加注释 `// +kubebuilder:storageversion`，则 `v2.User` 为默认的存储版本。\n\n### 编写转换函数\n\n1、`v1.User` 结构体添加函数 `ConvertTo` 和 `ConvertFrom`，用于转换到 v2.User 结构体。\n\n2、`v2.User` 结构体添加函数 `Hub`，用于指定内部版本（Hub）的结构体。\n\n### 编写 Webhook\n\n最终 etcd 中存储 `v2.User` 版本的 API 数据，所以需要在存储到 etcd 之前，将 `v1.User` 版本的 API 数据转换为 `v2.User` 版本的 API 数据，这其中可能需要对数据做修改（Mutating）和验证（Validating）准入控制。\n\n1、为 `v2.User` 结构体实现 `webhook.Defaulter` 和 `webhook.Validator` 接口函数，用于设置默认值。\n\n2、为 `v2.User` 添加 `// +kubebuilder:webhook:path=/mutate-sampleapis-poneding-com-v2-user,mutating=true,failurePolicy=fail,groups=sampleapis.poneding.com,resources=users,verbs=create;update,versions=v2,name=muser.dp.io,sideEffects=None,admissionReviewVersions=v1\n` 和 `// +kubebuilder:webhook:verbs=create;update;delete,path=/validate-sampleapis-poneding-com-v2-user,mutating=false,failurePolicy=fail,groups=sampleapis.poneding.com,resources=users,versions=v2,name=vuser.dp.io,sideEffects=None,admissionReviewVersions=v1` 注释，用于生成 Admission Webhook。\n\n### 生成资源清单\n\n```bash\nmake generate\nmake manifest\n```\n\n### Kustomize 资源清单\n\n1、取消 `config/crd/kustomization.yaml` 文件中 `patches/cainjection_in_sampleapis_users.yaml` 和 `patches/webhook_in_sampleapis_users.yaml` 注释；\n\n2、取消 `config/default/kustomization.yaml` 文件中 `../certmanager`、`../webhook`、`manager_webhook_patch.yaml`、`webhookcainjection_patch.yaml` 的注释；\n\n3、取消 `config/default/kustomization.yaml` 文件中 `CERTMANAGER` 段 `replacements` 内容的注释。\n\n### 镜像\n\n1、修改 `Makefile` 中 `IMG` 变量，指定镜像地址，打多架构镜像并推送到镜像仓库中;\n\n2、修改 `Makefile` 中 `PLATFORMS` 变量，只保留最常见的架构：`linux/amd64`、`linux/arm64`。\n\n3、编译镜像并推送\n\n```bash\nmake docker-buildx\n```\n\n## 部署和验证\n\n```bash\nmake install deploy\n```\n\u003e `kube-rbac-proxy` 默认会拉取 `gcr.io/kubebuilder/kube-rbac-proxy` 下的镜像，但是国内网络无法拉取，直接去除 `gcr.io` 镜像前缀即可，将会直接拉取 Docker Hub 的镜像。\n\n配置 `config/samples/sampleapis_v1_user.yaml` 和 `config/samples/sampleapis_v2_user.yaml` 文件，分别创建 `v1.User` 和 `v2.User` 资源。\n\n```bash\nkubectl apply -f config/samples/sampleapis_v1_user.yaml\n``` \n\n此时查看资源\n```bash\nkubectl get user.sampleapis.poneding.com user-sample -o yaml\n```\n\n能看到存储的是 `v2.User` 结构的数据。\n\n## 卸载和清理\n\n```bash\nmake undeploy uninstall\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fponeding%2Fmulti-version-api-sample","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fponeding%2Fmulti-version-api-sample","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fponeding%2Fmulti-version-api-sample/lists"}