k8s之CRD--为自定义资源生成代码

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: CRD简介和使用姿势 CustomResourceDefinition(CRD)是 v1.7 + 新增的无需改变代码就可以扩展 Kubernetes API 的机制,用来管理自定义对象。它实际上是 ThirdPartyResources(TPR) 的升级版本,而 TPR 已经在 v1.8 中删除。

CRD简介和使用姿势

CustomResourceDefinition(CRD)是 v1.7 + 新增的无需改变代码 就可以扩展 Kubernetes API 的机制,用来管理自定义对象。它实际上是 ThirdPartyResources(TPR) 的升级版本,而 TPR 已经在 v1.8 中删除。

一些使用场景:

  • 提供/管理外部数据存储/数据库(例如 CloudSQL/RDS 实例)
  • 对k8s基础资源进行更高层次的抽象(比如定义一个etcd集群)

其实crd在很多k8s周边开源项目中有使用,比如ingress-controller和众多的operator。

CRD 控制器

在使用 CRD 扩展 Kubernetes API 时,通常还需要实现一个新建资源的控制器,监听改资源的变化情况,并作进一步的处理。官方提供的示例项目sample-controller
这个例子主要讲述了以下几个方面:

  • 如何使用自定义资源定义注册Foo类型的新自定义资源(自定义资源类型)
  • 如何创建/获取/列出新资源类型Foo实例
  • 如何在资源处理创建/更新/删除事件上设置控制器

编写crd controller之前,一定要使用k8s官方提供的代码生成工具k8s.io/code-generator 去生成 client, informers, listers and deep-copy函数.不仅代码风格符合k8s,而且减少出错和减少工作量都是有很大的帮助。

在项目中使用代码生成器

下面展示了代码生成工具是如何工作的以及如何使用最少的代码行将它们应用到自己的项目中,从而为您生成 deepcopy 函数/typed clients/listers/informer,所有这些的生成仅需要一个 shell 脚本调用和部分代码注释。
不要觉得代码生成有多么复杂,其实官方已经做了很多工作了,提供了 generator-group.sh。看过client-go的gopher应该都知道项目中有大量代码工具生成的代码。
执行./hack/update-codegen.sh,即

#!/usr/bin/env bash
 # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -o errexit
set -o nounset
set -o pipefail

SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}

# generate the code with: # --output-base because this script should also be able to run inside the vendor dir of # k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir # instead of the $GOPATH directly. For normal projects this can be dropped. ${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
 k8s.io/canary-controller/pkg/client k8s.io/canary-controller/pkg/apis \
 canarycontroller:v1alpha1 \
 --output-base "$(dirname ${BASH_SOURCE})/../../.." \
 --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt

# To use your own boilerplate text use: # --go-header-file ${SCRIPT_ROOT}/hack/custom-boilerplate.go.txt 

update-codegen脚本将自动生成下面的文件和路径

  • pkg/apis/canarycontroller/v1alpha1/zz_generated.deepcopy.go
  • pkg/client/

脚本运行后大体会建立如下的包管理结构:

432c62b6242a19035f1014edf16f65d2686bf606

是不是很简单?pkg/client 代码是被完全生成的,就像包含我们的 CustomResource golang语言类型的 types.go 文件下面的 zz_generated.deepcopy.go 文件一样,然后你就可以基于生成的代码写自己的controller了。不过并不是不需要自己写一点代码,毕竟机器没有智能到你定义了什么样子的crd。所有以下几个文件需要自己来定义和实现,均是和你自己的业务逻辑相关。
pkg/apis以下的除zz_generated.deepcopy.go以外的所有文件。
比如:
types.go

 /*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Canary is a specification for a Foo resource type Canary struct {
 metav1.TypeMeta `json:",inline"`
 metav1.ObjectMeta `json:"metadata,omitempty"`

 Spec CanarySpec `json:"spec"`
 Status CanaryStatus `json:"status"`
}

// CanarySpec is the spec for a Foo resource type CanarySpec struct {
 DeploymentName string `json:"deploymentName"`
 Replicas *int32 `json:"replicas"`
}

// CanaryStatus is the status for a Foo resource type CanaryStatus struct {
 AvailableReplicas int32 `json:"availableReplicas"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // CanaryList is a list of Foo resources type CanaryList struct {
 metav1.TypeMeta `json:",inline"`
 metav1.ListMeta `json:"metadata"`

 Items []Canary `json:"items"`
}

registry.go

/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/ package v1alpha1

import (
 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema"

 canarycontroller "k8s.io/canary-controller/pkg/apis/canarycontroller"
)

// SchemeGroupVersion is group version used to register these objects var SchemeGroupVersion = schema.GroupVersion{Group: canarycontroller.GroupName, Version: "v1alpha1"}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind func Kind(kind string) schema.GroupKind {
 return SchemeGroupVersion.WithKind(kind).GroupKind()
}

// Resource takes an unqualified resource and returns a Group qualified GroupResource func Resource(resource string) schema.GroupResource {
 return SchemeGroupVersion.WithResource(resource).GroupResource()
}

var (
 SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
 AddToScheme = SchemeBuilder.AddToScheme
)

// Adds the list of known types to Scheme. func addKnownTypes(scheme *runtime.Scheme) error {
 scheme.AddKnownTypes(SchemeGroupVersion,
 &Canary{},
 &CanaryList{},
 )
 metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 return nil
}

更多相关细节

Kubernetes Deep Dive: Code Generation for CustomResources给出了具体的步骤和关于tag的标注。

总结

基于crd以及crd controller可以抽象很多业务场景。接下我司准备实现一个部署策略相关的项目。

本文转自中文社区-k8s之CRD--为自定义资源生成代码

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
运维 Kubernetes 监控
揭秘高效运维:如何用kubectl top命令实时监控K8s资源使用情况?
揭秘高效运维:如何用kubectl top命令实时监控K8s资源使用情况?
612 0
|
17天前
|
Kubernetes 安全 测试技术
超大规模商用 K8s 场景下,阿里巴巴如何动态解决容器资源的按需分配问题?
超大规模商用 K8s 场景下,阿里巴巴如何动态解决容器资源的按需分配问题?
|
2月前
|
运维 Kubernetes Shell
Kubernetes详解(十二)——节点选择器与资源注解
Kubernetes详解(十二)——节点选择器与资源注解
49 2
|
2月前
|
运维 Kubernetes Linux
Kubernetes详解(九)——资源配置清单创建Pod实战
Kubernetes详解(九)——资源配置清单创建Pod实战
86 2
|
2月前
|
JSON Kubernetes API
Kubernetes详解(八)——Kubernetes资源配置清单
Kubernetes详解(八)——Kubernetes资源配置清单
50 2
|
2月前
|
Kubernetes 监控 调度
Kubernetes(K8s)与虚拟GPU(vGPU)协同:实现GPU资源的高效管理与利用
本文探讨了如何使用Kubernetes和虚拟GPU(vGPU)实现异构GPU的协同调度。Kubernetes是一个容器编排平台,通过设备插件、资源规格、调度器扩展和节点标签实现GPU资源管理。vGPU技术允许物理GPU资源在多个虚拟机或容器中共享。文章详细介绍了vGPU的部署配置步骤,并提出了GPU资源调度、负载均衡和监控调优的方法。强调虚拟GPU的性能取决于硬件和驱动支持,合理配置能提供高性能计算环境。参考文献包括Kubernetes和NVIDIA官方文档及相关研究论文。
|
2月前
|
存储 Kubernetes 关系型数据库
Kubernetes详解(二)——Kubernetes结构与资源对象
Kubernetes详解(二)——Kubernetes结构与资源对象
62 0
|
2月前
|
Kubernetes 调度 容器
Kubernetes容器资源限制
Kubernetes容器资源限制
36 0
|
2月前
|
消息中间件 Kubernetes Kafka
Terraform阿里云创建资源1分钟创建集群一键发布应用Terraform 创建 Kubernetes 集群
Terraform阿里云创建资源1分钟创建集群一键发布应用Terraform 创建 Kubernetes 集群
85 0
|
2月前
|
Kubernetes 网络协议 应用服务中间件
K8S管理核心资源的三种基本方法
K8S管理核心资源的三种基本方法
37 0

推荐镜像

更多