Aggregated APIServer 构建云原生应用最佳实践
张鹏,腾讯云容器产品工程师,拥有多年云原生项目开发落地经验。目前主要负责腾讯云 TKE 云原生 AI 产品的开发工作。
谢远东,腾讯高级工程师,Kubeflow Member、Fluid(CNCF Sandbox) 核心开发者,负责腾讯云 TKE 在 AI 场景的研发和支持工作。
概述
为什么选择 Aggregated APIServer?
选择独立 API 还是 Aggregated APIServer ?
能利用 Kubernetes 原生的认证、授权、准入等机制,有更高的开发效率; 能更好的和 K8s 系统融合,借助 K8s 生态更快的推广自己的产品,方便用户上手; 借助于 K8s 成熟的 API 工具及规范,构建出的 API 接口更加规范整齐;
考虑 API 聚合的情况 | 优选独立 API 的情况 |
---|---|
你在开发新的 API | 你已经有一个提供 API 服务的程序并且工作良好 |
你希望可以是使用 kubectl 来读写你的新资源类别 | 不要求 kubectl 支持 |
你希望在 Kubernetes UI (如仪表板)中和其他内置类别一起查看你的新资源类别 | 不需要 Kubernetes UI 支持 |
你希望复用 Kubernetes API 支持特性[1] | 你不需要这类特性 |
你有意愿取接受 Kubernetes 对 REST 资源路径所作的格式限制,例如 API 组和名字空间。(参阅 API 概述[2]) | 你需要使用一些特殊的 REST 路径以便与已经定义的 REST API 保持兼容 |
你的 API 是声明式的[3] | 你的 API 不符合声明式[4]模型 |
你的资源可以自然地界定为集群作用域或集群中某个名字空间作用域 | 集群作用域或名字空间作用域这种二分法很不合适;你需要对资源路径的细节进行控制 |
选择 CRDs 还是 Aggregated APIServer?
定制资源的字段不多; 你在组织内部使用该资源或者在一个小规模的开源项目中使用该资源,而不是在商业产品中使用;聚合 API 可提供更多的高级 API 特性,也可对其他特性进行定制;例如,对存储层进行定制、对 protobuf 协议支持、对 logs、patch 等操作支持。
APIServer 扩展的基本原理
AggregatorServer:负责处理 apiregistration.k8s.io
组下的 APIService 资源请求,同时将来自用户的请求拦截转发给 Aggregated APIServer(AA);KubeAPIServer:负责对请求的一些通用处理,包括:认证、鉴权以及各个内建资源(pod, deployment,service)的 REST 服务等; ApiExtensionsServer:负责 CustomResourceDefinition(CRD)apiResources 以及 apiVersions 的注册,同时处理 CRD 以及相应 CustomResource(CR)的REST请求(如果对应 CR 不能被处理的话则会返回404),也是 apiserver Delegation 的最后一环;
如何快速构建 Aggregated APIServer?
安装 apiserver-builder 工具
$ GO111MODULE=on go get sigs.k8s.io/apiserver-builder-alpha/cmd/apiserver-boot
下载[8]最新版本 解压到 /usr/local/apiserver-builder/ 如果此目录不存在,则创建此目录 添加/usr/local/apiserver-builder/bin到您的路径 export PATH=$PATH:/usr/local/apiserver-builder/bin
运行 apiserver-boot -h
初始化项目
$ mkdir skai-demo
$ cd skai-demo
$ apiserver-boot init repo --domain skai.io
.
├── BUILD.bazel
├── Dockerfile
├── Makefile
├── PROJECT
├── WORKSPACE
├── bin
├── cmd
│ ├── apiserver
│ │ └── main.go
│ └── manager
│ └── main.go -> ../../main.go
├── go.mod
├── hack
│ └── boilerplate.go.txt
├── main.go
└── pkg
└── apis
└── doc.go
hack 目录存放自动脚本
cmd/apiserver 是 aggregated server的启动入口
cmd/manager 是 controller 的启动入口
pkg/apis 存放 CR 相关的结构体定义,会在下一步自动生成
生成自定义资源
$ apiserver-boot create group version resource --group animal --version v1alpha1 --kind Cat --non-namespaced=false
Create Resource [y/n]
y
Create Controller [y/n]
n
└── pkg
└── apis
├── animal
│ ├── doc.go
│ └── v1alpha1
│ ├── cat_types.go
│ ├── doc.go
│ └── register.go
└── doc.go
cat_types.go
文件,此文件包含了我们资源的基础定义,我们在 spec 中增加字段定义,并在已经实现的 Validate
方法中完成基础字段的校验。// Cat
// +k8s:openapi-gen=true
type Cat struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec CatSpec `json:"spec,omitempty"`
Status CatStatus `json:"status,omitempty"`
}
// CatSpec defines the desired state of Cat
type CatSpec struct {
Name string `json:"name"`
}
func (in *Cat) Validate(ctx context.Context) field.ErrorList {
allErrs := field.ErrorList{}
if len(in.Spec.Name) == 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "name"), in.Spec.Name, "must be specify"))
}
return allErrs
}
部署运行
创建EKS集群[9]&配置好本地kubeconfig[10];
执行部署命令 ;
$ apiserver-boot run in-cluster --image=xxx/skai.io/skai-demo:0.0.1 --name=skai-demo --namespace=default
自动生成 APIServer Dockerfile 文件; 通过 APIServer Dockerfile 构建服务镜像,并将镜像推送到指定仓库; 在config目录下生成 CA 及其他 APIServer 部署需要的证书文件; 在config目录下生成 APIServer 部署需要的 Deployment、Service、APIService、ServiceAccount 等 yaml 文件; 将上一步生成的 yaml 文件部署到集群中;
功能验证
确认 Resource 注册成功
$ kubectl api-versions |grep animal
animal.skai.io/v1alpha1
确认 Aggregated APIServer 能正常工作
$ kubectl get apiservice v1alpha1.animal.skai.io
NAME SERVICE AVAILABLE AGE
v1alpha1.animal.skai.io default/skai-demo True 19h
创建并查看新增的 Resource
创建
$ cat lucky.yaml
apiVersion: animal.skai.io/v1alpha1
kind: Cat
metadata:
name: mycat
namespace: default
spec:
name: lucky
# 创建自定义 resource
$ kubectl apply -f lucky.yaml
查找
# 查找自定义 resource 列表
$ kubectl get cat
NAME CREATED AT
mycat 2021-11-17T09:08:10Z
# 查找自定义资源详情
$ kubectl get cat mycat -oyaml
apiVersion: animal.skai.io/v1alpha1
kind: Cat
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"animal.skai.io/v1alpha1","kind":"Cat","metadata":{"annotations":{},"name":"mycat"},"spec":{"name":"lucky"}}
creationTimestamp: "2021-11-17T09:08:10Z"
name: mycat
resourceVersion: "17"
uid: 98af0905-f01d-4042-bad3-71b96c0919f4
spec:
name: lucky
status: {}
总结
参考资料
Kubernetes API 支持特性: 【https://kubernetes.io/zh/docs/concepts/extend-kubernetes/api-extension/custom-resources/#common-features】
[2]API 概述: 【https://kubernetes.io/zh/docs/concepts/overview/kubernetes-api/】
[3]声明式API: 【https://kubernetes.io/zh/docs/concepts/extend-kubernetes/api-extension/custom-resources/#declarative-apis】
[4]声明式: 【https://kubernetes.io/zh/docs/concepts/extend-kubernetes/api-extension/custom-resources/#declarative-apis】
[5]官方文档: 【https://kubernetes.io/zh/docs/concepts/extend-kubernetes/api-extension/custom-resources/#compare-ease-of-use】
[6]sample-apiserver: 【https://github.com/kubernetes/sample-apiserver】
[7]apiserver-builder: 【https://github.com/kubernetes-sigs/apiserver-builder-alpha】
[8]下载: 【https://github.com/kubernetes-sigs/apiserver-builder-alpha/releases】
[9]EKS集群: 【https://cloud.tencent.com/document/product/457/39813】
[10]kubeconfig: 【https://cloud.tencent.com/document/product/457/39814】
互动赢好礼
精读文章,回答问题赢好礼
Q1: 扩展API服务器与 kube-apiserver 之间会有网络延迟限制吗?如果有,能容忍的最大延迟是多久?
Q2:基于 Kubernetes 来构建 AI 平台最大的优势是什么?11月21日上午11点,由作者选出回答最佳的5位读者,送腾讯云定制企鹅一个。
重 磅 来 袭
往期精选推荐