青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Fork me on GitHub
隨筆 - 215  文章 - 13  trackbacks - 0
<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456


專注即時通訊及網游服務端編程
------------------------------------
Openresty 官方模塊
Openresty 標準模塊(Opm)
Openresty 三方模塊
------------------------------------
本博收藏大部分文章為轉載,并在文章開頭給出了原文出處,如有再轉,敬請保留相關信息,這是大家對原創(chuàng)作者勞動成果的自覺尊重!!如為您帶來不便,請于本博下留言,謝謝配合。

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

相冊

Awesome

Blog

Book

GitHub

Link

搜索

  •  

積分與排名

  • 積分 - 220850
  • 排名 - 117

最新評論

閱讀排行榜

轉自:https://my.oschina.net/caicloud/blog/829365
著作權歸作者所有,轉載請自覺標明出處,以示尊重!

大家好,我是徐超,從事 Kubernetes 開發(fā)已經兩年多了。 

今天,我從一個開發(fā)者的角度來講一講 client-go repository,以及怎么用 client-go 搭建 Controller。同時,也給大家講一講開發(fā)過程中遇到的坑,希望大家在開發(fā)的時候可以繞坑而行。

另外,我還會講一下 Kubernetes 的 API,讓 controller 功能變的更加強大。

那我們現(xiàn)在先來講,有哪些方法可以跟 APIserver 進行通訊。最常用的,可能就是 kubectl,以及官方支持的 UI,Kube Dashboard,這是 google 最近投入很多的一個項目。

開發(fā)過程中 debug 的時候可以直接去調用 k8s 的 Restful API,通過寫腳本去實現(xiàn) Controller。

但是,這些做法無論從效率還是可編程性來說都是不太令人滿意的。

這也就是為什么我們要創(chuàng)建 client-go,我們其實就是把寫 controller 所需的 clients,utilities 等都放到了 client-go 這個 repository 里面。大家如果需要寫 controller 的話,可以在這里面找到所需要的工具。client-go 是 go 語言的 client,除了 go 語言之外,我們現(xiàn)在還支持 python 的 client,目前是 beta 版本。但是這個 python client 是我們直接從 open API spec 生成的,之后我們會繼續(xù)生成 client Java 或者一些其它的語言。

我們先看一下 client library 的內容。它主要包括各種 clients:clientset、DynamicClient 和 RESTClient。還有幫助你寫 Controller 時用到的 utilities:Workqueue 和 Informer。

我們先看一下 kube-controller 的大致結構,典型的 controller 一般會有 1 個或者多個 informer,來跟蹤某一個 resource,跟 APIserver 保持通訊,把最新的狀態(tài)反映到本地的 cache 中。只要這些資源有變化,informal 會調用 callback。這些 callbacks 只是做一些非常簡單的預處理,把不關心的的變化過濾掉,然后把關心的變更的 Object 放到 workqueue 里面。其實真正的 business logic 都是在 worker 里面, 一般 1 個 Controller 會啟動很多 goroutines 跑 Workers,處理 workqueue 里的 items。它會計算用戶想要達到的狀態(tài)和當前的狀態(tài)有多大的區(qū)別,然后通過 clients 向 APIserver 發(fā)送請求,來驅動這個集群向用戶要求的狀態(tài)演化。圖里面藍色的是 client-go 的原件,紅色是自己寫 controller 時填的代碼。

我們來仔細看一下各種 clients。

先講最常見的 Clientset,它是 k8s 中出鏡率最高的 client,用法比較簡單。先選 group,比如 core,再選具體的 resource,比如 pod 或者 job,最后在把動詞(create、get)填上。

clientset 的使用分兩種情況:集群內和集群外。

集群內:將 controller 容器化后以 pod 的形式在集群里跑,只需調用 rest.InClusterConfig(),默認的 service accoutns 就可以訪問 apiserver 的所有資源。

集群外,比如在本地,可以使用與 kubectl 一樣的 kube-config 來配置 clients。如果是在云上,比如 gke,還需要 import Auth Plugin。

clientset 是用 client-gen 生成的。如果你打開 pkg/api/v1/tyeps.go,在 pod 的定義上有一行注釋,叫做“+genclient=true”,這句話的意思是,需要為這個 type 生成一個 client,如果之后要做自己的 API type 拓展,也可以通過這樣的方式來生成對應的 clients。

Clientset 的動詞很多細微的地方比較燒腦,我來幫助大家理解一下。

我們先來說 Get 的 GetOptions,這是 1.6 的 feature,如果在里面看 client 的 get 的話,有一個 field,叫做 resource version。

resourece version 是 kubernetes 里面一個 logical clock,用作 optimistic concurrency。如果沒有設置 resourceversion,api-server 收到請求后會從 etcd 讀出最新的值。但設為 0 的話,APIserver 就會從 local 的 cache 里面把值讀取出來,cache 的值可能會有一定的延遲。這樣可以減輕 APIserver 和 etcd 后端的壓力。現(xiàn)在是用得比較多的是 kubelet,經常要 get node status,但是不需要最新的 node status,如果集群很大,就能夠省不少 cpu/memory 的開銷。如果 resource version 設成非常大的值,get request 會在 api-server 掛起,沒有響應的話會 time-out。

同樣的,在 list 這個操作的時候,你可以提供一個 listOption,這個 listOption 里面也有 resource version,和 get 里的意義一樣。我們在寫 informer 的時候會用到。因為每一個 controller 在啟動的時候,會向 api-server 發(fā)送 list 請求,如果每一個 request 都是從 etcd 里讀取過來的話,這個開銷非常大,所以 list 會從 api-server 的 cache 讀取。

在 watch 里面也有一個 listOption,里面 resrouce version 的意義不一樣。在 watch 的時候,apiserver 會從這個 resuorce version 開始所有的變化。這里的 best practice 設置成:永遠要設置 resource version。因為如果不設置,那么 APIserver 就會從 cache 里隨便的一個時間點開始推送,令 controller 的行為不好預測。

我們看 informer 是怎么使用 list 進行 watch 的。在 informer 里面,我們一般都是先 list,把 resource version 設為 0,API Server 就可以從 cache 里面給我 list。List 完之后,把 list 的 resource version 取出來,并且設置為 watch 的 listOption,這樣就可以保證 informer 拿到的 events 是連續(xù)的。

另外要注意的是,watch 不是一勞永逸的,apiserver 會 timeout 一個 watchrequest 的,默認值是 5~10 分鐘。這時你需要重新 watch。

說一下這個 update,client 里面有兩種 update:Update 和 UpdateStatus。

他們的區(qū)別是,如果你 Update 一個 pod,那么你對 status 的修改會被  API server overwrite 掉。UptateStatus 則相反。

k8s 有 OptimisticConcurrency 機制,如果有兩個 client 都在 update 同一個,會 fail。所以寫代碼時一般會把 update 寫到 loop 里,直到 api-server 返回 200,ok 時才確定 update 成功。

另外,使用 get+update 有一個 bug:假設 cluster 的 pod 有一個新的 field,如果你使用一個舊的 client,它不知道這個新的 field,那么 get 到的 pod 是沒有這個新的 field 的,再 update 的時候,這個新的 field 會被覆蓋掉。

可能會在 1.7 的時候把這個 bug 處理掉。

跟 update 相對應的就是 patch。Update 像拆遷隊,只會把整個 object 推倒重做。Patch 則像手術刀,可以做精細操作,可以精確修改一個 object 的 field。

patch 如果有 conflicts,會在 apiserver 重試 5 次。除非有用戶 patch 同一個 field,否則一般 client 會一次 patch 成功。當然 patch 有性能問題,因為要在 API serve 做 Json serialiation 和 deserialization。我們估計會在 1.7 的時候優(yōu)化。如果不關心性能,我們還是推薦用 patch。

提醒一下:你在做 Patch 的時候,最佳實踐是把 original 的 UID 填在 patch 里。因為 API server 的 key-value store 是以“namespace + name”作為 key 的。在任意一個時間,這個組合都是唯一的。但是如果把時間這條軸加進來的話,比如你有一個 pod,刪除后過了一會兒,又在同一個 namespace 下建了同名的 pod,但是把所有的 spec 都改掉了,那么 controller 舊的 patch 可能會被應用到這個新建的 pod 上,這樣就會有 bug 了。如果在 patch 里加入 uid 的話,一旦發(fā)生剛才所說的情況,apiserver 會以為你是要修改 uid,這個是不允許的,所以這個 patch 就會 fail 掉,防止了 bug。

Delete Option,有一個選項叫 precondition,它有一個 uid 選項。也是為了防止 namespace+name 的組合在時間軸上不唯一。

當時,我們發(fā)現(xiàn) K8S 的 CI tests 經常會莫名其妙的 fail 掉。最后我發(fā)現(xiàn)是因為剛 create 的 pod 跟之前已經被刪除的 pod 重名,但是 kubelet 不知道,就把新的 pod 給誤刪除了。所以我們 delete 的時候,這個 precondition 的 UID 請勿刪除。

 

Delete 從 1.4 開始有一個 field 叫做 OrphanDependents。如果設為 true 或者 unset 的話,當 delete()返回的時候,這個 object 可能會在繼續(xù)存在一會兒,雖然最終還是會被刪掉。另外,這個時候,如果你把 OrphanDependents 設置成 true 或者不設置的話,要刪除的 Dependents 是不會被刪除的。如果設成 false,只要 delete()返回了,這個 object 就肯定已經在 apiserver 上被刪掉了,除非你另外設置了 finalizer。并且 garbage collector 會在背景里面慢慢刪除 dependents。

現(xiàn)在講一下另外一種 client,叫做 dynamic client。

dynamic client 用法比較靈活。因為你可以任意設置要操作的 resource。它的 return value,不是一個 structure,而是 map[string]interface{}。如果一個 controller 需要控制所有 API,比如 namespace controller 或者 garbage collector,那就用 dynamic client。使用時可以先通過 discovery,發(fā)現(xiàn)有哪些 API,再通過使用 dynamic client access 所有的 api。dynamic client 也支持 third party resources。

dynamic client 的缺點是它只支持 JSON 一種序列化。而 JSON 的效率遠遠低于 proto buf。

現(xiàn)在我們講一下 rest client。

Rest Client 是 client 和 dynamic client 的基礎。屬于比較底層的,跟 dynamic client 一樣,你可以使用它操作各種 resource。支持 Do() 和 DoRaw。

相比 dynamic client,支持 protobuf 和 json。效率會比較高。

但是問題就是,如果你要 access third party resource,需要自己寫反序列化,不能直接 decode 到 type。在 demo 里會進行演示。

現(xiàn)在我們講 informer,它的 input 其實就兩個,一是要 list function 和 watch function,二是你要給 informer 提供一些 callback。informer 跑起來后,它會維護 localstore。你之后就可以直接訪問 localstore,而不用跟 APIserver 通訊。提高一些 performance。

使用 informer 的好處一個是性能比較好,還有一個是可靠性。如果有 network partition,informer 后會從斷點開始繼續(xù) watch,它不會錯過任何 event 的。

Informer 也有一些 best practice,第一點,在 controller run 之前,最好等這些 informer 都 sync 了(初始化)。這樣做,一是可以避免 controller 初始化時的 churn:比如 replica set controller 要 watch replica set 和 pod,如果不 sync 就開始 run,controller 會以為現(xiàn)在沒有任何 pod,會創(chuàng)建很多不必要的 pod,之后還要刪除。二來就是會避免很多很詭異的 bug。我在寫 garbage collector 的時候就遇到過不少。

另外 informer 提供的 localcache 是 read-only 的。如果要修改,先用 DeepCopy 拷貝出來,否則可能有 read-write race。并且你的 cache 可能是和其他 controller 共享的,修改 cache 會影響其他 controller。

第三個要注意的地方就是,informer 傳遞給 callbacks 的 object 不一定是你所期待的 type。比如 informer 追蹤所有 pod,返回的 Object 可能不是 pod,而是 DeletedFinalStateUnknown。所以在處理 delete 的時候,除了要處理原來跟蹤的 object,還要處理 DeletedFinalStateUnknown。

最后要講一下的就是,informer 的 resyncoption。它只是周期性地把所有的 local cache 的東西重新放到 FIFO 里。并不是說把 APIserver 上所有的最新狀態(tài)都重新 list 一遍。這個 option 大家一般都是不會用到的,可以放心大膽地把這個 resync period 設成 0。

最后再講一下這個 workqueue。

其實主要是為了可以 concurrent processing,可以并行地讓 Callbacks 把狀態(tài)加到 workqueue 里,然后起一大堆的 worker。

workqueue 提供的一個保障就是,如果是同一個object,比如同一個 pod,被多次加到 workqueue 里,在 dequeue 時,它只會出現(xiàn)一次。防止會有同一個 object 被多個 worker 同時處理。

另外 workqueue 還有一些非常有用的 feature。比如說 rate limited:  如果你從 workqueue 里面拿出一個 object,處理時發(fā)生了錯誤,重新放回了 workqueue。這時,workqueue 保證這個 object 不會被立刻重新處理,防止 hot loop。

另外的一個 feature 就是提供 prometheus 監(jiān)控。你可以實時監(jiān)控 queue 的長度,延遲等。你可以監(jiān)控 queue 的處理速度是否跟得上。

現(xiàn)在我給大家做一個 demo(https://github.com/caesarxuchao/servicelookup)。通過 k8s 的 api 用戶是沒辦法很快通過 pod 的名字找到對應的 service 的。當然你可以找到這個 pod 的 label,然后去跟 selector 進行比較而確定 service,但做這種逆向查詢是非常費時間的。

所以我這里就是寫了這樣一種  controller,watch 所有的 endpoints 和 pods,來做比對,找到 pod 服務的 service。

我先啟動兩個 informer,1 個 informer 是追蹤所有 pods 的變化,另一個追蹤所有 endpoints 變化。

給 informer 注冊 callback,來把 pod 和 endpoint 的變化放到 workqueue。

然后啟動許多 worker,從 workquue 里拿出 pod 和 endpoint 做比對。

運行時,先啟動兩個 informer,等它們 sync,最后啟動 worker。

Demo 的代碼在 github 上,https://github.com/caesarxuchao/servicelookup。
視頻鏈接:http://v.qq.com/iframe/player.html?vid=c03641vzw2m&width=670&height=502.5&auto=0

posted on 2017-01-23 17:06 思月行云 閱讀(573) 評論(0)  編輯 收藏 引用 所屬分類: Docker\K8s
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            影音先锋一区| 国产一区二区三区观看| 国产精品理论片在线观看| 亚洲美女中出| 最新国产成人在线观看| 农夫在线精品视频免费观看| 在线观看日产精品| 91久久国产综合久久蜜月精品 | 亚洲美女性视频| 欧美激情按摩在线| 亚洲欧美日韩综合国产aⅴ| 亚洲一区二区三区四区五区黄| 国产精品五月天| 亚洲欧洲日本国产| 国产亚洲欧洲一区高清在线观看| 免费观看一区| 欧美午夜片欧美片在线观看| 亚洲免费av观看| 亚洲巨乳在线| 好吊日精品视频| 亚洲黄色av| 精品动漫3d一区二区三区| 亚洲国产婷婷| 精品动漫一区二区| 在线观看中文字幕亚洲| 夜夜爽www精品| 亚洲精品乱码久久久久久日本蜜臀| 亚洲一区二区三区中文字幕在线| 在线观看欧美视频| 久久一区二区视频| 欧美一区二区播放| 欧美日韩一卡二卡| 日韩一级免费| 亚洲一区二区免费在线| 欧美日韩国产精品| 亚洲美女在线国产| 一区二区三区视频在线| 欧美精品日韩| 9久草视频在线视频精品| 亚洲美女av电影| 亚洲欧美日韩综合| 国产乱码精品| 久久久久久尹人网香蕉| 免费观看在线综合| 在线观看国产日韩| 欧美激情一区二区三区蜜桃视频| 亚洲第一偷拍| 亚洲一区在线免费观看| 国产精品久久久久影院色老大| 午夜亚洲激情| 亚洲国产成人久久综合一区| 在线亚洲自拍| 在线观看亚洲视频啊啊啊啊| 欧美成人精品影院| 亚洲一区区二区| 欧美亚洲免费| 亚洲一级影院| 国内外成人免费激情在线视频网站 | 国产精品入口麻豆原神| 先锋影音久久| 亚洲日本中文字幕免费在线不卡| 午夜精品久久久久久久99樱桃 | 夜夜嗨网站十八久久| 国产精品成人av性教育| 久久米奇亚洲| 午夜视频精品| 日韩视频亚洲视频| 欧美va天堂| 久久精品国产免费观看| 一区二区三区导航| 日韩午夜电影av| 99精品福利视频| 樱花yy私人影院亚洲| 国产日产欧产精品推荐色 | 午夜精品久久久久久久99黑人| 久久综合色8888| 久久综合色婷婷| 老巨人导航500精品| 欧美中文字幕视频在线观看| 亚洲网站在线| 午夜视频久久久| 久久精品水蜜桃av综合天堂| 亚洲欧洲日本一区二区三区| 国产亚洲亚洲| 国产亚洲精品v| 精品福利电影| 亚洲欧洲精品天堂一级| 亚洲激情一区| 亚洲一区不卡| 欧美中文字幕视频在线观看| 久久九九99视频| 美女精品国产| 一本综合精品| 久久精品国产一区二区三区免费看| 欧美一区二区三区啪啪| 免费欧美视频| 国产精品亚洲综合| 99成人在线| 久久精品免费播放| 亚洲精品久久久久| 欧美在线影院| 欧美视频在线观看| 伊人久久大香线| 欧美一级视频精品观看| 亚洲国产精品ⅴa在线观看| 亚洲深夜福利| 欧美成人伊人久久综合网| 国产精品视频男人的天堂| 亚洲盗摄视频| 鲁大师影院一区二区三区| 亚洲影视在线| 欧美三级精品| 一区二区三区精密机械公司 | 在线中文字幕一区| 91久久夜色精品国产网站| 亚洲自拍电影| 最新热久久免费视频| 久久国产精品一区二区三区四区 | 国产精品久久久久一区二区三区共| 亚洲国产精品一区二区第一页 | 亚洲毛片在线观看.| 牛牛精品成人免费视频| 亚洲国内精品在线| 亚洲三级影片| 国产精品久久久久一区二区| 亚洲欧美日韩精品久久奇米色影视| 99国产精品久久久久久久| 国产美女高潮久久白浆| 久久久久中文| 欧美极品aⅴ影院| 亚洲欧美乱综合| 久久国产欧美日韩精品| 亚洲经典三级| 亚洲一区二区三区影院| 原创国产精品91| 国产一区二区精品丝袜| 亚洲国产精品一区在线观看不卡| 欧美美女bb生活片| 欧美一级久久久| 国产农村妇女毛片精品久久莱园子| 亚洲综合清纯丝袜自拍| 亚洲欧美一区二区原创| 黄网站免费久久| 欧美激情91| 国产精品高潮呻吟久久av黑人| 在线天堂一区av电影| 欧美一区二区三区四区在线观看地址| 正在播放欧美视频| 亚洲高清资源| 美日韩丰满少妇在线观看| 国产精品视频自拍| 老色鬼精品视频在线观看播放| 欧美激情中文字幕乱码免费| 亚洲国产精品女人久久久| 久久精品主播| 亚洲视频免费在线观看| 欧美综合77777色婷婷| 国产一本一道久久香蕉| 欧美一区二区视频观看视频| 亚洲美女毛片| 久久久av毛片精品| 免费观看一区| 国产专区精品视频| 精品91免费| 亚洲免费观看| 韩日成人av| 美女视频黄免费的久久| 午夜视黄欧洲亚洲| 欧美精品成人一区二区在线观看| 欧美一区二视频| 国内外成人在线视频| 亚洲影视中文字幕| 亚洲一区二区三区在线播放| 99国产麻豆精品| 亚洲欧美欧美一区二区三区| 欧美激情aⅴ一区二区三区| 老司机一区二区| 国产精品欧美一区二区三区奶水 | 国产精品99久久99久久久二8 | 久久福利精品| 亚洲美女诱惑| 久久久久久久久久久一区| 性久久久久久久久久久久| 国产一区二区主播在线| 久久www成人_看片免费不卡| 久久久噜久噜久久综合| 黑人中文字幕一区二区三区| 欧美国产三级| 亚洲欧美成人一区二区三区| 久久精品人人爽| 亚洲一区亚洲二区| 国精品一区二区| 欧美精品久久久久a| 亚洲电影免费观看高清完整版| 亚洲午夜极品| 亚洲国产精品久久人人爱蜜臀 | 国产日产亚洲精品系列| 欧美激情一区二区三区在线| 久久国产欧美日韩精品| 亚洲国产毛片完整版|