CustomResourceDefinition
CustomResourceDefinition(CRD)是 v1.7 新增的无需改变代码就可以扩展 Kubernetes API 的机制,用来管理自定义对象。它实际上是 ThirdPartyResources(TPR)的升级版本,而 TPR 已经在 v1.8 中弃用。
API 版本对照表
v1.8+
apiextensions.k8s.io/v1beta1
CRD 示例
下面的例子会创建一个 /apis/stable.example.com/v1/namespaces/<namespace>/crontabs/… 的自定义 API:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: crontabs.stable.example.com
spec:
# group name to use for REST API: /apis/<group>/<version>
group: stable.example.com
# versions to use for REST API: /apis/<group>/<version>
versions:
- name: v1beta1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
- name: v1
served: true
storage: false
# either Namespaced or Cluster
scope: Namespaced
names:
# plural name to be used in the URL: /apis/<group>/<version>/<plural>
plural: crontabs
# singular name to be used as an alias on the CLI and for display
singular: crontab
# kind is normally the CamelCased singular type. Your resource manifests use this.
kind: CronTab
# shortNames allow shorter string to match your resource on the CLI
shortNames:
- ctAPI 创建好后,就可以创建具体的 CronTab 对象了
Finalizer
Finalizer 用于实现控制器的异步预删除钩子,可以通过 metadata.finalizers 来指定 Finalizer。
Finalizer 指定后,客户端删除对象的操作只会设置 metadata.deletionTimestamp 而不是直接删除。这会触发正在监听 CRD 的控制器,控制器执行一些删除前的清理操作,从列表中删除自己的 finalizer,然后再重新发起一个删除操作。此时,被删除的对象才会真正删除。
Validation
v1.8 开始新增了实验性的基于 OpenAPI v3 schema 的验证(Validation)机制,可以用来提前验证用户提交的资源是否符合规范。使用该功能需要配置 kube-apiserver 的 --feature-gates=CustomResourceValidation=true。
比如下面的 CRD 要求
spec.cronSpec必须是匹配正则表达式的字符串spec.replicas必须是从 1 到 10 的整数
这样,在创建下面的 CronTab 时
会报验证失败的错误:
Subresources
v1.10 开始 CRD 还支持 /status 和 /scale 等两个子资源(Beta),并且从 v1.11 开始默认开启。
v1.10 版本使用前需要在
kube-apiserver开启--feature-gates=CustomResourceSubresources=true。
Categories
Categories 用来将 CRD 对象分组,这样就可以使用 kubectl get <category-name> 来查询属于该组的所有对象。
CRD 控制器
在使用 CRD 扩展 Kubernetes API 时,通常还需要实现一个新建资源的控制器,监听新资源的变化情况,并作进一步的处理。
https://github.com/kubernetes/sample-controller 提供了一个 CRD 控制器的示例,包括
如何注册资源
Foo如何创建、删除和查询
Foo对象如何监听
Foo资源对象的变化情况
Kubebuilder
从上面的实例中可以看到从头构建一个 CRD 控制器并不容易,需要对 Kubernetes 的 API 有深入了解,并且RBAC 集成、镜像构建、持续集成和部署等都需要很大工作量。
kubebuilder 正是为解决这个问题而生,为 CRD 控制器提供了一个简单易用的框架,并可直接生成镜像构建、持续集成、持续部署等所需的资源文件。
安装
使用方法
初始化项目
创建 API
然后按照实际需要修改 pkg/apis/ship/v1beta1/sloop_types.go 和 pkg/controller/sloop/sloop_controller.go 增加业务逻辑。
本地运行测试
如果碰到错误
ValidationError(CustomResourceDefinition.status): missing required field "storedVersions" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionStatus],可以手动修改config/crds/ships_v1beta1_sloop.yaml:```yaml status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: []
然后运行
kubectl apply -f config/crds创建 CRD。
然后就可以用 ships.k8s.io/v1beta1 来创建 Kind 为 Sloop 的资源了,比如
构建镜像并部署控制器
kustomize 已经不再支持通配符,因而上述
make deploy可能会碰到Load from path ../rbac/*.yaml failed错误,解决方法是手动修改config/default/kustomization.yaml:resources:
../rbac/rbac_role.yaml
../rbac/rbac_role_binding.yaml
../manager/manager.yaml
然后执行
kustomize build config/default | kubectl apply -f -部署,默认部署到demo-systemnamespace 中。
文档和测试
参考文档
最后更新于