使用 Kubebuilder 定義 CRD 輸出列

前面我們介紹了使用 kubebuilder 開發(fā) Operator 的示例,kubebuilder 是非常優(yōu)秀的 Operator 開發(fā)框架,他可以幫我們自動生成很多代碼,可以使用標準的 Go 對象來定義 CRD,此外我們還可以控制 kubectl 如何打印 CRD。
我們示例項目中開發(fā)的一個 MyApp 類型的 CRD 對象,通過這個 CRD 定義可以幫我們自動生成 Deployment 和 Service 對象。如下所示我們創(chuàng)建的 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:描述列的可讀字符串,目前暫未發(fā)現該屬性的作用...
新增了注釋后,我們需要運行 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 信息也回來了,當然如果我們還想獲取當前應用的狀態(tài),同樣也可以通過 +kubebuilder:printcolumn 來添加對應的信息,只是狀態(tài)的數據是通過 .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)。
本文節(jié)選自《Kubernetes 開發(fā)課》課程文檔,該課程正在持續(xù)更新中,對于 Kubernetes 二次開發(fā)感興趣的朋友可以掃描下方二維碼了解課程詳情。
