client-go實戰(zhàn)之二:RESTClient

歡迎訪問我的GitHub

https://github.com/zq2599/blog_demos

內(nèi)容:所有原創(chuàng)文章分類匯總及配套源碼廊营,涉及Java饼灿、Docker赘娄、Kubernetes归园、DevOPS等吞杭;

系列文章鏈接

  1. client-go實戰(zhàn)之一:準備工作
  2. client-go實戰(zhàn)之二:RESTClient
  3. client-go實戰(zhàn)之三:Clientset
  4. client-go實戰(zhàn)之四:dynamicClient
  5. client-go實戰(zhàn)之五:DiscoveryClient

本篇概覽

  • 本文是《client-go實戰(zhàn)》系列的第二篇廊遍,前文咱們提到過client-go一共有四種客戶端:RESTClient踪旷、ClientSet植捎、DynamicClient衙解、DiscoveryClient,而RESTClient是最基礎(chǔ)的版本鸥跟,其他三種都是基于RESTClient封裝的丢郊,今天咱們通過實戰(zhàn)編碼來學習RESTClient,熟悉最基礎(chǔ)的遠程操作步驟医咨;
  • 本篇由以下幾部分組成:
  1. 簡介RESTClient
  2. 每次編碼前的準備工作
  3. 正式編碼
  4. 驗證
  5. 關(guān)鍵源碼分析

RESTClient簡介

  • RESTClient是client-go最基礎(chǔ)的客戶端枫匾,主要是對HTTP Reqeust進行了封裝,對外提供RESTful風格的API拟淮,并且提供豐富的API用于各種設(shè)置干茉,相比其他幾種客戶端雖然更復雜,但是也更為靈活很泊;
  • 使用RESTClient對kubernetes的資源進行增刪改查的基本步驟如下:
  1. 確定要操作的資源類型(例如查找deployment列表)角虫,去官方API文檔中找到對于的path沾谓、數(shù)據(jù)結(jié)構(gòu)等信息,后面會用到戳鹅;
  2. 加載配置kubernetes配置文件(和kubectl使用的那種kubeconfig完全相同)均驶;
  3. 根據(jù)配置文件生成配置對象,并且通過API對配置對象就行設(shè)置(例如請求的path枫虏、Group妇穴、Version、序列化反序列化工具等)隶债;
  4. 創(chuàng)建RESTClient實例腾它,入?yún)⑹桥渲脤ο螅?/li>
  5. 調(diào)用RESTClient實例的方法向kubernetes的API Server發(fā)起請求,編碼用fluent風格將各種參數(shù)傳入(例如指定namespace死讹、資源等)瞒滴,如果是查詢類請求,還要傳入數(shù)據(jù)結(jié)構(gòu)實例的指針赞警,改數(shù)據(jù)結(jié)構(gòu)用于接受kubernetes返回的查詢結(jié)果妓忍;
  • 接下來的編碼實戰(zhàn)也是按照上述流程進行的;

實戰(zhàn)內(nèi)容

  • 本次實戰(zhàn)內(nèi)容很簡單:查詢<font color="blue">kube-system</font>這個namespace下的所有pod仅颇,然后在控制臺打印每個pod的幾個關(guān)鍵字段单默;
  • 感謝您耐心聽我啰嗦了一大堆,接下來開始實戰(zhàn)吧忘瓦;

源碼下載

名稱 鏈接 備注
項目主頁 https://github.com/zq2599/blog_demos 該項目在GitHub上的主頁
git倉庫地址(https) https://github.com/zq2599/blog_demos.git 該項目源碼的倉庫地址,https協(xié)議
git倉庫地址(ssh) git@github.com:zq2599/blog_demos.git 該項目源碼的倉庫地址耕皮,ssh協(xié)議
  • 這個git項目中有多個文件夾境蜕,client-go相關(guān)的應用在<font color="blue">client-go-tutorials</font>文件夾下,如下圖紅框所示:
在這里插入圖片描述
  • client-go-tutorials文件夾下有多個子文件夾凌停,本篇對應的源碼在<font color="blue">restclientdemo</font>目錄下粱年,如下圖紅框所示:
在這里插入圖片描述

查看官方文檔,獲取編碼所需內(nèi)容

在這里插入圖片描述
  • 然后還要關(guān)注響應的數(shù)據(jù)結(jié)構(gòu)赐俗,如下圖紅框拉队,返回的是:
在這里插入圖片描述
  • 點擊上圖紅框中的內(nèi)容,可見PodList的詳情阻逮,這就是我們編碼時所需的數(shù)據(jù)結(jié)構(gòu):
在這里插入圖片描述
  • 掌握了請求和響應的詳細信息粱快,可以開始編碼了;

編碼

  • 新建文件夾restclientdemo,在里面執(zhí)行以下命令事哭,新建module:
go mod init restclientdemo
  • 添加k8s.io/api和k8s.io/client-go這兩個依賴漫雷,注意版本要匹配kubernetes環(huán)境:
go get k8s.io/api@v0.20.0
go get k8s.io/client-go@v0.20.0
  • 新建main.go,內(nèi)容如下鳍咱,已經(jīng)都添加了詳細的注釋降盹,就不贅述了:
package main

import (
    "context"
    "flag"
    "fmt"
    "k8s.io/client-go/kubernetes/scheme"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
    corev1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "path/filepath"
)

func main() {
    var kubeconfig *string

    // home是家目錄,如果能取得家目錄的值谤辜,就可以用來做默認值
    if home:=homedir.HomeDir(); home != "" {
        // 如果輸入了kubeconfig參數(shù)澎现,該參數(shù)的值就是kubeconfig文件的絕對路徑,
        // 如果沒有輸入kubeconfig參數(shù)每辟,就用默認路徑~/.kube/config
        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    } else {
        // 如果取不到當前用戶的家目錄,就沒辦法設(shè)置kubeconfig的默認目錄了干旧,只能從入?yún)⒅腥?        kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    }

    flag.Parse()

    // 從本機加載kubeconfig配置文件渠欺,因此第一個參數(shù)為空字符串
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)

    // kubeconfig加載失敗就直接退出了
    if err != nil {
        panic(err.Error())
    }

    // 參考path : /api/v1/namespaces/{namespace}/pods
    config.APIPath = "api"
    // pod的group是空字符串
    config.GroupVersion = &corev1.SchemeGroupVersion
    // 指定序列化工具
    config.NegotiatedSerializer = scheme.Codecs

    // 根據(jù)配置信息構(gòu)建restClient實例
    restClient, err := rest.RESTClientFor(config)

    if err!=nil {
        panic(err.Error())
    }

    // 保存pod結(jié)果的數(shù)據(jù)結(jié)構(gòu)實例
    result := &corev1.PodList{}

    //  指定namespace
    namespace := "kube-system"
    // 設(shè)置請求參數(shù),然后發(fā)起請求
    // GET請求
    err = restClient.Get().
        //  指定namespace椎眯,參考path : /api/v1/namespaces/{namespace}/pods
        Namespace(namespace).
        // 查找多個pod挠将,參考path : /api/v1/namespaces/{namespace}/pods
        Resource("pods").
        // 指定大小限制和序列化工具
        VersionedParams(&metav1.ListOptions{Limit:100}, scheme.ParameterCodec).
        // 請求
        Do(context.TODO()).
        // 結(jié)果存入result
        Into(result)

    if err != nil {
        panic(err.Error())
    }

    // 表頭
    fmt.Printf("namespace\t status\t\t name\n")

    // 每個pod都打印namespace、status.Phase编整、name三個字段
    for _, d := range result.Items {
        fmt.Printf("%v\t %v\t %v\n",
            d.Namespace,
            d.Status.Phase,
            d.Name)
    }
}

  • 編碼完成舔稀,執(zhí)行<font color="blue">go run main.go</font>,即可獲取指定namespace下所有pod的信息掌测,控制臺輸出如下:
(base) zhaoqindeMBP:restclientdemo zhaoqin$ go run main.go
namespace    status      name
kube-system  Running     coredns-7f89b7bc75-5pdwc
kube-system  Running     coredns-7f89b7bc75-nvbvm
kube-system  Running     etcd-hedy
kube-system  Running     kube-apiserver-hedy
kube-system  Running     kube-controller-manager-hedy
kube-system  Running     kube-flannel-ds-v84vc
kube-system  Running     kube-proxy-hlppx
kube-system  Running     kube-scheduler-hedy
  • 至此内贮,RESTClient客戶端從編碼到驗證都完成了;

如何將收到的數(shù)據(jù)反序列化為PodList對象汞斧?

  • 前面的代碼比較簡單夜郁,但是有一處引起了我的興趣,如下圖紅框所示粘勒,result是corev1.PodList類型的結(jié)構(gòu)體指針竞端,restClient收到kubernetes返回的數(shù)據(jù)后,如何知道要將數(shù)據(jù)反序列化成corev1.PodList類型呢(Into方法入?yún)㈩愋蜑閞untime.Object)庙睡?
在這里插入圖片描述
  • 之前的代碼中有一行設(shè)置了編解碼工具:<font color="blue">config.NegotiatedSerializer = scheme.Codecs</font>事富,展開這個scheme.Codecs,可見設(shè)置的時候確定了序列化工具為runtime.Serializer:
在這里插入圖片描述
  • Serializer的typer字段類型是runtime.ObjectTyper乘陪,這里實際上是runtime.Scheme统台,因此ObjectTyper.ObjectKinds方法,實際上就是Scheme.ObjectKinds方法暂刘,在里面根據(jù)s.typeToGVK[t]拿到了GVK饺谬,也就是v1.PodList:
在這里插入圖片描述
  • 有了這個GVK就確定的返回數(shù)據(jù)的類型,最終調(diào)用<font color="blue">caseSensitiveJSONIterator.Unmarshal(data, obj)</font>完成byte數(shù)組到對象的反序列化操作:
在這里插入圖片描述
  • 最后還有一行關(guān)鍵代碼,將data的內(nèi)容寫到最外層的Into方法的入?yún)⒅校?/li>
在這里插入圖片描述
  • 源碼分析完成募寨,簡單來說除了利用反射獲取實際類型族展,還有就是Scheme內(nèi)部維護的數(shù)據(jù)類型和GVK的關(guān)系映射表;
  • 至此拔鹰,RESTClient的實戰(zhàn)就完成了仪缸,希望本篇能幫助您打好基礎(chǔ),這樣后面在體驗其他三種客戶端時已對其底層的實現(xiàn)原理了然于胸列肢;

你不孤單恰画,欣宸原創(chuàng)一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 數(shù)據(jù)庫+中間件系列
  6. DevOps系列

你不孤單,欣宸原創(chuàng)一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 數(shù)據(jù)庫+中間件系列
  6. DevOps系列

歡迎關(guān)注公眾號:程序員欣宸

微信搜索「程序員欣宸」瓷马,我是欣宸拴还,期待與您一同暢游Java世界...
https://github.com/zq2599/blog_demos

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市欧聘,隨后出現(xiàn)的幾起案子片林,更是在濱河造成了極大的恐慌,老刑警劉巖怀骤,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件费封,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒋伦,警方通過查閱死者的電腦和手機弓摘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痕届,“玉大人韧献,你說我怎么就攤上這事⊙薪校” “怎么了势决?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蓝撇。 經(jīng)常有香客問我果复,道長,這世上最難降的妖魔是什么渤昌? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任虽抄,我火速辦了婚禮,結(jié)果婚禮上独柑,老公的妹妹穿的比我還像新娘迈窟。我一直安慰自己,他們只是感情好忌栅,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布车酣。 她就那樣靜靜地躺著曲稼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪湖员。 梳的紋絲不亂的頭發(fā)上贫悄,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音娘摔,去河邊找鬼窄坦。 笑死,一個胖子當著我的面吹牛凳寺,可吹牛的內(nèi)容都是我干的鸭津。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肠缨,長吁一口氣:“原來是場噩夢啊……” “哼逆趋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起晒奕,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤父泳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吴汪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蒸眠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年漾橙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片楞卡。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡霜运,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蒋腮,到底是詐尸還是另有隱情淘捡,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布池摧,位于F島的核電站焦除,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏作彤。R本人自食惡果不足惜膘魄,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望竭讳。 院中可真熱鬧创葡,春花似錦、人聲如沸绢慢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至骚露,卻和暖如春蹬挤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荸百。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工闻伶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人够话。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓蓝翰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親女嘲。 傳聞我的和親對象是個殘疾皇子畜份,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容