使用 Kubebuilder 定义 CRD 输出列
共 4548字,需浏览 10分钟
·
2020-11-16 23:39
前面我们介绍了使用 kubebuilder 开发 Operator 的示例,kubebuilder 是非常优秀的 Operator 开发框架,他可以帮我们自动生成很多代码,可以使用标准的 Go 对象来定义 CRD,此外我们还可以控制 kubectl 如何打印 CRD。
我们示例项目中开发的一个 MyApp
类型的 CRD 对象,通过这个 CRD 定义可以帮我们自动生成 Deployment 和 Service 对象。如下所示我们创建的 MyApp 的实例,我们可以使用 kubectl 命令列出这个对象:
$ kubectl get myapp
NAME AGE
myapp-demo 5d18h
但是这个信息太过于简单,如果我们想要查看这个对象使用了什么镜像,部署了多少个副本,我们可能还需要通过 kubectl describe
命令去查看,这样就太过于麻烦了。这个时候我们就可以在 CRD 定义的结构体类型中使用 +kubebuilder:printcolumn
这个注释来告诉 kubebuilder 将我们所需的信息添加到 CRD 中,比如我们想要打印使用的镜像,在 +kubebuilder:object:root=true
注释下面添加一列新的注释,如下所示:
// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Image",type="string",JSONPath=".spec.image",description="The Docker Image of MyAPP"
// +kubebuilder:subresource:status
// MyApp is the Schema for the myapps API
type MyApp struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec MyAppSpec `json:"spec,omitempty"`
Status MyAppStatus `json:"status,omitempty"`
}
printcolumn
注释有几个不同的选项,在这里我们只使用了其中一部分:
-
name:这是我们新增的列的标题,由 kubectl 打印在标题中 -
type:要打印的值的数据类型,有效类型为 integer、number、string、boolean 和 date -
JSONPath:这是要打印数据的路径,在我们的例子中,镜像 image 属于 spec 下面的属性,所以我们使用 .spec.image
。需要注意的是 JSONPath 属性引用的是生成的 JSON CRD -
description:描述列的可读字符串,目前暂未发现该属性的作用...
新增了注释后,我们需要运行 make install
命令重新生成 CRD 并安装,然后我们再次尝试列出 CRD。
$ kubectl get myapp
NAME IMAGE
myapp-demo nginx
可以看到现在列出来的数据有一列 IMAGE 的数据了,不过却没有了之前列出来的 AGE 这一列了。这是因为当我们添加自定义列的时候,就不会再显示其他默认的列了(NAME 除外),所以如果我们还想出现 AGE 这一列,我们还需要在 MyApp 的结构体上面添加对应的注释信息,如下所示:
// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Image",type="string",JSONPath=".spec.image",description="The Docker Image of MyAPP"
// +kubebuilder:printcolumn:name="Size",type="integer",JSONPath=".spec.size",description="Replicas of MyAPP"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:subresource:status
// MyApp is the Schema for the myapps API
type MyApp struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec MyAppSpec `json:"spec,omitempty"`
Status MyAppStatus `json:"status,omitempty"`
}
运行 make install
命令行,再次查看 CRD 数据:
$ kubectl get myapp
NAME IMAGE SIZE AGE
myapp-demo nginx 3 5d18h
现在我们可以看到正则运行的应用副本数了,而且 AGE 信息也回来了,当然如果我们还想获取当前应用的状态,同样也可以通过 +kubebuilder:printcolumn
来添加对应的信息,只是状态的数据是通过 .status
在 JSONPath 属性中去获取了。
如果你觉得这里添加了太多的信息,如果我们想隐藏某个字段并只在需要时显示该字段怎么办?这个时候就需要使用 priority
这个属性了,如果没有配置这个属性,默认值为0,也就是默认情况下列出显示的数据是 priority=0
的列,如果将 priority 设置为大于1的数字,那么则只会当我们使用 -o wide
参数的时候才会显示,比如我们给 Image 这一列添加一个 priority=1
的属性:
// +kubebuilder:printcolumn:name="Image",type="string",priority=1,JSONPath=".spec.image",description="The Docker Image of MyAPP
同样重新运行 make install
命令后,再次查看 CRD 数据:
$ kubectl get myapp
NAME SIZE AGE
myapp-demo 3 5d18h
我们可以看到已经没有打印出 IMAGE 这一列了,当我们添加 -o wide
时,该列会再次显示:
$ kubectl get myapp -o wide
NAME IMAGE SIZE AGE
myapp-demo nginx 3 5d18h
如果你还想了解更多详细信息请查看 CRD 文档上的 AdditionalPrinterColumns 字段(https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#additional-printer-columns)。
本文节选自《Kubernetes 开发课》课程文档,该课程正在持续更新中,对于 Kubernetes 二次开发感兴趣的朋友可以扫描下方二维码了解课程详情。