k8s自定义controller三部曲之二:自动生成代码

简介: 本文是《k8s自定义controller三部曲》的第二篇,我们一起来实战如何将controller所需的informer、client等代码通过工具自动生成

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos
  • 本文是《k8s自定义controller三部曲》的第二篇,上一篇我们在k8s环境注册了API对象Student,此时如果创建Student对象就会在etcd保存该对象信息;

三部曲所有文章链接

  1. 《k8s自定义controller三部曲之一:创建CRD(Custom Resource Definition)》
  2. 《k8s自定义controller三部曲之二:自动生成代码》
  3. 《k8s自定义controller三部曲之三:编写controller代码》

源码下载

  • 接下来详细讲述应用的编码过程,如果您不想自己写代码,也可以在GitHub下载完整的应用源码,地址和链接信息如下表所示:
名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
  • 这个git项目中有多个文件夹,本章源码在k8s_customize_controller这个文件夹下,如下图红框所示:

在这里插入图片描述

为什么要做controller

  • 但如果仅仅是在etcd保存Student对象是没有什么意义的,试想通过deployment创建pod时,如果只在etcd创建pod对象,而不去node节点创建容器,那这个pod对象只是一条数据而已,没有什么实质性作用,其他对象如service、pv也是如此;
    controller的作用就是监听指定对象的新增、删除、修改等变化,针对这些变化做出相应的响应(例如新增pod的响应为创建docker容器),关于controller的详细设计,最好的参考就是Harry (Lei) Zhang老师在twitter上的分享,如下图,地址是:https://twitter.com/resouer/status/1009996649832185856
    在这里插入图片描述
  • 如上图,API对象的变化会通过Informer存入队列(WorkQueue),在Controller中消费队列的数据做出响应,响应相关的具体代码就是我们要做的真正业务逻辑;

自动生成代码是什么

  • 从上图可以发现整个逻辑还是比较复杂的,为了简化我们的自定义controller开发,k8s的大师们利用自动代码生成工具将controller之外的事情都做好了,我们只要专注于controller的开发就好。
  • 关于controller的代码我们留待下一章完成,本章关注的是如何自动生成代码的实战,将上图中controller之外的事情都完成了;

开始实战

  • 接下来要做的事情就是编写API对象Student相关的声明的定义代码,然后用代码生成工具结合这些代码,自动生成Client、Informet、WorkQueue相关的代码;
  • 在$GOPATH/src/目录下创建一个文件夹k8s_customize_controller
  • 进入文件夹k8s_customize_controller,执行如下命令创建三层目录:
mkdir -p pkg/apis/bolingcavalry
  • 在新建的bolingcavalry目录下创建文件register.go,内容如下:
package bolingcavalry

const (
        GroupName = "bolingcavalry.k8s.io"
        Version   = "v1"
)
  • 在新建的bolingcavalry目录下创建名为v1的文件夹;
  • 在新建的v1文件夹下创建文件doc.go,内容如下:
// +k8s:deepcopy-gen=package

// +groupName=bolingcavalry.k8s.io
package v1
  • 上述代码中的两行注释,都是代码生成工具会用到的,一个是声明为整个v1包下的类型定义生成DeepCopy方法,另一个声明了这个包对应的API的组名,和CRD中的组名一致;
  • 在v1文件夹下创建文件types.go,里面定义了Student对象的具体内容:
package v1

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

// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type Student struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`
    Spec              StudentSpec `json:"spec"`
}

type StudentSpec struct {
    name   string `json:"name"`
    school string `json:"school"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// StudentList is a list of Student resources
type StudentList struct {
    metav1.TypeMeta `json:",inline"`
    metav1.ListMeta `json:"metadata"`

    Items []Student `json:"items"`
}
  • 从上述源码可见,Student对象的内容已经被设定好,主要有name和school这两个字段,表示学生的名字和所在学校,因此创建Student对象的时候内容就要和这里匹配了;
  • 在v1目录下创建register.go文件,此文件的作用是通过addKnownTypes方法使得client可以知道Student类型的API对象:
package v1

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

    "k8s_customize_controller/pkg/apis/bolingcavalry"
)

var SchemeGroupVersion = schema.GroupVersion{
    Group:   bolingcavalry.GroupName,
    Version: bolingcavalry.Version,
}

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

func Resource(resource string) schema.GroupResource {
    return SchemeGroupVersion.WithResource(resource).GroupResource()
}

func Kind(kind string) schema.GroupKind {
    return SchemeGroupVersion.WithKind(kind).GroupKind()
}

func addKnownTypes(scheme *runtime.Scheme) error {
    scheme.AddKnownTypes(
        SchemeGroupVersion,
        &Student{},
        &StudentList{},
    )

    // register the type in the scheme
    metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
    return nil
}
  • 至此,为自动生成代码做的准备工作已经完成了,目前为止,$GOPATH/src目录下的文件和目录结构是这样的:
[root@golang src]# tree
.
└── k8s_customize_controller
    └── pkg
        └── apis
            └── bolingcavalry
                ├── register.go
                └── v1
                    ├── doc.go
                    ├── register.go
                    └── types.go

5 directories, 4 files
  • 执行以下命令,会先下载依赖包,再下载代码生成工具,再执行代码生成工作:
cd $GOPATH/src \
&& go get -u k8s.io/apimachinery/pkg/apis/meta/v1 \
&& go get -u k8s.io/code-generator/... \
&& cd $GOPATH/src/k8s.io/code-generator \
&& ./generate-groups.sh all \
k8s_customize_controller/pkg/client \
k8s_customize_controller/pkg/apis \
bolingcavalry:v1
  • 如果代码写得没有问题,会看到以下输出:
Generating deepcopy funcs
Generating clientset for bolingcavalry:v1 at k8s_customize_controller/pkg/client/clientset
Generating listers for bolingcavalry:v1 at k8s_customize_controller/pkg/client/listers
Generating informers for bolingcavalry:v1 at k8s_customize_controller/pkg/client/informers
  • 此时再去$GOPATH/src/k8s_customize_controller目录下执行tree命令,可见已生成了很多内容:
[root@master k8s_customize_controller]# tree
.
└── pkg
    ├── apis
    │   └── bolingcavalry
    │       ├── register.go
    │       └── v1
    │           ├── doc.go
    │           ├── register.go
    │           ├── types.go
    │           └── zz_generated.deepcopy.go
    └── client
        ├── clientset
        │   └── versioned
        │       ├── clientset.go
        │       ├── doc.go
        │       ├── fake
        │       │   ├── clientset_generated.go
        │       │   ├── doc.go
        │       │   └── register.go
        │       ├── scheme
        │       │   ├── doc.go
        │       │   └── register.go
        │       └── typed
        │           └── bolingcavalry
        │               └── v1
        │                   ├── bolingcavalry_client.go
        │                   ├── doc.go
        │                   ├── fake
        │                   │   ├── doc.go
        │                   │   ├── fake_bolingcavalry_client.go
        │                   │   └── fake_student.go
        │                   ├── generated_expansion.go
        │                   └── student.go
        ├── informers
        │   └── externalversions
        │       ├── bolingcavalry
        │       │   ├── interface.go
        │       │   └── v1
        │       │       ├── interface.go
        │       │       └── student.go
        │       ├── factory.go
        │       ├── generic.go
        │       └── internalinterfaces
        │           └── factory_interfaces.go
        └── listers
            └── bolingcavalry
                └── v1
                    ├── expansion_generated.go
                    └── student.go

21 directories, 27 files
  • 如上所示,zz_generated.deepcopy.go就是DeepCopy代码文件,client目录下的内容都是客户端相关代码,在开发controller时会用到;
  • client目录下的clientset、informers、listers的身份和作用可以和前面的图结合来理解;
  • 至此,自动生成代码的步骤已经完成,我们已经为后面编写controller做好了充分的准备,接下来的章节就是编写controller了,点击链接继续实战:《k8s自定义controller三部曲之三:编写controller代码》

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
29天前
|
运维 Kubernetes 容灾
kubernetes核心技术之Controller控制器知识总结
kubernetes核心技术之Controller控制器知识总结
18 1
|
2月前
|
Kubernetes JavaScript API
云效常见问题之appstack连接自定义k8s连不上如何解决
云效(CloudEfficiency)是阿里云提供的一套软件研发效能平台,旨在通过工程效能、项目管理、质量保障等工具与服务,帮助企业提高软件研发的效率和质量。本合集是云效使用中可能遇到的一些常见问题及其答案的汇总。
262 1
|
4月前
|
消息中间件 Kubernetes 监控
kubernetes—Controller详解(二)
kubernetes—Controller详解(二)
51 0
|
4月前
|
Kubernetes 测试技术 Perl
kubernetes—Controller详解(一)
kubernetes—Controller详解(一)
38 0
|
5月前
|
Kubernetes Cloud Native 开发工具
云原生|kubernetes|helm3 自定义离线安装部署ingress-nginx
云原生|kubernetes|helm3 自定义离线安装部署ingress-nginx
149 0
|
7月前
|
存储 Kubernetes 调度
【云原生】k8s核心概念—Pod & Controller & Service & Serect & ConfigMap介绍——20230213
【云原生】k8s核心概念—Pod & Controller & Service & Serect & ConfigMap介绍——20230213
124 0
|
7月前
|
Kubernetes 应用服务中间件 调度
kubernetes Ingress、Ingress controller
kubernetes Ingress、Ingress controller
|
5天前
|
运维 Kubernetes 监控
Kubernetes 集群的持续性能优化实践
【4月更文挑战第26天】 在动态且不断增长的云计算环境中,维护高性能的 Kubernetes 集群是一个挑战。本文将探讨一系列实用的策略和工具,旨在帮助运维专家监控、分析和优化 Kubernetes 集群的性能。我们将讨论资源分配的最佳实践,包括 CPU 和内存管理,以及集群规模调整的策略。此外,文中还将介绍延迟和吞吐量的重要性,并提供日志和监控工具的使用技巧,以实现持续改进的目标。
|
7天前
|
存储 运维 Kubernetes
Kubernetes 集群的监控与维护策略
【4月更文挑战第23天】 在微服务架构日益盛行的当下,容器编排工具如 Kubernetes 成为了运维工作的重要环节。然而,随着集群规模的增长和复杂性的提升,如何确保 Kubernetes 集群的高效稳定运行成为了一大挑战。本文将深入探讨 Kubernetes 集群的监控要点、常见问题及解决方案,并提出一系列切实可行的维护策略,旨在帮助运维人员有效管理和维护 Kubernetes 环境,保障服务的持续可用性和性能优化。
|
9天前
|
存储 运维 Kubernetes
Kubernetes 集群的持续性能优化实践
【4月更文挑战第22天】在动态且复杂的微服务架构中,确保 Kubernetes 集群的高性能运行是至关重要的。本文将深入探讨针对 Kubernetes 集群性能优化的策略与实践,从节点资源配置、网络优化到应用部署模式等多个维度展开,旨在为运维工程师提供一套系统的性能调优方法论。通过实际案例分析与经验总结,读者可以掌握持续优化 Kubernetes 集群性能的有效手段,以适应不断变化的业务需求和技术挑战。

推荐镜像

更多