摘要:通過監視資源的變化,并根據的信息生成記錄寫入到中。是唯一保留的容器,依然提供健康檢查。操作會獲取最新的全量資源與本地狀態進行比較來產生通知,可以避免網絡原因導致的丟失通知的情況。最后一個參數用來設置處理事件的回調。
上一期我們以1.2版本為背景,介紹了K8S的服務發現和kube-dns插件的相關內容。有了上一期內容作為基礎,這期了解最新版本的kube-dns就會容易很多。
本文主要對比1.2和1.4版本中kube-dns 的主要變化,以及最新版本中kube-dns的內部實現。滿滿的干貨來了,你準備好了嗎?
大綱● kube-dns的主要變化
● kube-dns的實現原理
● kubedns容器詳解
● dnsmasq容器簡介
● exechealthz容器簡介
主要變化● 服務發現機制未變化
也就是說kube-dns對外的接口是基本沒變的。變化主要在于kube-dns插件的內部組成,由原來的四個容器變為了三個。
現在回顧一下上一期所講的1.2版本kube-dns的組成。
Kube2sky通過K8S API監視K8S Service資源的變化,并根據Service的信息生成DNS記錄寫入到etcd中。Skydns為集群中的Pod提供DNS查詢服務,DNS記錄從etcd中讀取。Exechealthz提供健康檢查功能。
接下來我們再看一下1.4版本kube-dns的組成。對比兩張圖,可以很直觀的看到kube-dns對外接口沒有發生變化。Exechealthz是唯一保留的容器,依然提供健康檢查。
不同點:
1.會檢查兩個容器的健康狀態。
2.為集群提供DNS查詢服務的容器由skydns變為了dnsmasq。
3.Kubedns容器替代了kube2sky來監視Service資源。
4.Etcd容器不見了。
相信有些人會好奇DNS記錄現在保存在哪了呢?那為了回答這個問題以及了解新版kube-dns的工作原理,我們就進入下一章內容來了解其實現原理。
實現原理● kubedns容器的實現
本著“Talk is cheap, show me the code”原則,我們將會以源碼分析的方式介紹其原理。對另外兩個容器會進行簡要介紹。
先來看一下源碼位置,這里列出的是kube-dns插件相關的源碼,不僅僅是kubedns容器的。之前的源碼是集中在cluster/addons/dns下面的,那么1.4版本中分成了三個目錄:
● 第一個目錄會有K8S DNS相關的README以及kubedns容器的Dockerfile。
● 第二個目錄存放kube-dns插件的編排文件。
● 第三個是kubedns源碼目錄,kubedns容器使用的命令行就是從這構建出來的。
● kubedns容器的功能:
● 接入SkyDNS,為dnsmasq提供查詢服務
● 替換etcd容器,使用樹形結構在內存中保存DNS記錄
● 通過K8S API監視Service資源變化并更新DNS記錄
● 服務10053端口
對功能有了大概了解之后,我們下面就結合源碼來看看各個功能是如何實現的。
● kubedns實現——SkyDNS接入
下面是kubedns啟動的部分代碼,這部分顯示的是kubedns在啟動的時候會初始化一個SkyDNS Server,初始化的時候傳入了一個KubeDNSServer.kd。
下面是KubeDNSServer.kd的初始化代碼,使用的是K8S提供的包。使用K8S提供的包可以初始化一個SkyDNS Server?相信很多人能夠想到,這個KubeDNSServer.kd應該實現了一個接口。
SkyDNS Server在初始化的時候需要傳入一個Backend接口,其定義如下。SkyDNS基于Etcd實現了該接口,也會使用它初始化Server。得益于SkyDNS的良好設計,K8S只要實現該接口便可以接入SkyDNS來提供DNS查詢服務,并定制存儲功能。
skydns/server/server.go
skydns/server/backend.go
● kubedns實現——etcd替換
在服務發現的流程中,主要用到了Records這個方法,下面我們就來看看K8S是如何實現這個方法。
主要步驟是先將域名按“.”拆分,并將各部分顛倒順序生成一個path數組。調用getRecordsForPath方法獲取DNS記錄并返回。
kubernetes/pkg/dns/dns.go
getRecordsForPath會調用cache的相關方法。這個cache會被初始化為一個TreeCache結構,定義如下:
kubernetes/pkg/dns/dns.go
kubernetes/pkg/dns/treecache.go
如下圖所示,TreeCache的結構類似于目錄樹。從根節點到葉子節點的每個路徑與一個域名是相對應的,順序是顛倒的。它的葉子節點只包含Entries,非葉子節點只包含ChildNodes。葉子節點中保存的就是SkyDNS定義的msg.Service結構,可以理解為DNS記錄。
在Records接口方法實現中,只需根據域名查找到對應的葉子節點,并返回葉子節點中保存的所有msg.Service數據。K8S就是通過這樣的一個數據結構來保存DNS記錄的,并替換了Etcd。
● kubedns實現——監視Service
最后我們來看一下監視Service資源的相關代碼。如下圖所示,這里使用了k8s.io/kubernetes/pkg/client/cache包的NewInformer方法,這個方法在K8S源碼里會經常看到。其參數為:
● 第一個參數需要傳入ListWatch結構,它定義了List和Watch操作步驟。kd.kubeClient結構可以用來訪問K8S API,從代碼中可以看出分別訪問了List和Watch API
● 第二個參數為監視的資源類型,代碼中指定了Service資源
● 第三個參數為List操作的執行間隔。Watch操作是通知機制,只要監視的資源發送變化
就會調用對應的回調函數。List操作會獲取最新的全量資源與本地狀態進行比較來產生通知,可以避免網絡原因導致的Watch丟失通知的情況。List操作代價較高,因此需要通過第三個參數來設置其執行間隔。
● 最后一個參數用來設置處理事件的回調。
kubernetes/pkg/dns/dns.go
下面我們以新增Service事件的處理流程為例來簡單了解一下事件處理的代碼。
在創建一個K8S Service資源后,newService方法最終會調用newPortalService方法,其代碼如下。getSkyMsg函數會將Service的ClusterIP保存到msg.Service結構中并返回,對應recordValue。recordLabel可以理解為一個摘要值,與ClusterIP是一一對應的,它將作為TreeCache葉子節點的key。
最后根據Service信息找到對應的樹枝(如不存在會構建),并設置葉子節點。這樣一個新建的Service對應的DNS記錄就保存到kubedns中了。
kubernetes/pkg/dns/dns.go
Kubedns容器的主要原理已經講解完了,下面我們簡要介紹一下其他兩個容器。
● dnsmasq簡介
● Dnsmasq是一款小巧的DNS配置工具
● 在kube-dns插件中的作用:
● 通過kubedns容器獲取DNS規則,在集群中提供DNS查詢服務
● 提供DNS緩存,提高查詢性能
● 降低kubedns容器的壓力、提高穩定性
● Dockerfile在GitHub上Kubernetes組織的contrib倉庫中,位于dnsmasq目錄下。
● 在kube-dns插件的編排文件中可以看到,dnsmasq通過參數--server=127.0.0.1#10053指定upstream為kubedns。
● exechealthz簡介
● 在kube-dns插件中提供健康檢查功能
● 源碼同樣在contrib倉庫中,位于exec-healthz目錄下。
● 新版中會對兩個容器都進行健康檢查,更加完善。
總結1.4版本kube-dns插件的三個容器的功能如下:
● kubedns容器
● 監視k8s Service資源并更新DNS記錄
● 替換etcd,使用TreeCache數據結構保存DNS記錄并實現SkyDNS的Backend接口
● 接入SkyDNS,對dnsmasq提供DNS查詢服務
● dnsmasq容器
● 對集群提供DNS查詢服務
● 設置kubedns為upstream
● 提供DNS緩存,降低kubedns負載,提高性能
● exechealthz容器
● 定期檢查kubedns和dnsmasq的健康狀態
● 為k8s活性檢測提供HTTP API
相比于1.2版本,個人認為有了如下改進:
● 無狀態服務。1.2版本中,需要將Etcd的數據Volume出來才能保證Etcd容器重啟之后數據不會丟失,服務可以快速恢復。新版本中作為無狀態服務出現,通過增加冗余來提高可靠性。即使kubedns容器重啟,dnsmasq緩存機制也可以保證服務的可用性。
● 優化查詢效率。SkyDNS直接從內存中獲取DNS記錄。
● 完善健康檢查。1.2版本中只對kube2sky設置了健康檢查。
除了改進之外,還有一點不足,也是大家比較擔心的 「 內存占用 」。目前在kube-dns編排文件中默認設置了內存限制為170M,在注釋中可以看出這一數字并未在大規模集群中驗證。不過相信不久的將來我們就能看到這一驗證結果。
Tips :直播在哪里?噓,悄悄告訴你,點擊http://t.cn/RVRITb3 即可查看直播回放!
掃描上方二維碼。閱讀更多優質文章。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/32513.html
摘要:前言我是,如果你還不認識我,不妨先看看技術的前世今生一平靜的生活已經有一段日子了。傳送門技術的前世今生一技術的前世今生三 前言:我是JavaScript,如果你還不認識我,不妨先看看《Web技術的前世今生(一)》 平靜的生活已經有一段日子了。 這一天,HTML大哥面露不悅地走過來問我: Js,你是打算和我們分家嗎? 大哥,您這說的哪里話,我什么地方做的不對么?我一臉茫然地回答道。 哼,...
摘要:前言我是,如果你還不認識我,不妨先看看技術的前世今生一平靜的生活已經有一段日子了。傳送門技術的前世今生一技術的前世今生三 前言:我是JavaScript,如果你還不認識我,不妨先看看《Web技術的前世今生(一)》 平靜的生活已經有一段日子了。 這一天,HTML大哥面露不悅地走過來問我: Js,你是打算和我們分家嗎? 大哥,您這說的哪里話,我什么地方做的不對么?我一臉茫然地回答道。 哼,...
摘要:前言我是,如果你還不認識我,不妨先看看技術的前世今生一平靜的生活已經有一段日子了。傳送門技術的前世今生一技術的前世今生三 前言:我是JavaScript,如果你還不認識我,不妨先看看《Web技術的前世今生(一)》 平靜的生活已經有一段日子了。 這一天,HTML大哥面露不悅地走過來問我: Js,你是打算和我們分家嗎? 大哥,您這說的哪里話,我什么地方做的不對么?我一臉茫然地回答道。 哼,...
摘要:原文鏈接版本之前世今生最全篇語言語言是博士在創建年,被命名為提出了愿景公開版本個包文件,的類文件第一個版本發布在定義為代表技術虛擬機版本發布時間代表技術文件格式內部類反射版本發布時間從開始以后的版本定義為擴展到個包個類版本名稱為區分企業平 原文鏈接:Java版本之前世今生-最全篇 1.Oak 語言 Oak 語言是James Gosling 博士在1991創建 2.JDK Beta 1...
摘要:前言我是,如果你還不認識我,不妨先看看技術的前世今生一,以及技術的前世今生二前面我提過,我的大哥有一個叫的死黨,這家伙有事沒事經常上我們家串門。時間來到了年,在那前后發生了兩件事讓我印象深刻。傳送門技術的前世今生一技術的前世今生二 前言:我是JavaScript,如果你還不認識我,不妨先看看《Web技術的前世今生(一)》,以及《Web技術的前世今生(二)》 前面我提過,我的大哥HTML...
閱讀 2655·2023-04-26 02:44
閱讀 8252·2021-11-22 14:44
閱讀 2119·2021-09-27 13:36
閱讀 2463·2021-09-08 10:43
閱讀 676·2019-08-30 15:56
閱讀 1392·2019-08-30 15:55
閱讀 2887·2019-08-28 18:12
閱讀 2826·2019-08-26 13:50