<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          kubernetes client-go源代碼閱讀之動態(tài)客戶端

          共 4673字,需瀏覽 10分鐘

           ·

          2023-07-15 06:37

          與client-go靜態(tài)客戶端相對應的自然就是動態(tài)客戶端了,動態(tài)客戶端的價值在于靈活,不用重新生成客戶端代碼就能訪問k8s集群中的所有資源,即使是非內(nèi)置資源。

          快速入門

          下面是官方的一個例子,完整版可參考: https://github.com/kubernetes/client-go/blob/v0.20.2/examples/dynamic-create-update-delete-deployment/main.go

                
                func?main()?{
          ?var?kubeconfig?*string
          ?config,?err?:=?clientcmd.BuildConfigFromFlags("",?*kubeconfig)
          ?client,?err?:=?dynamic.NewForConfig(config)

          ?deploymentRes?:=?schema.GroupVersionResource{Group:?"apps",?Version:?"v1",?Resource:?"deployments"}

          ?deployment?:=?&unstructured.Unstructured{/*具體代碼被省略了*/}

          ?//?Create?Deployment
          ?fmt.Println("Creating?deployment...")
          ?result,?err?:=?client.Resource(deploymentRes).Namespace(namespace).Create(context.TODO(),?deployment,?metav1.CreateOptions{})
          ?fmt.Printf("Created?deployment?%q.\n",?result.GetName())

          ?fmt.Println("Updating?deployment...")
          ?retryErr?:=?retry.RetryOnConflict(retry.DefaultRetry,?func()?error?{
          ??//?Retrieve?the?latest?version?of?Deployment?before?attempting?update
          ??//?RetryOnConflict?uses?exponential?backoff?to?avoid?exhausting?the?apiserver
          ??result,?getErr?:=?client.Resource(deploymentRes).Namespace(namespace).Get(context.TODO(),?"demo-deployment",?metav1.GetOptions{})
          ??//?update?replicas?to?1
          ??if?err?:=?unstructured.SetNestedField(result.Object,?int64(1),?"spec",?"replicas");?err?!=?nil?{
          ???panic(fmt.Errorf("failed?to?set?replica?value:?%v",?err))
          ??}

          ??//?extract?spec?containers
          ??containers,?found,?err?:=?unstructured.NestedSlice(result.Object,?"spec",?"template",?"spec",?"containers")
          ??if?err?!=?nil?||?!found?||?containers?==?nil?{
          ???panic(fmt.Errorf("deployment?containers?not?found?or?error?in?spec:?%v",?err))
          ??}

          ??//?update?container[0]?image
          ??if?err?:=?unstructured.SetNestedField(containers[0].(map[string]interface{}),?"nginx:1.13",?"image");?err?!=?nil?{
          ???panic(err)
          ??}
          ??if?err?:=?unstructured.SetNestedField(result.Object,?containers,?"spec",?"template",?"spec",?"containers");?err?!=?nil?{
          ???panic(err)
          ??}

          ??_,?updateErr?:=?client.Resource(deploymentRes).Namespace(namespace).Update(context.TODO(),?result,?metav1.UpdateOptions{})
          ??return?updateErr
          ?})
          ?fmt.Println("Updated?deployment...")

          ?fmt.Printf("Listing?deployments?in?namespace?%q:\n",?apiv1.NamespaceDefault)
          ?list,?err?:=?client.Resource(deploymentRes).Namespace(namespace).List(context.TODO(),?metav1.ListOptions{})
          ?for?_,?d?:=?range?list.Items?{
          ??replicas,?found,?err?:=?unstructured.NestedInt64(d.Object,?"spec",?"replicas")
          ??if?err?!=?nil?||?!found?{
          ???fmt.Printf("Replicas?not?found?for?deployment?%s:?error=%s",?d.GetName(),?err)
          ???continue
          ??}
          ??fmt.Printf("?*?%s?(%d?replicas)\n",?d.GetName(),?replicas)
          ?}

          ?fmt.Println("Deleting?deployment...")
          ?deletePolicy?:=?metav1.DeletePropagationForeground
          ?deleteOptions?:=?metav1.DeleteOptions{
          ??PropagationPolicy:?&deletePolicy,
          ?}
          ?if?err?:=?client.Resource(deploymentRes).Namespace(namespace).Delete(context.TODO(),?"demo-deployment",?deleteOptions);?err?!=?nil?{
          ??panic(err)
          ?}
          ?fmt.Println("Deleted?deployment.")
          }

          動態(tài)客戶端的與靜態(tài)客戶端的區(qū)別主要在于是否手動傳GVR。

          客戶端構(gòu)造

          具體定位到deployment客戶端,可以這么寫

                
                client,?err?:=?dynamic.NewForConfig(config)
          deploymentRes?:=?schema.GroupVersionResource{Group:?"apps",?Version:?"v1",?Resource:?"deployments"}
          deploymentsClient?:=?client.Resource(deploymentRes).Namespace(namespace)

          為了減少文章篇幅,動態(tài)客戶端就只分析Create的代碼了, 其他接口代碼可閱讀client-go/dynamic/simple.go,大致邏輯都是差不多的,不同點主要在于驗證邏輯和最終的構(gòu)造方法。

          Create 代碼解析

          代碼如下

                
                func?(c?*dynamicResourceClient)?Create(ctx?context.Context,?obj?*unstructured.Unstructured,?opts?metav1.CreateOptions,?subresources?...string)?(*unstructured.Unstructured,?error)?{
          ????//?1.?
          ?outBytes,?err?:=?runtime.Encode(unstructured.UnstructuredJSONScheme,?obj)
          ????
          ????//?2.
          ?name?:=?""
          ?if?len(subresources)?>?0?{
          ??accessor,?err?:=?meta.Accessor(obj)
          ??name?=?accessor.GetName()
          ??if?len(name)?==?0?{
          ???return?nil,?fmt.Errorf("name?is?required")
          ??}
          ?}
          ?//?3.
          ?result?:=?c.client.client.
          ??Post().
          ??AbsPath(append(c.makeURLSegments(name),?subresources...)...).
          ??Body(outBytes).
          ??SpecificallyVersionedParams(&opts,?dynamicParameterCodec,?versionV1).
          ??Do(ctx)
          ?//?4.?
          ?retBytes,?err?:=?result.Raw()
          ?uncastObj,?err?:=?runtime.Decode(unstructured.UnstructuredJSONScheme,?retBytes)
          ?return?uncastObj.(*unstructured.Unstructured),?nil
          }

          代碼主要分為四個部分。

          1. 將對象序列化成[]byte對象,用于后續(xù)上傳
          2. 如果是子資源,就進一步獲取子資源的名字,比如status, scale等
          3. 構(gòu)造請求,具體就是使用Post方法,構(gòu)造請求路徑,設(shè)置請求體參數(shù), 指定編解碼參數(shù)等,最后請求
          4. 將結(jié)果解碼并返回

          k8s里面的編解碼是個很復雜的過程,這個以后再說,可以單獨寫一篇或者兩篇文章呢。

          總結(jié)

          在不使用反射的情況下,靜態(tài)客戶端的接口調(diào)用比較機械化,不夠靈活,所以存在動態(tài)客戶端,GVR的指定可以動態(tài)的指定,相較于靜態(tài)客戶端要靈活很多,兩者各有優(yōu)缺點。

          瀏覽 39
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91亚洲国产精品 | 日韩av手机在线 日韩va在线观看 | a在线视频中文字幕 | 91九色视频网站 | 免费看国产黄色片网站 |