kube-dns的前世此生

上一期咱們以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的組成。spa

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 便可查看直播回放!

掃描上方二維碼。閱讀更多優質文章。

相關文章
相關標籤/搜索