资讯专栏INFORMATION COLUMN

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

simon_chen / 597人阅读

摘要:看过的应该都知道项目中有大量代码工具生成的代码。执行即脚本将自动生成下面的文件和路径脚本运行后大体会建立如下的包管理结构是不是很简单代码是被完全生成的,就像包含我们的语言类型的文件下面的文件一样然后你就可以基于生成的代码写自己的了。

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/

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

是不是很简单?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可以抽象很多业务场景。接下我司准备实现一个部署策略相关的项目。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/32653.html

相关文章

  • k8sCRD--为自定义资源生成代码

    摘要:看过的应该都知道项目中有大量代码工具生成的代码。执行即脚本将自动生成下面的文件和路径脚本运行后大体会建立如下的包管理结构是不是很简单代码是被完全生成的,就像包含我们的语言类型的文件下面的文件一样然后你就可以基于生成的代码写自己的了。 CRD简介和使用姿势 CustomResourceDefinition(CRD)是 v1.7 + 新增的无需改变代码就可以扩展 Kubernetes AP...

    jkyin 评论0 收藏0
  • kubernetes自定义资源对象高级功能

    摘要:可以通过验证自定义对象是否符合标准。此功能可用于及以上版本自定义资源。状态和规范节分别由自定义资源内的和表示。对子资源的请求采用自定义资源对象,并忽略除状态节之外的任何更改。该对象作为有效负载发送。 kubernetes自定义资源对象高级功能 本文首发于微信公众号我的小碗汤,扫码文末二维码即可关注,欢迎一起交流! kubernetes自定义资源对象再极大程度提高了API Server的...

    Mr_zhang 评论0 收藏0
  • kubernetes自定义资源对象高级功能

    摘要:可以通过验证自定义对象是否符合标准。此功能可用于及以上版本自定义资源。状态和规范节分别由自定义资源内的和表示。对子资源的请求采用自定义资源对象,并忽略除状态节之外的任何更改。该对象作为有效负载发送。 kubernetes自定义资源对象高级功能 本文首发于微信公众号我的小碗汤,扫码文末二维码即可关注,欢迎一起交流! kubernetes自定义资源对象再极大程度提高了API Server的...

    陈江龙 评论0 收藏0
  • 容器监控实践—Prometheus部署方案

    摘要:同时有权限控制日志审计整体配置过期时间等功能。将成为趋势前置条件要求的版本应该是因为和支持的限制的核心思想是将的部署与它监控的对象的配置分离,做到部署与监控对象的配置分离之后,就可以轻松实现动态配置。 一.单独部署 二进制安装各版本下载地址:https://prometheus.io/download/ Docker运行 运行命令:docker run --name promet...

    GeekQiaQia 评论0 收藏0
  • 容器 PaaS 新技术架构下的运维实践

    摘要:王磊此次演讲的题目为容器新技术架构下的运维实践,详细为大家讲解了在基于构建容器的过程中,如何以应用为中心,通过新的技术工具对服务节点集群平台等多个方面进行管理运维,提高系统的自动化运维能力。 2018年11月16-17日,运维&容器技术盛会 CNUTCon 全球运维技术大会在上海·光大会展中心成功举办。时速云联合创始人兼 CTO 王磊受邀参加此次大会,并发表主题演讲。王磊此次演讲的题目...

    BaronZhang 评论0 收藏0

发表评论

0条评论

simon_chen

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<