天天看點

Kubernetes叢集DNS插件安裝

在上一篇關于Kubernetes叢集安裝的文章中,我們建立一個最小可用的k8s叢集,不過k8s與1.12版本後的内置了叢集管理的Docker不同,k8s是一組松耦合的元件組合而成對外提供服務的。除了核心元件,其他元件是以Add-on形式提供的,比如叢集内kube-DNS、K8s Dashboard等。kube-dns是k8s的重要插件,用于完成叢集内部service的注冊和發現。随着k8s安裝和管理體驗的進一步完善,DNS插件勢必将成為k8s預設安裝的一部分。本篇将在《一篇文章帶你了解Kubernetes安裝》一文的基礎上,進一步探讨DNS元件的安裝”套路”^_^以及問題的troubleshooting。

上文說過,K8s的安裝根據Provider的不同而不同,我們這裡是基于provider=ubuntu為前提的,使用的安裝腳本是浙大團隊維護的那套。是以如果你的provider是其他選項,那麼這篇文章裡所講述的内容可能不适用。但了解provider=ubuntu下的DNS元件的安裝原理,總體上對其他安裝方式也是有一定幫助的。

在部署機k8s安裝工作目錄的cluster/ubuntu下面,除了安裝核心元件所用的download-release.sh、util.sh外,我們看到了另外一個腳本deployAddons.sh,這個腳本内容不多,結構也很清晰,大緻的執行步驟就是:

可以看出,這個腳本就是用來部署k8s的兩個常用插件:dns和dashboard的。進一步分析,發現deployAddons.sh的執行也是基于./cluster/ubuntu/config-default.sh中的配置,相關的幾個配置包括:

deployAddons.sh首先會根據上述配置生成skydns-rc.yaml和skydns-svc.yaml兩個k8s描述檔案,再通過kubectl create建立dns service。

為了讓deployAddons.sh腳本執行時隻進行DNS元件安裝,需要先設定一下環境變量:

執行安裝腳本:

似乎很順利。我們通過kubectl來檢視一下(注意:由于DNS服務被建立在了一個名為kube-system的namespace中,kubectl執行時要指定namespace名字,否則将無法查到dns service):

在檢視DNS元件對應的Pod時,發現Ready為0/3,STATUS為”ErrImagePull”,DNS服務并沒有真正起來。

我們來修正上面的問題。在cluster/ubuntu下,我們發現多了兩個檔案:skydns-rc.yaml和skydns-svc.yaml,這兩個檔案就是deployAddons.sh執行時根據config-default.sh中的配置生成的兩個k8s service描述檔案,問題就出在skydns-rc.yaml中。在該檔案中,我們看到了dns service啟動的pod所含的三個容器對應的鏡像名字:

在這次安裝時,我并沒有配置加速器(vpn)。是以在pull gcr.io上的鏡像檔案時出錯了。在沒有加速器的情況,我們在docker hub上可以很容易尋找到替代品(由于國内網絡連接配接docker hub慢且經常無法連接配接,建議先手動pull出這三個替代鏡像):

我們需要手工将skydns-rc.yaml中的三個鏡像名進行替換。并且為了防止deployAddons.sh重新生成skydns-rc.yaml,我們需要注釋掉deployAddons.sh中的下面兩行:

删除dns服務:

再次執行deployAddons.sh重新部署DNS元件(不贅述)。安裝後,我們還是來檢視一下是否安裝ok,這次我們直接用docker ps檢視pod内那三個容器是否都起來了:

似乎kube-dns這個鏡像的容器并沒有啟動成功。docker ps -a印證了這一點:

檢視一下stop狀态下的kube-dns container的容器日志:

從日志上去看,應該是kube-dns去連接配接apiserver失敗,重試一定次數後,退出了。從日志上看,kube-dns視角中的kubernetes api server的位址是:

而實際上我們的k8s apiserver監聽的insecure port是8080,secure port是6443(由于沒有顯式配置,6443是源碼中的預設端口),通過https+443端口通路apiserver毫無疑問将以失敗告終。問題找到了,接下來就是如何解決了。

我們看一下kube-dns指令都有哪些可以傳入的指令行參數:

可以看出:–kube-master-url這個指令行選項可以實作我們的訴求。我們需要再次修改一下skydns-rc.yaml:

再次重新部署DNS Addon,不贅述。部署後檢視kube-dns服務資訊:

在通過docker logs直接檢視kube-dns容器的日志:

通過日志可以看到,apiserver的url是正确的,kube-dns元件沒有再輸出錯誤,安裝似乎成功了,還需要測試驗證一下。

按照預期,k8s dns元件可以為k8s叢集内的service做dns解析。目前k8s叢集預設namespace已經部署的服務如下:

我們在k8s叢集中的一個myclient容器中嘗試去ping和curl my-nginx服務:

ping my-nginx解析成功(找到my-nginx的clusterip: 192.168.3.179):

curl my-nginx服務也得到如下成功結果:

用戶端容器的dns配置,這應該是k8s安裝時采用的預設配置(與config-default.sh有關):

到此,k8s dns元件就安裝ok了。

繼續閱讀