导读
我们在使用client-go管理内置资源时,有内置的结构体定义,比如Pod、Deployment等,都已经定义好了,非常方便。但是当你想管理CRD资源时,就比较麻烦了,首先client-go中没有针对特定CRD的操作方法,需要你自己去管理dynamic client。 另外,对CRD资源的list-watch也非常复杂,很多同学不知道到底如何去做。 所以我们又要请出kom来了。
基于 kom 执行管理CRD资源的操作教程
1. 工具简介
kom 是一个用于管理 Kubernetes 集群的高效工具,支持多集群操作、自定义资源定义(CRD)、POD 文件操作等。通过链式调用和回调机制,kom 提供了简单易用的 Kubernetes 管理方式。
2. 安装和运行
2.1 集成 kom
在项目中引入 kom 依赖:
import (
_ "github.com/weibaohui/kom/callbacks" // 导入回调机制
"github.com/weibaohui/kom"
)
3. 自定义资源定义(CRD)增删改查及Watch操作
因为没有CRD的结构体定义文件,所以我们才有client-go内置的unstructured.Unstructured结构体来装载实例。 每一个资源都有Group、Version、Kind,CRD也是通过GVK来定位识别资源类型。
因此可以通过kom.DefaultCluster().GVK(group, version, kind)来替代kom.DefaultCluster().Resource(interface{})
为方便记忆及使用,kom提供了kom.DefaultCluster().CRD(group, version, kind)来简化操作。
下面给出操作CRD的示例: 首先定义一个通用的处理对象,用来接收CRD的返回结果。
var item unstructured.Unstructured
创建CRD
yaml := `apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cronSpec:
type: string
image:
type: string
replicas:
type: integer
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
shortNames:
- ct`
result := kom.DefaultCluster().Applier().Apply(yaml)
创建CRD的CR对象
item = unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "stable.example.com/v1",
"kind": "CronTab",
"metadata": map[string]interface{}{
"name": "test-crontab",
"namespace": "default",
},
"spec": map[string]interface{}{
"cronSpec": "* * * * */8",
"image": "test-crontab-image",
},
},
}
err := kom.DefaultCluster().CRD("stable.example.com", "v1", "CronTab").Namespace(item.GetNamespace()).Name(item.GetName()).Create(&item).Error
Get获取单个CR对象
err := kom.DefaultCluster().CRD("stable.example.com", "v1", "CronTab").Name(item.GetName()).Namespace(item.GetNamespace()).Get(&item).Error
List获取CR对象的列表
var crontabList []unstructured.Unstructured
err := kom.DefaultCluster().CRD("stable.example.com", "v1", "CronTab").Namespace(crontab.GetNamespace()).List(&crontabList).Error
更新CR对象
patchData := `{
"spec": {
"image": "patch-image"
},
"metadata": {
"labels": {
"new-label": "new-value"
}
}
}`
err := kom.DefaultCluster().CRD("stable.example.com", "v1", "CronTab").Name(crontab.GetName()).Namespace(crontab.GetNamespace()).Patch(&crontab, types.MergePatchType, patchData).Error
删除CR对象
err := kom.DefaultCluster().CRD("stable.example.com", "v1", "CronTab").Name(crontab.GetName()).Namespace(crontab.GetNamespace()).Delete().Error
Watch CR对象
var watcher watch.Interface
err := kom.DefaultCluster().CRD("stable.example.com", "v1", "CronTab").Namespace("default").Watch(&watcher).Error
if err != nil {
fmt.Printf("Create Watcher Error %v", err)
}
go func() {
defer watcher.Stop()
for event := range watcher.ResultChan() {
var item *unstructured.Unstructured
item, err := kom.DefaultCluster().Tools().ConvertRuntimeObjectToUnstructuredObject(event.Object)
if err != nil {
fmt.Printf("无法将对象转换为 Unstructured 类型: %v", err)
return
}
// 处理事件
switch event.Type {
case watch.Added:
fmt.Printf("Added Unstructured [ %s/%s ]\n", item.GetNamespace(), item.GetName())
case watch.Modified:
fmt.Printf("Modified Unstructured [ %s/%s ]\n", item.GetNamespace(), item.GetName())
case watch.Deleted:
fmt.Printf("Deleted Unstructured [ %s/%s ]\n", item.GetNamespace(), item.GetName())
}
}
}()
4. 总结
通过 kom 的kom.CRD("stable.example.com", "v1", "CronTab")方法,可以操作任意类型的CRD资源了。读取、列表、修改、删除、List-Watch都不在话下。