使用 Kubebuilder 定义 CRD 输出列

k8s技术圈

共 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 二次开发感兴趣的朋友可以扫描下方二维码了解课程详情。

浏览 70
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报